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