FenceTime.cpp revision 3da8d2748580b2575e368e203ce2c7f8d34dea05
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
1333da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    // Allow tests to override SIGNAL_TIME_INVALID behavior, since tests
1343da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    // use invalid underlying Fences without real file descriptors.
1353da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    if (CC_UNLIKELY(mState == State::FORCED_VALID_FOR_TEST)) {
1363da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson        if (signalTime == Fence::SIGNAL_TIME_INVALID) {
1373da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson            signalTime = Fence::SIGNAL_TIME_PENDING;
1383da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson        }
1393da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    }
1403da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson
141221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    // Make the signal time visible to everyone if it is no longer pending
142221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    // and remove the class' reference to the fence.
143221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    if (signalTime != Fence::SIGNAL_TIME_PENDING) {
144221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        std::lock_guard<std::mutex> lock(mMutex);
145221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        mFence.clear();
146221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        mSignalTime.store(signalTime, std::memory_order_relaxed);
147221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    }
148221de2a33d456738f7f64db0b015a960211d4834Brian Anderson
149221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    return signalTime;
150221de2a33d456738f7f64db0b015a960211d4834Brian Anderson}
151221de2a33d456738f7f64db0b015a960211d4834Brian Anderson
152221de2a33d456738f7f64db0b015a960211d4834Brian Andersonnsecs_t FenceTime::getCachedSignalTime() const {
153221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    // memory_order_acquire since we don't have a lock fallback path
154221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    // that will do an acquire.
155221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    return mSignalTime.load(std::memory_order_acquire);
156221de2a33d456738f7f64db0b015a960211d4834Brian Anderson}
157221de2a33d456738f7f64db0b015a960211d4834Brian Anderson
158221de2a33d456738f7f64db0b015a960211d4834Brian AndersonFenceTime::Snapshot FenceTime::getSnapshot() const {
159221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    // Quick check without the lock.
160221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    nsecs_t signalTime = mSignalTime.load(std::memory_order_relaxed);
161221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    if (signalTime != Fence::SIGNAL_TIME_PENDING) {
162221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        return Snapshot(signalTime);
163221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    }
164221de2a33d456738f7f64db0b015a960211d4834Brian Anderson
165221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    // Do the full check with the lock.
166221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    std::lock_guard<std::mutex> lock(mMutex);
167221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    signalTime = mSignalTime.load(std::memory_order_relaxed);
168221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    if (signalTime != Fence::SIGNAL_TIME_PENDING) {
169221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        return Snapshot(signalTime);
170221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    }
171221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    return Snapshot(mFence);
172221de2a33d456738f7f64db0b015a960211d4834Brian Anderson}
173221de2a33d456738f7f64db0b015a960211d4834Brian Anderson
1743da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// For tests only. If forceValidForTest is true, then getSignalTime will
1753da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// never return SIGNAL_TIME_INVALID and isValid will always return true.
1763da8d2748580b2575e368e203ce2c7f8d34dea05Brian AndersonFenceTime::FenceTime(const sp<Fence>& fence, bool forceValidForTest)
1773da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson  : mState(forceValidForTest ?
1783da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson            State::FORCED_VALID_FOR_TEST : State::INVALID),
1793da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    mFence(fence),
1803da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    mSignalTime(mState == State::INVALID ?
1813da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson            Fence::SIGNAL_TIME_INVALID : Fence::SIGNAL_TIME_PENDING) {
1823da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson}
1833da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson
1843da8d2748580b2575e368e203ce2c7f8d34dea05Brian Andersonvoid FenceTime::signalForTest(nsecs_t signalTime) {
1853da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    // To be realistic, this should really set a hidden value that
1863da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    // gets picked up in the next call to getSignalTime, but this should
1873da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    // be good enough.
1883da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    std::lock_guard<std::mutex> lock(mMutex);
1893da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    mFence.clear();
1903da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    mSignalTime.store(signalTime, std::memory_order_relaxed);
1913da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson}
1923da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson
193221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// ============================================================================
194221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// FenceTime::Snapshot
195221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// ============================================================================
196221de2a33d456738f7f64db0b015a960211d4834Brian AndersonFenceTime::Snapshot::Snapshot(const sp<Fence>& srcFence)
197221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    : state(State::FENCE), fence(srcFence) {
198221de2a33d456738f7f64db0b015a960211d4834Brian Anderson}
199221de2a33d456738f7f64db0b015a960211d4834Brian Anderson
200221de2a33d456738f7f64db0b015a960211d4834Brian AndersonFenceTime::Snapshot::Snapshot(nsecs_t srcSignalTime)
201221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    : state(State::SIGNAL_TIME), signalTime(srcSignalTime) {
202221de2a33d456738f7f64db0b015a960211d4834Brian Anderson}
203221de2a33d456738f7f64db0b015a960211d4834Brian Anderson
204221de2a33d456738f7f64db0b015a960211d4834Brian Andersonsize_t FenceTime::Snapshot::getFlattenedSize() const {
205221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    constexpr size_t min = sizeof(state);
206221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    switch (state) {
207221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        case State::EMPTY:
208221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            return min;
209221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        case State::FENCE:
210221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            return min + fence->getFlattenedSize();
211221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        case State::SIGNAL_TIME:
212221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            return min + sizeof(signalTime);
213221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    }
214221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    return 0;
215221de2a33d456738f7f64db0b015a960211d4834Brian Anderson}
216221de2a33d456738f7f64db0b015a960211d4834Brian Anderson
217221de2a33d456738f7f64db0b015a960211d4834Brian Andersonsize_t FenceTime::Snapshot::getFdCount() const {
218221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    return state == State::FENCE ? fence->getFdCount() : 0u;
219221de2a33d456738f7f64db0b015a960211d4834Brian Anderson}
220221de2a33d456738f7f64db0b015a960211d4834Brian Anderson
221221de2a33d456738f7f64db0b015a960211d4834Brian Andersonstatus_t FenceTime::Snapshot::flatten(
222221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        void*& buffer, size_t& size, int*& fds, size_t& count) const {
223221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    if (size < getFlattenedSize()) {
224221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        return NO_MEMORY;
225221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    }
226221de2a33d456738f7f64db0b015a960211d4834Brian Anderson
227221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    FlattenableUtils::write(buffer, size, state);
228221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    switch (state) {
229221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        case State::EMPTY:
230221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            return NO_ERROR;
231221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        case State::FENCE:
232221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            return fence->flatten(buffer, size, fds, count);
233221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        case State::SIGNAL_TIME:
234221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            FlattenableUtils::write(buffer, size, signalTime);
235221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            return NO_ERROR;
236221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    }
237221de2a33d456738f7f64db0b015a960211d4834Brian Anderson
238221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    return NO_ERROR;
239221de2a33d456738f7f64db0b015a960211d4834Brian Anderson}
240221de2a33d456738f7f64db0b015a960211d4834Brian Anderson
241221de2a33d456738f7f64db0b015a960211d4834Brian Andersonstatus_t FenceTime::Snapshot::unflatten(
242221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        void const*& buffer, size_t& size, int const*& fds, size_t& count) {
243221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    if (size < sizeof(state)) {
244221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        return NO_MEMORY;
245221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    }
246221de2a33d456738f7f64db0b015a960211d4834Brian Anderson
247221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    FlattenableUtils::read(buffer, size, state);
248221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    switch (state) {
249221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        case State::EMPTY:
250221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            return NO_ERROR;
251221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        case State::FENCE:
252221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            fence = new Fence;
253221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            return fence->unflatten(buffer, size, fds, count);
254221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        case State::SIGNAL_TIME:
255221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            if (size < sizeof(signalTime)) {
256221de2a33d456738f7f64db0b015a960211d4834Brian Anderson                return NO_MEMORY;
257221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            }
258221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            FlattenableUtils::read(buffer, size, signalTime);
259221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            return NO_ERROR;
260221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    }
261221de2a33d456738f7f64db0b015a960211d4834Brian Anderson
262221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    return NO_ERROR;
263221de2a33d456738f7f64db0b015a960211d4834Brian Anderson}
264221de2a33d456738f7f64db0b015a960211d4834Brian Anderson
265221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// ============================================================================
266221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// FenceTimeline
267221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// ============================================================================
268221de2a33d456738f7f64db0b015a960211d4834Brian Andersonvoid FenceTimeline::push(const std::shared_ptr<FenceTime>& fence) {
269221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    std::lock_guard<std::mutex> lock(mMutex);
270221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    while (mQueue.size() >= MAX_ENTRIES) {
271221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        // This is a sanity check to make sure the queue doesn't grow unbounded.
272221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        // MAX_ENTRIES should be big enough not to trigger this path.
273221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        // In case this path is taken though, users of FenceTime must make sure
274221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        // not to rely solely on FenceTimeline to get the final timestamp and
275221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        // should eventually call Fence::getSignalTime on their own.
276221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        std::shared_ptr<FenceTime> front = mQueue.front().lock();
277221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        if (front) {
278221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            // Make a last ditch effort to get the signalTime here since
279221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            // we are removing it from the timeline.
280221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            front->getSignalTime();
281221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        }
282221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        mQueue.pop();
283221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    }
284221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    mQueue.push(fence);
285221de2a33d456738f7f64db0b015a960211d4834Brian Anderson}
286221de2a33d456738f7f64db0b015a960211d4834Brian Anderson
287221de2a33d456738f7f64db0b015a960211d4834Brian Andersonvoid FenceTimeline::updateSignalTimes() {
288221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    while (!mQueue.empty()) {
289221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        std::lock_guard<std::mutex> lock(mMutex);
290221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        std::shared_ptr<FenceTime> fence = mQueue.front().lock();
291221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        if (!fence) {
292221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            // The shared_ptr no longer exists and no one cares about the
293221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            // timestamp anymore.
294221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            mQueue.pop();
295221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            continue;
296221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        } else if (fence->getSignalTime() != Fence::SIGNAL_TIME_PENDING) {
297221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            // The fence has signaled and we've removed the sp<Fence> ref.
298221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            mQueue.pop();
299221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            continue;
300221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        } else {
301221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            // The fence didn't signal yet. Break since the later ones
302221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            // shouldn't have signaled either.
303221de2a33d456738f7f64db0b015a960211d4834Brian Anderson            break;
304221de2a33d456738f7f64db0b015a960211d4834Brian Anderson        }
305221de2a33d456738f7f64db0b015a960211d4834Brian Anderson    }
306221de2a33d456738f7f64db0b015a960211d4834Brian Anderson}
307221de2a33d456738f7f64db0b015a960211d4834Brian Anderson
3083da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// ============================================================================
3093da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// FenceToFenceTimeMap
3103da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// ============================================================================
3113da8d2748580b2575e368e203ce2c7f8d34dea05Brian Andersonstd::shared_ptr<FenceTime> FenceToFenceTimeMap::createFenceTimeForTest(
3123da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson        const sp<Fence>& fence) {
3133da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    std::lock_guard<std::mutex> lock(mMutex);
3143da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    // Always garbage collecting isn't efficient, but this is only for testing.
3153da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    garbageCollectLocked();
3163da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    std::shared_ptr<FenceTime> fenceTime(new FenceTime(fence, true));
3173da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    mMap[fence.get()].push_back(fenceTime);
3183da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    return fenceTime;
3193da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson}
3203da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson
3213da8d2748580b2575e368e203ce2c7f8d34dea05Brian Andersonvoid FenceToFenceTimeMap::signalAllForTest(
3223da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson        const sp<Fence>& fence, nsecs_t signalTime) {
3233da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    bool signaled = false;
3243da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson
3253da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    std::lock_guard<std::mutex> lock(mMutex);
3263da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    auto it = mMap.find(fence.get());
3273da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    if (it != mMap.end()) {
3283da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson        for (auto& weakFenceTime : it->second) {
3293da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson            std::shared_ptr<FenceTime> fenceTime = weakFenceTime.lock();
3303da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson            if (!fenceTime) {
3313da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson                continue;
3323da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson            }
3333da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson            ALOGE_IF(!fenceTime->isValid(),
3343da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson                    "FenceToFenceTimeMap::signalAllForTest: "
3353da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson                     "Signaling invalid fence.");
3363da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson            fenceTime->signalForTest(signalTime);
3373da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson            signaled = true;
3383da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson        }
3393da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    }
3403da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson
3413da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    if (!signaled) {
3423da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson        ALOGE("FenceToFenceTimeMap::signalAllForTest: Nothing to signal.");
3433da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    }
3443da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson}
3453da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson
3463da8d2748580b2575e368e203ce2c7f8d34dea05Brian Andersonvoid FenceToFenceTimeMap::garbageCollectLocked() {
3473da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    for (auto& it : mMap) {
3483da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson        // Erase all expired weak pointers from the vector.
3493da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson        auto& vect = it.second;
3503da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson        vect.erase(
3513da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson                std::remove_if(vect.begin(), vect.end(),
3523da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson                        [](const std::weak_ptr<FenceTime>& ft) {
3533da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson                            return ft.expired();
3543da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson                        }),
3553da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson                vect.end());
3563da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson
3573da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson        // Also erase the map entry if the vector is now empty.
3583da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson        if (vect.empty()) {
3593da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson            mMap.erase(it.first);
3603da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson        }
3613da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson    }
3623da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson}
3633da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson
364221de2a33d456738f7f64db0b015a960211d4834Brian Anderson} // namespace android
365