1f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis/* 2f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * Copyright (C) 2012 The Android Open Source Project 3f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * 4f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * Licensed under the Apache License, Version 2.0 (the "License"); 5f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * you may not use this file except in compliance with the License. 6f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * You may obtain a copy of the License at 7f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * 8f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * http://www.apache.org/licenses/LICENSE-2.0 9f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * 10f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * Unless required by applicable law or agreed to in writing, software 11f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * distributed under the License is distributed on an "AS IS" BASIS, 12f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * See the License for the specific language governing permissions and 14f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * limitations under the License. 15f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis */ 16f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 17175a7206c5aea70236b916d7707ab25025eb9cd6Brian Anderson#include <ui/Fence.h> 18175a7206c5aea70236b916d7707ab25025eb9cd6Brian Anderson 19f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#define LOG_TAG "Fence" 20f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS 21f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis//#define LOG_NDEBUG 0 22f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 23d31824004277f554000417cea349d69f18655e95Dan Stoza// We would eliminate the non-conforming zero-length array, but we can't since 24d31824004277f554000417cea349d69f18655e95Dan Stoza// this is effectively included from the Linux kernel 25d31824004277f554000417cea349d69f18655e95Dan Stoza#pragma clang diagnostic push 26d31824004277f554000417cea349d69f18655e95Dan Stoza#pragma clang diagnostic ignored "-Wzero-length-array" 27f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <sync/sync.h> 28d31824004277f554000417cea349d69f18655e95Dan Stoza#pragma clang diagnostic pop 29d31824004277f554000417cea349d69f18655e95Dan Stoza 30175a7206c5aea70236b916d7707ab25025eb9cd6Brian Anderson#include <sys/types.h> 31f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <unistd.h> 32f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <utils/Log.h> 33175a7206c5aea70236b916d7707ab25025eb9cd6Brian Anderson#include <utils/String8.h> 34f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <utils/Trace.h> 35f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 36f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennisnamespace android { 37f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 381df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennisconst sp<Fence> Fence::NO_FENCE = sp<Fence>(new Fence); 39ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall 40f25e183a70bd631f75dce51e85b7d568472a0cdbJamie GennisFence::Fence(int fenceFd) : 41f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis mFenceFd(fenceFd) { 42f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 43f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 44df1baddb6f4a13e7253ca547549b3157725c3121Chia-I WuFence::Fence(base::unique_fd fenceFd) : 45df1baddb6f4a13e7253ca547549b3157725c3121Chia-I Wu mFenceFd(std::move(fenceFd)) { 46f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 47f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 48d31824004277f554000417cea349d69f18655e95Dan Stozastatus_t Fence::wait(int timeout) { 49f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis ATRACE_CALL(); 50f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis if (mFenceFd == -1) { 51f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return NO_ERROR; 52f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis } 53b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian int err = sync_wait(mFenceFd, timeout); 54b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian return err < 0 ? -errno : status_t(NO_ERROR); 55f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 56f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 57ea74d3b78d607cde17790a7bb83e6f68ffd34cfdMathias Agopianstatus_t Fence::waitForever(const char* logname) { 58ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall ATRACE_CALL(); 59ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall if (mFenceFd == -1) { 60ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall return NO_ERROR; 61ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall } 62d31824004277f554000417cea349d69f18655e95Dan Stoza int warningTimeout = 3000; 63ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall int err = sync_wait(mFenceFd, warningTimeout); 64b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian if (err < 0 && errno == ETIME) { 65df1baddb6f4a13e7253ca547549b3157725c3121Chia-I Wu ALOGE("%s: fence %d didn't signal in %u ms", logname, mFenceFd.get(), 66ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall warningTimeout); 67ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall err = sync_wait(mFenceFd, TIMEOUT_NEVER); 68ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall } 69b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian return err < 0 ? -errno : status_t(NO_ERROR); 70ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall} 71ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall 72fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyacksp<Fence> Fence::merge(const char* name, const sp<Fence>& f1, 73f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis const sp<Fence>& f2) { 74f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis ATRACE_CALL(); 751df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis int result; 761df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis // Merge the two fences. In the case where one of the fences is not a 771df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis // valid fence (e.g. NO_FENCE) we merge the one valid fence with itself so 781df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis // that a new fence with the given name is created. 791df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis if (f1->isValid() && f2->isValid()) { 80fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack result = sync_merge(name, f1->mFenceFd, f2->mFenceFd); 811df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } else if (f1->isValid()) { 82fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack result = sync_merge(name, f1->mFenceFd, f1->mFenceFd); 831df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } else if (f2->isValid()) { 84fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack result = sync_merge(name, f2->mFenceFd, f2->mFenceFd); 851df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } else { 861df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis return NO_FENCE; 871df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } 88f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis if (result == -1) { 89d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian status_t err = -errno; 90d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian ALOGE("merge: sync_merge(\"%s\", %d, %d) returned an error: %s (%d)", 91df1baddb6f4a13e7253ca547549b3157725c3121Chia-I Wu name, f1->mFenceFd.get(), f2->mFenceFd.get(), 92d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian strerror(-err), err); 93ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall return NO_FENCE; 94f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis } 95f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return sp<Fence>(new Fence(result)); 96f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 97f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 98fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyacksp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1, 99fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack const sp<Fence>& f2) { 100fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack return merge(name.string(), f1, f2); 101fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack} 102fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack 103f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hallint Fence::dup() const { 104f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall return ::dup(mFenceFd); 105f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall} 106f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall 10782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennisnsecs_t Fence::getSignalTime() const { 10882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis if (mFenceFd == -1) { 109221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return SIGNAL_TIME_INVALID; 11082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 11182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 11282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis struct sync_fence_info_data* finfo = sync_fence_info(mFenceFd); 11382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis if (finfo == NULL) { 114df1baddb6f4a13e7253ca547549b3157725c3121Chia-I Wu ALOGE("sync_fence_info returned NULL for fd %d", mFenceFd.get()); 115221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return SIGNAL_TIME_INVALID; 11682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 11782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis if (finfo->status != 1) { 1187c36cd231542990e0ef8240fcc8dfd35a9e4b38bJesse Hall sync_fence_info_free(finfo); 119221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return SIGNAL_TIME_PENDING; 12082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 12182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 12282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis struct sync_pt_info* pinfo = NULL; 12382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis uint64_t timestamp = 0; 12482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis while ((pinfo = sync_pt_info(finfo, pinfo)) != NULL) { 12582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis if (pinfo->timestamp_ns > timestamp) { 12682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis timestamp = pinfo->timestamp_ns; 12782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 12882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 12982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis sync_fence_info_free(finfo); 13082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 13182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis return nsecs_t(timestamp); 13282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis} 13382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 134f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennissize_t Fence::getFlattenedSize() const { 1356fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza return 4; 136f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 137f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 138f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennissize_t Fence::getFdCount() const { 1391df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis return isValid() ? 1 : 0; 140f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 141f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 142e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopianstatus_t Fence::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const { 143e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian if (size < getFlattenedSize() || count < getFdCount()) { 144e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian return NO_MEMORY; 145f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis } 1466fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza // Cast to uint32_t since the size of a size_t can vary between 32- and 1476fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza // 64-bit processes 1486fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza FlattenableUtils::write(buffer, size, static_cast<uint32_t>(getFdCount())); 1491df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis if (isValid()) { 150e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian *fds++ = mFenceFd; 151e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian count--; 1521df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } 153f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return NO_ERROR; 154f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 155f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 156e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopianstatus_t Fence::unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count) { 157f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis if (mFenceFd != -1) { 158f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // Don't unflatten if we already have a valid fd. 159f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return INVALID_OPERATION; 160f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis } 161f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 1629809602ac32dcb7bceaa5bc34df5b7fb68aacd38Chris Forbes if (size < getFlattenedSize()) { 163e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian return NO_MEMORY; 164e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian } 165e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian 166288f2ef6294b99a4a53355273ae8ad0f5a525f65Colin Cross uint32_t numFds; 167e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian FlattenableUtils::read(buffer, size, numFds); 168e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian 169e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian if (numFds > 1) { 170e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian return BAD_VALUE; 171e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian } 172e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian 173e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian if (count < numFds) { 174e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian return NO_MEMORY; 175e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian } 176e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian 177e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian if (numFds) { 178df1baddb6f4a13e7253ca547549b3157725c3121Chia-I Wu mFenceFd.reset(*fds++); 179e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian count--; 1801df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } 1811df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis 182f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return NO_ERROR; 183f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 184f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 185f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} // namespace android 186