FenceTime.cpp revision 221de2a33d456738f7f64db0b015a960211d4834
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 19221de2a33d456738f7f64db0b015a960211d4834Brian Anderson#include <cutils/compiler.h> // For CC_[UN]LIKELY 20221de2a33d456738f7f64db0b015a960211d4834Brian Anderson#include <inttypes.h> 21221de2a33d456738f7f64db0b015a960211d4834Brian Anderson#include <stdlib.h> 22221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 23221de2a33d456738f7f64db0b015a960211d4834Brian Anderson#include <memory> 24221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 25221de2a33d456738f7f64db0b015a960211d4834Brian Andersonnamespace android { 26221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 27221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// ============================================================================ 28221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// FenceTime 29221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// ============================================================================ 30221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 31221de2a33d456738f7f64db0b015a960211d4834Brian Andersonconst auto FenceTime::NO_FENCE = std::make_shared<FenceTime>(Fence::NO_FENCE); 32221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 33221de2a33d456738f7f64db0b015a960211d4834Brian Andersonvoid* FenceTime::operator new(size_t byteCount) noexcept { 34221de2a33d456738f7f64db0b015a960211d4834Brian Anderson void *p = nullptr; 35221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (posix_memalign(&p, alignof(FenceTime), byteCount)) { 36221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return nullptr; 37221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 38221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return p; 39221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 40221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 41221de2a33d456738f7f64db0b015a960211d4834Brian Andersonvoid FenceTime::operator delete(void *p) { 42221de2a33d456738f7f64db0b015a960211d4834Brian Anderson free(p); 43221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 44221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 45221de2a33d456738f7f64db0b015a960211d4834Brian AndersonFenceTime::FenceTime(const sp<Fence>& fence) 46221de2a33d456738f7f64db0b015a960211d4834Brian Anderson : mState(((fence.get() != nullptr) && fence->isValid()) ? 47221de2a33d456738f7f64db0b015a960211d4834Brian Anderson State::VALID : State::INVALID), 48221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mFence(fence), 49221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mSignalTime(mState == State::INVALID ? 50221de2a33d456738f7f64db0b015a960211d4834Brian Anderson Fence::SIGNAL_TIME_INVALID : Fence::SIGNAL_TIME_PENDING) { 51221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 52221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 53221de2a33d456738f7f64db0b015a960211d4834Brian AndersonFenceTime::FenceTime(sp<Fence>&& fence) 54221de2a33d456738f7f64db0b015a960211d4834Brian Anderson : mState(((fence.get() != nullptr) && fence->isValid()) ? 55221de2a33d456738f7f64db0b015a960211d4834Brian Anderson State::VALID : State::INVALID), 56221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mFence(std::move(fence)), 57221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mSignalTime(mState == State::INVALID ? 58221de2a33d456738f7f64db0b015a960211d4834Brian Anderson Fence::SIGNAL_TIME_INVALID : Fence::SIGNAL_TIME_PENDING) { 59221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 60221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 61221de2a33d456738f7f64db0b015a960211d4834Brian AndersonFenceTime::FenceTime(nsecs_t signalTime) 62221de2a33d456738f7f64db0b015a960211d4834Brian Anderson : mState(Fence::isValidTimestamp(signalTime) ? State::VALID : State::INVALID), 63221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mFence(nullptr), 64221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mSignalTime(signalTime == Fence::SIGNAL_TIME_PENDING ? 65221de2a33d456738f7f64db0b015a960211d4834Brian Anderson Fence::SIGNAL_TIME_INVALID : signalTime) { 66221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 67221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 68221de2a33d456738f7f64db0b015a960211d4834Brian Andersonvoid FenceTime::applyTrustedSnapshot(const Snapshot& src) { 69221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (CC_UNLIKELY(src.state != Snapshot::State::SIGNAL_TIME)) { 70221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Applying Snapshot::State::FENCE, could change the valid state of the 71221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // FenceTime, which is not allowed. Callers should create a new 72221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // FenceTime from the snapshot instead. 73221de2a33d456738f7f64db0b015a960211d4834Brian Anderson ALOGE("FenceTime::applyTrustedSnapshot: Unexpected fence."); 74221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return; 75221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 76221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 77221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (src.state == Snapshot::State::EMPTY) { 78221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return; 79221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 80221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 81221de2a33d456738f7f64db0b015a960211d4834Brian Anderson nsecs_t signalTime = mSignalTime.load(std::memory_order_relaxed); 82221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (signalTime != Fence::SIGNAL_TIME_PENDING) { 83221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // We should always get the same signalTime here that we did in 84221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // getSignalTime(). This check races with getSignalTime(), but it is 85221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // only a sanity check so that's okay. 86221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (CC_UNLIKELY(signalTime != src.signalTime)) { 87221de2a33d456738f7f64db0b015a960211d4834Brian Anderson ALOGE("FenceTime::applyTrustedSnapshot: signalTime mismatch. " 88221de2a33d456738f7f64db0b015a960211d4834Brian Anderson "(%" PRId64 " (old) != %" PRId64 " (new))", 89221de2a33d456738f7f64db0b015a960211d4834Brian Anderson signalTime, src.signalTime); 90221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 91221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return; 92221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 93221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 94221de2a33d456738f7f64db0b015a960211d4834Brian Anderson std::lock_guard<std::mutex> lock(mMutex); 95221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mFence.clear(); 96221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mSignalTime.store(src.signalTime, std::memory_order_relaxed); 97221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 98221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 99221de2a33d456738f7f64db0b015a960211d4834Brian Andersonbool FenceTime::isValid() const { 100221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // We store the valid state in the constructors and return it here. 101221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // This lets release code remember the valid state even after the 102221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // underlying fence is destroyed. 103221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return mState != State::INVALID; 104221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 105221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 106221de2a33d456738f7f64db0b015a960211d4834Brian Andersonnsecs_t FenceTime::getSignalTime() { 107221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // See if we already have a cached value we can return. 108221de2a33d456738f7f64db0b015a960211d4834Brian Anderson nsecs_t signalTime = mSignalTime.load(std::memory_order_relaxed); 109221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (signalTime != Fence::SIGNAL_TIME_PENDING) { 110221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return signalTime; 111221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 112221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 113221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Hold a reference to the fence on the stack in case the class' 114221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // reference is removed by another thread. This prevents the 115221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // fence from being destroyed until the end of this method, where 116221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // we conveniently do not have the lock held. 117221de2a33d456738f7f64db0b015a960211d4834Brian Anderson sp<Fence> fence; 118221de2a33d456738f7f64db0b015a960211d4834Brian Anderson { 119221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // With the lock acquired this time, see if we have the cached 120221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // value or if we need to poll the fence. 121221de2a33d456738f7f64db0b015a960211d4834Brian Anderson std::lock_guard<std::mutex> lock(mMutex); 122221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (!mFence.get()) { 123221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Another thread set the signal time just before we added the 124221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // reference to mFence. 125221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return mSignalTime.load(std::memory_order_relaxed); 126221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 127221de2a33d456738f7f64db0b015a960211d4834Brian Anderson fence = mFence; 128221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 129221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 130221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Make the system call without the lock held. 131221de2a33d456738f7f64db0b015a960211d4834Brian Anderson signalTime = fence->getSignalTime(); 132221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 133221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Make the signal time visible to everyone if it is no longer pending 134221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // and remove the class' reference to the fence. 135221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (signalTime != Fence::SIGNAL_TIME_PENDING) { 136221de2a33d456738f7f64db0b015a960211d4834Brian Anderson std::lock_guard<std::mutex> lock(mMutex); 137221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mFence.clear(); 138221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mSignalTime.store(signalTime, std::memory_order_relaxed); 139221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 140221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 141221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return signalTime; 142221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 143221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 144221de2a33d456738f7f64db0b015a960211d4834Brian Andersonnsecs_t FenceTime::getCachedSignalTime() const { 145221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // memory_order_acquire since we don't have a lock fallback path 146221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // that will do an acquire. 147221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return mSignalTime.load(std::memory_order_acquire); 148221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 149221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 150221de2a33d456738f7f64db0b015a960211d4834Brian AndersonFenceTime::Snapshot FenceTime::getSnapshot() const { 151221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Quick check without the lock. 152221de2a33d456738f7f64db0b015a960211d4834Brian Anderson nsecs_t signalTime = mSignalTime.load(std::memory_order_relaxed); 153221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (signalTime != Fence::SIGNAL_TIME_PENDING) { 154221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return Snapshot(signalTime); 155221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 156221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 157221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Do the full check with the lock. 158221de2a33d456738f7f64db0b015a960211d4834Brian Anderson std::lock_guard<std::mutex> lock(mMutex); 159221de2a33d456738f7f64db0b015a960211d4834Brian Anderson signalTime = mSignalTime.load(std::memory_order_relaxed); 160221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (signalTime != Fence::SIGNAL_TIME_PENDING) { 161221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return Snapshot(signalTime); 162221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 163221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return Snapshot(mFence); 164221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 165221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 166221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// ============================================================================ 167221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// FenceTime::Snapshot 168221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// ============================================================================ 169221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 170221de2a33d456738f7f64db0b015a960211d4834Brian AndersonFenceTime::Snapshot::Snapshot(const sp<Fence>& srcFence) 171221de2a33d456738f7f64db0b015a960211d4834Brian Anderson : state(State::FENCE), fence(srcFence) { 172221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 173221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 174221de2a33d456738f7f64db0b015a960211d4834Brian AndersonFenceTime::Snapshot::Snapshot(nsecs_t srcSignalTime) 175221de2a33d456738f7f64db0b015a960211d4834Brian Anderson : state(State::SIGNAL_TIME), signalTime(srcSignalTime) { 176221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 177221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 178221de2a33d456738f7f64db0b015a960211d4834Brian Andersonsize_t FenceTime::Snapshot::getFlattenedSize() const { 179221de2a33d456738f7f64db0b015a960211d4834Brian Anderson constexpr size_t min = sizeof(state); 180221de2a33d456738f7f64db0b015a960211d4834Brian Anderson switch (state) { 181221de2a33d456738f7f64db0b015a960211d4834Brian Anderson case State::EMPTY: 182221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return min; 183221de2a33d456738f7f64db0b015a960211d4834Brian Anderson case State::FENCE: 184221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return min + fence->getFlattenedSize(); 185221de2a33d456738f7f64db0b015a960211d4834Brian Anderson case State::SIGNAL_TIME: 186221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return min + sizeof(signalTime); 187221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 188221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return 0; 189221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 190221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 191221de2a33d456738f7f64db0b015a960211d4834Brian Andersonsize_t FenceTime::Snapshot::getFdCount() const { 192221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return state == State::FENCE ? fence->getFdCount() : 0u; 193221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 194221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 195221de2a33d456738f7f64db0b015a960211d4834Brian Andersonstatus_t FenceTime::Snapshot::flatten( 196221de2a33d456738f7f64db0b015a960211d4834Brian Anderson void*& buffer, size_t& size, int*& fds, size_t& count) const { 197221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (size < getFlattenedSize()) { 198221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return NO_MEMORY; 199221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 200221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 201221de2a33d456738f7f64db0b015a960211d4834Brian Anderson FlattenableUtils::write(buffer, size, state); 202221de2a33d456738f7f64db0b015a960211d4834Brian Anderson switch (state) { 203221de2a33d456738f7f64db0b015a960211d4834Brian Anderson case State::EMPTY: 204221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return NO_ERROR; 205221de2a33d456738f7f64db0b015a960211d4834Brian Anderson case State::FENCE: 206221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return fence->flatten(buffer, size, fds, count); 207221de2a33d456738f7f64db0b015a960211d4834Brian Anderson case State::SIGNAL_TIME: 208221de2a33d456738f7f64db0b015a960211d4834Brian Anderson FlattenableUtils::write(buffer, size, signalTime); 209221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return NO_ERROR; 210221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 211221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 212221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return NO_ERROR; 213221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 214221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 215221de2a33d456738f7f64db0b015a960211d4834Brian Andersonstatus_t FenceTime::Snapshot::unflatten( 216221de2a33d456738f7f64db0b015a960211d4834Brian Anderson void const*& buffer, size_t& size, int const*& fds, size_t& count) { 217221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (size < sizeof(state)) { 218221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return NO_MEMORY; 219221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 220221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 221221de2a33d456738f7f64db0b015a960211d4834Brian Anderson FlattenableUtils::read(buffer, size, state); 222221de2a33d456738f7f64db0b015a960211d4834Brian Anderson switch (state) { 223221de2a33d456738f7f64db0b015a960211d4834Brian Anderson case State::EMPTY: 224221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return NO_ERROR; 225221de2a33d456738f7f64db0b015a960211d4834Brian Anderson case State::FENCE: 226221de2a33d456738f7f64db0b015a960211d4834Brian Anderson fence = new Fence; 227221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return fence->unflatten(buffer, size, fds, count); 228221de2a33d456738f7f64db0b015a960211d4834Brian Anderson case State::SIGNAL_TIME: 229221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (size < sizeof(signalTime)) { 230221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return NO_MEMORY; 231221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 232221de2a33d456738f7f64db0b015a960211d4834Brian Anderson FlattenableUtils::read(buffer, size, signalTime); 233221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return NO_ERROR; 234221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 235221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 236221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return NO_ERROR; 237221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 238221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 239221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// ============================================================================ 240221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// FenceTimeline 241221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// ============================================================================ 242221de2a33d456738f7f64db0b015a960211d4834Brian Andersonvoid FenceTimeline::push(const std::shared_ptr<FenceTime>& fence) { 243221de2a33d456738f7f64db0b015a960211d4834Brian Anderson std::lock_guard<std::mutex> lock(mMutex); 244221de2a33d456738f7f64db0b015a960211d4834Brian Anderson while (mQueue.size() >= MAX_ENTRIES) { 245221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // This is a sanity check to make sure the queue doesn't grow unbounded. 246221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // MAX_ENTRIES should be big enough not to trigger this path. 247221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // In case this path is taken though, users of FenceTime must make sure 248221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // not to rely solely on FenceTimeline to get the final timestamp and 249221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // should eventually call Fence::getSignalTime on their own. 250221de2a33d456738f7f64db0b015a960211d4834Brian Anderson std::shared_ptr<FenceTime> front = mQueue.front().lock(); 251221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (front) { 252221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Make a last ditch effort to get the signalTime here since 253221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // we are removing it from the timeline. 254221de2a33d456738f7f64db0b015a960211d4834Brian Anderson front->getSignalTime(); 255221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 256221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mQueue.pop(); 257221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 258221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mQueue.push(fence); 259221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 260221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 261221de2a33d456738f7f64db0b015a960211d4834Brian Andersonvoid FenceTimeline::updateSignalTimes() { 262221de2a33d456738f7f64db0b015a960211d4834Brian Anderson while (!mQueue.empty()) { 263221de2a33d456738f7f64db0b015a960211d4834Brian Anderson std::lock_guard<std::mutex> lock(mMutex); 264221de2a33d456738f7f64db0b015a960211d4834Brian Anderson std::shared_ptr<FenceTime> fence = mQueue.front().lock(); 265221de2a33d456738f7f64db0b015a960211d4834Brian Anderson if (!fence) { 266221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // The shared_ptr no longer exists and no one cares about the 267221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // timestamp anymore. 268221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mQueue.pop(); 269221de2a33d456738f7f64db0b015a960211d4834Brian Anderson continue; 270221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } else if (fence->getSignalTime() != Fence::SIGNAL_TIME_PENDING) { 271221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // The fence has signaled and we've removed the sp<Fence> ref. 272221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mQueue.pop(); 273221de2a33d456738f7f64db0b015a960211d4834Brian Anderson continue; 274221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } else { 275221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // The fence didn't signal yet. Break since the later ones 276221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // shouldn't have signaled either. 277221de2a33d456738f7f64db0b015a960211d4834Brian Anderson break; 278221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 279221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 280221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} 281221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 282221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} // namespace android 283