1221de2a33d456738f7f64db0b015a960211d4834Brian Anderson/* 2221de2a33d456738f7f64db0b015a960211d4834Brian Anderson* Copyright 2016 The Android Open Source Project 3221de2a33d456738f7f64db0b015a960211d4834Brian Anderson* 4221de2a33d456738f7f64db0b015a960211d4834Brian Anderson* Licensed under the Apache License, Version 2.0 (the "License"); 5221de2a33d456738f7f64db0b015a960211d4834Brian Anderson* you may not use this file except in compliance with the License. 6221de2a33d456738f7f64db0b015a960211d4834Brian Anderson* You may obtain a copy of the License at 7221de2a33d456738f7f64db0b015a960211d4834Brian Anderson* 8221de2a33d456738f7f64db0b015a960211d4834Brian Anderson* http://www.apache.org/licenses/LICENSE-2.0 9221de2a33d456738f7f64db0b015a960211d4834Brian Anderson* 10221de2a33d456738f7f64db0b015a960211d4834Brian Anderson* Unless required by applicable law or agreed to in writing, software 11221de2a33d456738f7f64db0b015a960211d4834Brian Anderson* distributed under the License is distributed on an "AS IS" BASIS, 12221de2a33d456738f7f64db0b015a960211d4834Brian Anderson* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13221de2a33d456738f7f64db0b015a960211d4834Brian Anderson* See the License for the specific language governing permissions and 14221de2a33d456738f7f64db0b015a960211d4834Brian Anderson* limitations under the License. 15221de2a33d456738f7f64db0b015a960211d4834Brian Anderson*/ 16221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 17221de2a33d456738f7f64db0b015a960211d4834Brian Anderson#include <ui/FenceTime.h> 18221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 198cc8b10e27d515a6962ae6c66a62387ced45f5feBrian Anderson#define LOG_TAG "FenceTime" 208cc8b10e27d515a6962ae6c66a62387ced45f5feBrian Anderson 21221de2a33d456738f7f64db0b015a960211d4834Brian Anderson#include <cutils/compiler.h> // For CC_[UN]LIKELY 22175a7206c5aea70236b916d7707ab25025eb9cd6Brian Anderson#include <utils/Log.h> 23221de2a33d456738f7f64db0b015a960211d4834Brian Anderson#include <inttypes.h> 24221de2a33d456738f7f64db0b015a960211d4834Brian Anderson#include <stdlib.h> 25221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 26221de2a33d456738f7f64db0b015a960211d4834Brian Anderson#include <memory> 27221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 28221de2a33d456738f7f64db0b015a960211d4834Brian Andersonnamespace android { 29221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 30221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// ============================================================================ 31221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// FenceTime 32221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// ============================================================================ 33221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 34221de2a33d456738f7f64db0b015a960211d4834Brian Andersonconst auto FenceTime::NO_FENCE = std::make_shared<FenceTime>(Fence::NO_FENCE); 35221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 36221de2a33d456738f7f64db0b015a960211d4834Brian Andersonvoid* FenceTime::operator new(size_t byteCount) noexcept { 37221de2a33d456738f7f64db0b015a960211d4834Brian Anderson void *p = nullptr; 38221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (posix_memalign(&p, alignof(FenceTime), byteCount)) { 39221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return nullptr; 40221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 41221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return p; 42221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 43221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 44221de2a33d456738f7f64db0b015a960211d4834Brian Andersonvoid FenceTime::operator delete(void *p) { 45221de2a33d456738f7f64db0b015a960211d4834Brian Anderson free(p); 46221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 47221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 48221de2a33d456738f7f64db0b015a960211d4834Brian AndersonFenceTime::FenceTime(const sp<Fence>& fence) 49221de2a33d456738f7f64db0b015a960211d4834Brian Anderson : mState(((fence.get() != nullptr) && fence->isValid()) ? 50221de2a33d456738f7f64db0b015a960211d4834Brian Anderson State::VALID : State::INVALID), 51221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mFence(fence), 52221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mSignalTime(mState == State::INVALID ? 53221de2a33d456738f7f64db0b015a960211d4834Brian Anderson Fence::SIGNAL_TIME_INVALID : Fence::SIGNAL_TIME_PENDING) { 54221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 55221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 56221de2a33d456738f7f64db0b015a960211d4834Brian AndersonFenceTime::FenceTime(sp<Fence>&& fence) 57221de2a33d456738f7f64db0b015a960211d4834Brian Anderson : mState(((fence.get() != nullptr) && fence->isValid()) ? 58221de2a33d456738f7f64db0b015a960211d4834Brian Anderson State::VALID : State::INVALID), 59221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mFence(std::move(fence)), 60221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mSignalTime(mState == State::INVALID ? 61221de2a33d456738f7f64db0b015a960211d4834Brian Anderson Fence::SIGNAL_TIME_INVALID : Fence::SIGNAL_TIME_PENDING) { 62221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 63221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 64221de2a33d456738f7f64db0b015a960211d4834Brian AndersonFenceTime::FenceTime(nsecs_t signalTime) 65221de2a33d456738f7f64db0b015a960211d4834Brian Anderson : mState(Fence::isValidTimestamp(signalTime) ? State::VALID : State::INVALID), 66221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mFence(nullptr), 678cc8b10e27d515a6962ae6c66a62387ced45f5feBrian Anderson mSignalTime(signalTime) { 688cc8b10e27d515a6962ae6c66a62387ced45f5feBrian Anderson if (CC_UNLIKELY(mSignalTime == Fence::SIGNAL_TIME_PENDING)) { 698cc8b10e27d515a6962ae6c66a62387ced45f5feBrian Anderson ALOGE("Pending signal time not allowed after signal."); 708cc8b10e27d515a6962ae6c66a62387ced45f5feBrian Anderson mSignalTime = Fence::SIGNAL_TIME_INVALID; 718cc8b10e27d515a6962ae6c66a62387ced45f5feBrian Anderson } 72221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 73221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 74221de2a33d456738f7f64db0b015a960211d4834Brian Andersonvoid FenceTime::applyTrustedSnapshot(const Snapshot& src) { 75221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (CC_UNLIKELY(src.state != Snapshot::State::SIGNAL_TIME)) { 76221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Applying Snapshot::State::FENCE, could change the valid state of the 77221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // FenceTime, which is not allowed. Callers should create a new 78221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // FenceTime from the snapshot instead. 798cc8b10e27d515a6962ae6c66a62387ced45f5feBrian Anderson ALOGE("applyTrustedSnapshot: Unexpected fence."); 80221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return; 81221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 82221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 83221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (src.state == Snapshot::State::EMPTY) { 84221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return; 85221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 86221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 87221de2a33d456738f7f64db0b015a960211d4834Brian Anderson nsecs_t signalTime = mSignalTime.load(std::memory_order_relaxed); 88221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (signalTime != Fence::SIGNAL_TIME_PENDING) { 89221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // We should always get the same signalTime here that we did in 90221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // getSignalTime(). This check races with getSignalTime(), but it is 91221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // only a sanity check so that's okay. 92221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (CC_UNLIKELY(signalTime != src.signalTime)) { 93221de2a33d456738f7f64db0b015a960211d4834Brian Anderson ALOGE("FenceTime::applyTrustedSnapshot: signalTime mismatch. " 94221de2a33d456738f7f64db0b015a960211d4834Brian Anderson "(%" PRId64 " (old) != %" PRId64 " (new))", 95221de2a33d456738f7f64db0b015a960211d4834Brian Anderson signalTime, src.signalTime); 96221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 97221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return; 98221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 99221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 100221de2a33d456738f7f64db0b015a960211d4834Brian Anderson std::lock_guard<std::mutex> lock(mMutex); 101221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mFence.clear(); 102221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mSignalTime.store(src.signalTime, std::memory_order_relaxed); 103221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 104221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 105221de2a33d456738f7f64db0b015a960211d4834Brian Andersonbool FenceTime::isValid() const { 106221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // We store the valid state in the constructors and return it here. 107221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // This lets release code remember the valid state even after the 108221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // underlying fence is destroyed. 109221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return mState != State::INVALID; 110221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 111221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 112221de2a33d456738f7f64db0b015a960211d4834Brian Andersonnsecs_t FenceTime::getSignalTime() { 113221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // See if we already have a cached value we can return. 114221de2a33d456738f7f64db0b015a960211d4834Brian Anderson nsecs_t signalTime = mSignalTime.load(std::memory_order_relaxed); 115221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (signalTime != Fence::SIGNAL_TIME_PENDING) { 116221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return signalTime; 117221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 118221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 119221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Hold a reference to the fence on the stack in case the class' 120221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // reference is removed by another thread. This prevents the 121221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // fence from being destroyed until the end of this method, where 122221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // we conveniently do not have the lock held. 123221de2a33d456738f7f64db0b015a960211d4834Brian Anderson sp<Fence> fence; 124221de2a33d456738f7f64db0b015a960211d4834Brian Anderson { 125221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // With the lock acquired this time, see if we have the cached 126221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // value or if we need to poll the fence. 127221de2a33d456738f7f64db0b015a960211d4834Brian Anderson std::lock_guard<std::mutex> lock(mMutex); 128221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (!mFence.get()) { 129221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Another thread set the signal time just before we added the 130221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // reference to mFence. 131221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return mSignalTime.load(std::memory_order_relaxed); 132221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 133221de2a33d456738f7f64db0b015a960211d4834Brian Anderson fence = mFence; 134221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 135221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 136221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Make the system call without the lock held. 137221de2a33d456738f7f64db0b015a960211d4834Brian Anderson signalTime = fence->getSignalTime(); 138221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 1393da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson // Allow tests to override SIGNAL_TIME_INVALID behavior, since tests 1403da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson // use invalid underlying Fences without real file descriptors. 1413da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson if (CC_UNLIKELY(mState == State::FORCED_VALID_FOR_TEST)) { 1423da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson if (signalTime == Fence::SIGNAL_TIME_INVALID) { 1433da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson signalTime = Fence::SIGNAL_TIME_PENDING; 1443da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson } 1453da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson } 1463da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson 147221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Make the signal time visible to everyone if it is no longer pending 148221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // and remove the class' reference to the fence. 149221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (signalTime != Fence::SIGNAL_TIME_PENDING) { 150221de2a33d456738f7f64db0b015a960211d4834Brian Anderson std::lock_guard<std::mutex> lock(mMutex); 151221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mFence.clear(); 152221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mSignalTime.store(signalTime, std::memory_order_relaxed); 153221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 154221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 155221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return signalTime; 156221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 157221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 158221de2a33d456738f7f64db0b015a960211d4834Brian Andersonnsecs_t FenceTime::getCachedSignalTime() const { 159221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // memory_order_acquire since we don't have a lock fallback path 160221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // that will do an acquire. 161221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return mSignalTime.load(std::memory_order_acquire); 162221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 163221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 164221de2a33d456738f7f64db0b015a960211d4834Brian AndersonFenceTime::Snapshot FenceTime::getSnapshot() const { 165221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Quick check without the lock. 166221de2a33d456738f7f64db0b015a960211d4834Brian Anderson nsecs_t signalTime = mSignalTime.load(std::memory_order_relaxed); 167221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (signalTime != Fence::SIGNAL_TIME_PENDING) { 168221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return Snapshot(signalTime); 169221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 170221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 171221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Do the full check with the lock. 172221de2a33d456738f7f64db0b015a960211d4834Brian Anderson std::lock_guard<std::mutex> lock(mMutex); 173221de2a33d456738f7f64db0b015a960211d4834Brian Anderson signalTime = mSignalTime.load(std::memory_order_relaxed); 174221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (signalTime != Fence::SIGNAL_TIME_PENDING) { 175221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return Snapshot(signalTime); 176221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 177221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return Snapshot(mFence); 178221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 179221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 1803da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// For tests only. If forceValidForTest is true, then getSignalTime will 1813da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// never return SIGNAL_TIME_INVALID and isValid will always return true. 1823da8d2748580b2575e368e203ce2c7f8d34dea05Brian AndersonFenceTime::FenceTime(const sp<Fence>& fence, bool forceValidForTest) 1833da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson : mState(forceValidForTest ? 1843da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson State::FORCED_VALID_FOR_TEST : State::INVALID), 1853da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson mFence(fence), 1863da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson mSignalTime(mState == State::INVALID ? 1873da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson Fence::SIGNAL_TIME_INVALID : Fence::SIGNAL_TIME_PENDING) { 1883da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson} 1893da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson 1903da8d2748580b2575e368e203ce2c7f8d34dea05Brian Andersonvoid FenceTime::signalForTest(nsecs_t signalTime) { 1913da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson // To be realistic, this should really set a hidden value that 1923da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson // gets picked up in the next call to getSignalTime, but this should 1933da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson // be good enough. 1943da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson std::lock_guard<std::mutex> lock(mMutex); 1953da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson mFence.clear(); 1963da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson mSignalTime.store(signalTime, std::memory_order_relaxed); 1973da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson} 1983da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson 199221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// ============================================================================ 200221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// FenceTime::Snapshot 201221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// ============================================================================ 202221de2a33d456738f7f64db0b015a960211d4834Brian AndersonFenceTime::Snapshot::Snapshot(const sp<Fence>& srcFence) 203221de2a33d456738f7f64db0b015a960211d4834Brian Anderson : state(State::FENCE), fence(srcFence) { 204221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 205221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 206221de2a33d456738f7f64db0b015a960211d4834Brian AndersonFenceTime::Snapshot::Snapshot(nsecs_t srcSignalTime) 207221de2a33d456738f7f64db0b015a960211d4834Brian Anderson : state(State::SIGNAL_TIME), signalTime(srcSignalTime) { 208221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 209221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 210221de2a33d456738f7f64db0b015a960211d4834Brian Andersonsize_t FenceTime::Snapshot::getFlattenedSize() const { 211221de2a33d456738f7f64db0b015a960211d4834Brian Anderson constexpr size_t min = sizeof(state); 212221de2a33d456738f7f64db0b015a960211d4834Brian Anderson switch (state) { 213221de2a33d456738f7f64db0b015a960211d4834Brian Anderson case State::EMPTY: 214221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return min; 215221de2a33d456738f7f64db0b015a960211d4834Brian Anderson case State::FENCE: 216221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return min + fence->getFlattenedSize(); 217221de2a33d456738f7f64db0b015a960211d4834Brian Anderson case State::SIGNAL_TIME: 218221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return min + sizeof(signalTime); 219221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 220221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return 0; 221221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 222221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 223221de2a33d456738f7f64db0b015a960211d4834Brian Andersonsize_t FenceTime::Snapshot::getFdCount() const { 224221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return state == State::FENCE ? fence->getFdCount() : 0u; 225221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 226221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 227221de2a33d456738f7f64db0b015a960211d4834Brian Andersonstatus_t FenceTime::Snapshot::flatten( 228221de2a33d456738f7f64db0b015a960211d4834Brian Anderson void*& buffer, size_t& size, int*& fds, size_t& count) const { 229221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (size < getFlattenedSize()) { 230221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return NO_MEMORY; 231221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 232221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 233221de2a33d456738f7f64db0b015a960211d4834Brian Anderson FlattenableUtils::write(buffer, size, state); 234221de2a33d456738f7f64db0b015a960211d4834Brian Anderson switch (state) { 235221de2a33d456738f7f64db0b015a960211d4834Brian Anderson case State::EMPTY: 236221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return NO_ERROR; 237221de2a33d456738f7f64db0b015a960211d4834Brian Anderson case State::FENCE: 238221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return fence->flatten(buffer, size, fds, count); 239221de2a33d456738f7f64db0b015a960211d4834Brian Anderson case State::SIGNAL_TIME: 240221de2a33d456738f7f64db0b015a960211d4834Brian Anderson FlattenableUtils::write(buffer, size, signalTime); 241221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return NO_ERROR; 242221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 243221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 244221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return NO_ERROR; 245221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 246221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 247221de2a33d456738f7f64db0b015a960211d4834Brian Andersonstatus_t FenceTime::Snapshot::unflatten( 248221de2a33d456738f7f64db0b015a960211d4834Brian Anderson void const*& buffer, size_t& size, int const*& fds, size_t& count) { 249221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (size < sizeof(state)) { 250221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return NO_MEMORY; 251221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 252221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 253221de2a33d456738f7f64db0b015a960211d4834Brian Anderson FlattenableUtils::read(buffer, size, state); 254221de2a33d456738f7f64db0b015a960211d4834Brian Anderson switch (state) { 255221de2a33d456738f7f64db0b015a960211d4834Brian Anderson case State::EMPTY: 256221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return NO_ERROR; 257221de2a33d456738f7f64db0b015a960211d4834Brian Anderson case State::FENCE: 258221de2a33d456738f7f64db0b015a960211d4834Brian Anderson fence = new Fence; 259221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return fence->unflatten(buffer, size, fds, count); 260221de2a33d456738f7f64db0b015a960211d4834Brian Anderson case State::SIGNAL_TIME: 261221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (size < sizeof(signalTime)) { 262221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return NO_MEMORY; 263221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 264221de2a33d456738f7f64db0b015a960211d4834Brian Anderson FlattenableUtils::read(buffer, size, signalTime); 265221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return NO_ERROR; 266221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 267221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 268221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return NO_ERROR; 269221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 270221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 271221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// ============================================================================ 272221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// FenceTimeline 273221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// ============================================================================ 274221de2a33d456738f7f64db0b015a960211d4834Brian Andersonvoid FenceTimeline::push(const std::shared_ptr<FenceTime>& fence) { 275221de2a33d456738f7f64db0b015a960211d4834Brian Anderson std::lock_guard<std::mutex> lock(mMutex); 276221de2a33d456738f7f64db0b015a960211d4834Brian Anderson while (mQueue.size() >= MAX_ENTRIES) { 277221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // This is a sanity check to make sure the queue doesn't grow unbounded. 278221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // MAX_ENTRIES should be big enough not to trigger this path. 279221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // In case this path is taken though, users of FenceTime must make sure 280221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // not to rely solely on FenceTimeline to get the final timestamp and 281221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // should eventually call Fence::getSignalTime on their own. 282221de2a33d456738f7f64db0b015a960211d4834Brian Anderson std::shared_ptr<FenceTime> front = mQueue.front().lock(); 283221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (front) { 284221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Make a last ditch effort to get the signalTime here since 285221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // we are removing it from the timeline. 286221de2a33d456738f7f64db0b015a960211d4834Brian Anderson front->getSignalTime(); 287221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 288221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mQueue.pop(); 289221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 290221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mQueue.push(fence); 291221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 292221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 293221de2a33d456738f7f64db0b015a960211d4834Brian Andersonvoid FenceTimeline::updateSignalTimes() { 294221de2a33d456738f7f64db0b015a960211d4834Brian Anderson while (!mQueue.empty()) { 295221de2a33d456738f7f64db0b015a960211d4834Brian Anderson std::lock_guard<std::mutex> lock(mMutex); 296221de2a33d456738f7f64db0b015a960211d4834Brian Anderson std::shared_ptr<FenceTime> fence = mQueue.front().lock(); 297221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (!fence) { 298221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // The shared_ptr no longer exists and no one cares about the 299221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // timestamp anymore. 300221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mQueue.pop(); 301221de2a33d456738f7f64db0b015a960211d4834Brian Anderson continue; 302221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } else if (fence->getSignalTime() != Fence::SIGNAL_TIME_PENDING) { 303221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // The fence has signaled and we've removed the sp<Fence> ref. 304221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mQueue.pop(); 305221de2a33d456738f7f64db0b015a960211d4834Brian Anderson continue; 306221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } else { 307221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // The fence didn't signal yet. Break since the later ones 308221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // shouldn't have signaled either. 309221de2a33d456738f7f64db0b015a960211d4834Brian Anderson break; 310221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 311221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 312221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 313221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 3143da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// ============================================================================ 3153da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// FenceToFenceTimeMap 3163da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// ============================================================================ 3173da8d2748580b2575e368e203ce2c7f8d34dea05Brian Andersonstd::shared_ptr<FenceTime> FenceToFenceTimeMap::createFenceTimeForTest( 3183da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson const sp<Fence>& fence) { 3193da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson std::lock_guard<std::mutex> lock(mMutex); 3203da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson // Always garbage collecting isn't efficient, but this is only for testing. 3213da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson garbageCollectLocked(); 3223da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson std::shared_ptr<FenceTime> fenceTime(new FenceTime(fence, true)); 3233da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson mMap[fence.get()].push_back(fenceTime); 3243da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson return fenceTime; 3253da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson} 3263da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson 3273da8d2748580b2575e368e203ce2c7f8d34dea05Brian Andersonvoid FenceToFenceTimeMap::signalAllForTest( 3283da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson const sp<Fence>& fence, nsecs_t signalTime) { 3293da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson bool signaled = false; 3303da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson 3313da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson std::lock_guard<std::mutex> lock(mMutex); 3323da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson auto it = mMap.find(fence.get()); 3333da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson if (it != mMap.end()) { 3343da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson for (auto& weakFenceTime : it->second) { 3353da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson std::shared_ptr<FenceTime> fenceTime = weakFenceTime.lock(); 3363da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson if (!fenceTime) { 3373da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson continue; 3383da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson } 3393da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson ALOGE_IF(!fenceTime->isValid(), 3408cc8b10e27d515a6962ae6c66a62387ced45f5feBrian Anderson "signalAllForTest: Signaling invalid fence."); 3413da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson fenceTime->signalForTest(signalTime); 3423da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson signaled = true; 3433da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson } 3443da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson } 3453da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson 3468cc8b10e27d515a6962ae6c66a62387ced45f5feBrian Anderson ALOGE_IF(!signaled, "signalAllForTest: Nothing to signal."); 3473da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson} 3483da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson 3493da8d2748580b2575e368e203ce2c7f8d34dea05Brian Andersonvoid FenceToFenceTimeMap::garbageCollectLocked() { 3503da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson for (auto& it : mMap) { 3513da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson // Erase all expired weak pointers from the vector. 3523da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson auto& vect = it.second; 3533da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson vect.erase( 3543da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson std::remove_if(vect.begin(), vect.end(), 3553da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson [](const std::weak_ptr<FenceTime>& ft) { 3563da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson return ft.expired(); 3573da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson }), 3583da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson vect.end()); 3593da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson 3603da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson // Also erase the map entry if the vector is now empty. 3613da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson if (vect.empty()) { 3623da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson mMap.erase(it.first); 3633da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson } 3643da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson } 3653da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson} 3663da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson 367221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} // namespace android 368