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