Fence.cpp revision 221de2a33d456738f7f64db0b015a960211d4834
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 17f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#define LOG_TAG "Fence" 18f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS 19f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis//#define LOG_NDEBUG 0 20f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 21d31824004277f554000417cea349d69f18655e95Dan Stoza// We would eliminate the non-conforming zero-length array, but we can't since 22d31824004277f554000417cea349d69f18655e95Dan Stoza// this is effectively included from the Linux kernel 23d31824004277f554000417cea349d69f18655e95Dan Stoza#pragma clang diagnostic push 24d31824004277f554000417cea349d69f18655e95Dan Stoza#pragma clang diagnostic ignored "-Wzero-length-array" 25f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <sync/sync.h> 26d31824004277f554000417cea349d69f18655e95Dan Stoza#pragma clang diagnostic pop 27d31824004277f554000417cea349d69f18655e95Dan Stoza 28f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <ui/Fence.h> 29f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <unistd.h> 30f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <utils/Log.h> 31f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <utils/Trace.h> 32f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 33f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennisnamespace android { 34f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 351df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennisconst sp<Fence> Fence::NO_FENCE = sp<Fence>(new Fence); 36ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall 37f25e183a70bd631f75dce51e85b7d568472a0cdbJamie GennisFence::Fence() : 38f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis mFenceFd(-1) { 39f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 40f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 41f25e183a70bd631f75dce51e85b7d568472a0cdbJamie GennisFence::Fence(int fenceFd) : 42f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis mFenceFd(fenceFd) { 43f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 44f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 45f25e183a70bd631f75dce51e85b7d568472a0cdbJamie GennisFence::~Fence() { 46f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis if (mFenceFd != -1) { 47f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis close(mFenceFd); 48f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis } 49f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 50f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 51d31824004277f554000417cea349d69f18655e95Dan Stozastatus_t Fence::wait(int timeout) { 52f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis ATRACE_CALL(); 53f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis if (mFenceFd == -1) { 54f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return NO_ERROR; 55f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis } 56b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian int err = sync_wait(mFenceFd, timeout); 57b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian return err < 0 ? -errno : status_t(NO_ERROR); 58f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 59f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 60ea74d3b78d607cde17790a7bb83e6f68ffd34cfdMathias Agopianstatus_t Fence::waitForever(const char* logname) { 61ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall ATRACE_CALL(); 62ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall if (mFenceFd == -1) { 63ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall return NO_ERROR; 64ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall } 65d31824004277f554000417cea349d69f18655e95Dan Stoza int warningTimeout = 3000; 66ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall int err = sync_wait(mFenceFd, warningTimeout); 67b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian if (err < 0 && errno == ETIME) { 68ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall ALOGE("%s: fence %d didn't signal in %u ms", logname, mFenceFd, 69ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall warningTimeout); 70ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall err = sync_wait(mFenceFd, TIMEOUT_NEVER); 71ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall } 72b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian return err < 0 ? -errno : status_t(NO_ERROR); 73ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall} 74ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall 75fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyacksp<Fence> Fence::merge(const char* name, const sp<Fence>& f1, 76f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis const sp<Fence>& f2) { 77f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis ATRACE_CALL(); 781df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis int result; 791df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis // Merge the two fences. In the case where one of the fences is not a 801df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis // valid fence (e.g. NO_FENCE) we merge the one valid fence with itself so 811df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis // that a new fence with the given name is created. 821df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis if (f1->isValid() && f2->isValid()) { 83fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack result = sync_merge(name, f1->mFenceFd, f2->mFenceFd); 841df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } else if (f1->isValid()) { 85fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack result = sync_merge(name, f1->mFenceFd, f1->mFenceFd); 861df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } else if (f2->isValid()) { 87fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack result = sync_merge(name, f2->mFenceFd, f2->mFenceFd); 881df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } else { 891df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis return NO_FENCE; 901df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } 91f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis if (result == -1) { 92d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian status_t err = -errno; 93d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian ALOGE("merge: sync_merge(\"%s\", %d, %d) returned an error: %s (%d)", 94fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack name, f1->mFenceFd, f2->mFenceFd, 95d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian strerror(-err), err); 96ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall return NO_FENCE; 97f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis } 98f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return sp<Fence>(new Fence(result)); 99f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 100f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 101fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyacksp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1, 102fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack const sp<Fence>& f2) { 103fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack return merge(name.string(), f1, f2); 104fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack} 105fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack 106f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hallint Fence::dup() const { 107f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall return ::dup(mFenceFd); 108f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall} 109f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall 11082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennisnsecs_t Fence::getSignalTime() const { 11182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis if (mFenceFd == -1) { 112221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return SIGNAL_TIME_INVALID; 11382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 11482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 11582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis struct sync_fence_info_data* finfo = sync_fence_info(mFenceFd); 11682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis if (finfo == NULL) { 11782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis ALOGE("sync_fence_info returned NULL for fd %d", mFenceFd); 118221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return SIGNAL_TIME_INVALID; 11982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 12082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis if (finfo->status != 1) { 1217c36cd231542990e0ef8240fcc8dfd35a9e4b38bJesse Hall sync_fence_info_free(finfo); 122221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return SIGNAL_TIME_PENDING; 12382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 12482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 12582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis struct sync_pt_info* pinfo = NULL; 12682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis uint64_t timestamp = 0; 12782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis while ((pinfo = sync_pt_info(finfo, pinfo)) != NULL) { 12882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis if (pinfo->timestamp_ns > timestamp) { 12982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis timestamp = pinfo->timestamp_ns; 13082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 13182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 13282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis sync_fence_info_free(finfo); 13382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 13482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis return nsecs_t(timestamp); 13582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis} 13682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 137f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennissize_t Fence::getFlattenedSize() const { 1386fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza return 4; 139f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 140f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 141f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennissize_t Fence::getFdCount() const { 1421df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis return isValid() ? 1 : 0; 143f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 144f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 145e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopianstatus_t Fence::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const { 146e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian if (size < getFlattenedSize() || count < getFdCount()) { 147e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian return NO_MEMORY; 148f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis } 1496fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza // Cast to uint32_t since the size of a size_t can vary between 32- and 1506fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza // 64-bit processes 1516fbefbbd8edc9953041289fbd77bb18c4964dce5Dan Stoza FlattenableUtils::write(buffer, size, static_cast<uint32_t>(getFdCount())); 1521df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis if (isValid()) { 153e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian *fds++ = mFenceFd; 154e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian count--; 1551df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } 156f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return NO_ERROR; 157f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 158f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 159e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopianstatus_t Fence::unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count) { 160f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis if (mFenceFd != -1) { 161f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // Don't unflatten if we already have a valid fd. 162f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return INVALID_OPERATION; 163f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis } 164f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 165e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian if (size < 1) { 166e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian return NO_MEMORY; 167e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian } 168e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian 169288f2ef6294b99a4a53355273ae8ad0f5a525f65Colin Cross uint32_t numFds; 170e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian FlattenableUtils::read(buffer, size, numFds); 171e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian 172e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian if (numFds > 1) { 173e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian return BAD_VALUE; 174e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian } 175e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian 176e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian if (count < numFds) { 177e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian return NO_MEMORY; 178e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian } 179e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian 180e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian if (numFds) { 181e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian mFenceFd = *fds++; 182e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian count--; 1831df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } 1841df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis 185f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return NO_ERROR; 186f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 187f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 188f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} // namespace android 189