1221de2a33d456738f7f64db0b015a960211d4834Brian Anderson/* 2221de2a33d456738f7f64db0b015a960211d4834Brian Anderson * Copyright (C) 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#ifndef ANDROID_FENCE_TIME_H 18221de2a33d456738f7f64db0b015a960211d4834Brian Anderson#define ANDROID_FENCE_TIME_H 19221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 20221de2a33d456738f7f64db0b015a960211d4834Brian Anderson#include <ui/Fence.h> 21221de2a33d456738f7f64db0b015a960211d4834Brian Anderson#include <utils/Flattenable.h> 22221de2a33d456738f7f64db0b015a960211d4834Brian Anderson#include <utils/Timers.h> 23221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 24221de2a33d456738f7f64db0b015a960211d4834Brian Anderson#include <atomic> 25221de2a33d456738f7f64db0b015a960211d4834Brian Anderson#include <mutex> 26221de2a33d456738f7f64db0b015a960211d4834Brian Anderson#include <queue> 273da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson#include <unordered_map> 28221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 29221de2a33d456738f7f64db0b015a960211d4834Brian Andersonnamespace android { 30221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 313da8d2748580b2575e368e203ce2c7f8d34dea05Brian Andersonclass FenceToFenceTimeMap; 323da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson 33221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// A wrapper around fence that only implements isValid and getSignalTime. 34221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// It automatically closes the fence in a thread-safe manner once the signal 35221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// time is known. 36221de2a33d456738f7f64db0b015a960211d4834Brian Andersonclass FenceTime { 373da8d2748580b2575e368e203ce2c7f8d34dea05Brian Andersonfriend class FenceToFenceTimeMap; 38221de2a33d456738f7f64db0b015a960211d4834Brian Andersonpublic: 39221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // An atomic snapshot of the FenceTime that is flattenable. 40221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // 41221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // This class is needed because the FenceTime class may not stay 42221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // consistent for all steps of the flattening process. 43221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // 44221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Not thread safe. 45221de2a33d456738f7f64db0b015a960211d4834Brian Anderson struct Snapshot : public Flattenable<Snapshot> { 46221de2a33d456738f7f64db0b015a960211d4834Brian Anderson enum class State { 47221de2a33d456738f7f64db0b015a960211d4834Brian Anderson EMPTY, 48221de2a33d456738f7f64db0b015a960211d4834Brian Anderson FENCE, 49221de2a33d456738f7f64db0b015a960211d4834Brian Anderson SIGNAL_TIME, 50221de2a33d456738f7f64db0b015a960211d4834Brian Anderson }; 51221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 52221de2a33d456738f7f64db0b015a960211d4834Brian Anderson Snapshot() = default; // Creates an empty snapshot. 53221de2a33d456738f7f64db0b015a960211d4834Brian Anderson explicit Snapshot(const sp<Fence>& fence); 54221de2a33d456738f7f64db0b015a960211d4834Brian Anderson explicit Snapshot(nsecs_t signalTime); 55221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 56221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Movable. 57221de2a33d456738f7f64db0b015a960211d4834Brian Anderson Snapshot(Snapshot&& src) = default; 58221de2a33d456738f7f64db0b015a960211d4834Brian Anderson Snapshot& operator=(Snapshot&& src) = default; 59221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Not copyable. 60221de2a33d456738f7f64db0b015a960211d4834Brian Anderson Snapshot(const Snapshot& src) = delete; 61221de2a33d456738f7f64db0b015a960211d4834Brian Anderson Snapshot& operator=(const Snapshot&& src) = delete; 62221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 63221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Flattenable implementation. 64221de2a33d456738f7f64db0b015a960211d4834Brian Anderson size_t getFlattenedSize() const; 65221de2a33d456738f7f64db0b015a960211d4834Brian Anderson size_t getFdCount() const; 66221de2a33d456738f7f64db0b015a960211d4834Brian Anderson status_t flatten(void*& buffer, size_t& size, int*& fds, 67221de2a33d456738f7f64db0b015a960211d4834Brian Anderson size_t& count) const; 68221de2a33d456738f7f64db0b015a960211d4834Brian Anderson status_t unflatten(void const*& buffer, size_t& size, int const*& fds, 69221de2a33d456738f7f64db0b015a960211d4834Brian Anderson size_t& count); 70221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 71221de2a33d456738f7f64db0b015a960211d4834Brian Anderson State state{State::EMPTY}; 72221de2a33d456738f7f64db0b015a960211d4834Brian Anderson sp<Fence> fence{Fence::NO_FENCE}; 73221de2a33d456738f7f64db0b015a960211d4834Brian Anderson nsecs_t signalTime{Fence::SIGNAL_TIME_INVALID}; 74221de2a33d456738f7f64db0b015a960211d4834Brian Anderson }; 75221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 76221de2a33d456738f7f64db0b015a960211d4834Brian Anderson static const std::shared_ptr<FenceTime> NO_FENCE; 77221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 78221de2a33d456738f7f64db0b015a960211d4834Brian Anderson explicit FenceTime(const sp<Fence>& fence); 79221de2a33d456738f7f64db0b015a960211d4834Brian Anderson explicit FenceTime(sp<Fence>&& fence); 80221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 81221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Passing in Fence::SIGNAL_TIME_PENDING is not allowed. 82221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Doing so will convert the signalTime to Fence::SIGNAL_TIME_INVALID. 83221de2a33d456738f7f64db0b015a960211d4834Brian Anderson explicit FenceTime(nsecs_t signalTime); 84221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 85221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Do not allow default construction. Share NO_FENCE or explicitly construct 86221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // with Fence::SIGNAL_TIME_INVALID instead. 87221de2a33d456738f7f64db0b015a960211d4834Brian Anderson FenceTime() = delete; 88221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 89221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Do not allow copy, assign, or move. Use a shared_ptr to share the 90221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // signalTime result. Or use getSnapshot() if a thread-safe copy is really 91221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // needed. 92221de2a33d456738f7f64db0b015a960211d4834Brian Anderson FenceTime(const FenceTime&) = delete; 93221de2a33d456738f7f64db0b015a960211d4834Brian Anderson FenceTime(FenceTime&&) = delete; 94221de2a33d456738f7f64db0b015a960211d4834Brian Anderson FenceTime& operator=(const FenceTime&) = delete; 95221de2a33d456738f7f64db0b015a960211d4834Brian Anderson FenceTime& operator=(FenceTime&&) = delete; 96221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 97221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // This method should only be called when replacing the fence with 98221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // a signalTime. Since this is an indirect way of setting the signal time 99221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // of a fence, the snapshot should come from a trusted source. 100221de2a33d456738f7f64db0b015a960211d4834Brian Anderson void applyTrustedSnapshot(const Snapshot& src); 101221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 102221de2a33d456738f7f64db0b015a960211d4834Brian Anderson bool isValid() const; 103221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 104221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Attempts to get the timestamp from the Fence if the timestamp isn't 105221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // already cached. Otherwise, it returns the cached value. 106221de2a33d456738f7f64db0b015a960211d4834Brian Anderson nsecs_t getSignalTime(); 107221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 108221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Gets the cached timestamp without attempting to query the Fence. 109221de2a33d456738f7f64db0b015a960211d4834Brian Anderson nsecs_t getCachedSignalTime() const; 110221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 111221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Returns a snapshot of the FenceTime in its current state. 112221de2a33d456738f7f64db0b015a960211d4834Brian Anderson Snapshot getSnapshot() const; 113221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 1143da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson void signalForTest(nsecs_t signalTime); 1153da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson 116221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // Override new and delete since this needs 8-byte alignment, which 117221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // is not guaranteed on x86. 118221de2a33d456738f7f64db0b015a960211d4834Brian Anderson static void* operator new(size_t nbytes) noexcept; 119221de2a33d456738f7f64db0b015a960211d4834Brian Anderson static void operator delete(void *p); 120221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 121221de2a33d456738f7f64db0b015a960211d4834Brian Andersonprivate: 1223da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson // For tests only. If forceValidForTest is true, then getSignalTime will 1233da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson // never return SIGNAL_TIME_INVALID and isValid will always return true. 1243da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson FenceTime(const sp<Fence>& fence, bool forceValidForTest); 1253da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson 126221de2a33d456738f7f64db0b015a960211d4834Brian Anderson enum class State { 127221de2a33d456738f7f64db0b015a960211d4834Brian Anderson VALID, 128221de2a33d456738f7f64db0b015a960211d4834Brian Anderson INVALID, 1293da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson FORCED_VALID_FOR_TEST, 130221de2a33d456738f7f64db0b015a960211d4834Brian Anderson }; 131221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 132221de2a33d456738f7f64db0b015a960211d4834Brian Anderson const State mState{State::INVALID}; 133221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 134221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // mMutex guards mFence and mSignalTime. 135221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // mSignalTime is also atomic since it is sometimes read outside the lock 136221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // for quick checks. 137221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mutable std::mutex mMutex; 138221de2a33d456738f7f64db0b015a960211d4834Brian Anderson sp<Fence> mFence{Fence::NO_FENCE}; 139221de2a33d456738f7f64db0b015a960211d4834Brian Anderson std::atomic<nsecs_t> mSignalTime{Fence::SIGNAL_TIME_INVALID}; 140221de2a33d456738f7f64db0b015a960211d4834Brian Anderson}; 141221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 142221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// A queue of FenceTimes that are expected to signal in FIFO order. 143221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// Only maintains a queue of weak pointers so it doesn't keep references 144221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// to Fences on its own. 145221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// 146221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// Can be used to get the signal time of a fence and close its file descriptor 147221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// without making a syscall for every fence later in the timeline. 148221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// Additionally, since the FenceTime caches the timestamp internally, 149221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// other timelines that reference the same FenceTime can avoid the syscall. 150221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// 151221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// FenceTimeline only keeps track of a limited number of entries to avoid 152221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// growing unbounded. Users of FenceTime must make sure they can work even 153221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// if FenceTimeline did nothing. i.e. they should eventually call 154221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// Fence::getSignalTime(), not only Fence::getCachedSignalTime(). 155221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// 156221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// push() and updateSignalTimes() are safe to call simultaneously from 157221de2a33d456738f7f64db0b015a960211d4834Brian Anderson// different threads. 158221de2a33d456738f7f64db0b015a960211d4834Brian Andersonclass FenceTimeline { 159221de2a33d456738f7f64db0b015a960211d4834Brian Andersonpublic: 160221de2a33d456738f7f64db0b015a960211d4834Brian Anderson static constexpr size_t MAX_ENTRIES = 64; 161221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 162221de2a33d456738f7f64db0b015a960211d4834Brian Anderson void push(const std::shared_ptr<FenceTime>& fence); 163221de2a33d456738f7f64db0b015a960211d4834Brian Anderson void updateSignalTimes(); 164221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 165221de2a33d456738f7f64db0b015a960211d4834Brian Andersonprivate: 166221de2a33d456738f7f64db0b015a960211d4834Brian Anderson mutable std::mutex mMutex; 167221de2a33d456738f7f64db0b015a960211d4834Brian Anderson std::queue<std::weak_ptr<FenceTime>> mQueue; 168221de2a33d456738f7f64db0b015a960211d4834Brian Anderson}; 169221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 1703da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// Used by test code to create or get FenceTimes for a given Fence. 1713da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// 1723da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// By design, Fences cannot be signaled from user space. However, this class 1733da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// allows test code to set the apparent signalTime of a Fence and 1743da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// have it be visible to all FenceTimes. Release code should not use 1753da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// FenceToFenceTimeMap. 1763da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// 1773da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// FenceToFenceTimeMap keeps a weak reference to the FenceTime and automatically 1783da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// garbage collects entries every time a new FenceTime is created to avoid 1793da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// leaks. This prevents us from having to make the Fence destructor 1803da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// automatically notify that the underlying fence has been destroyed, which 1813da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// would affect release code paths. Garbage collecting so often is inefficient, 1823da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// but acceptable for testing. 1833da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// 1843da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// Since FenceTimes maintain a strong reference to underlying Fences, there 1853da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// should not be any aliasing issues where a new Fence happens to have the same 1863da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// address as a previous Fence; the previous entry will be garbage collected 1873da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson// before the new one is added. 1883da8d2748580b2575e368e203ce2c7f8d34dea05Brian Andersonclass FenceToFenceTimeMap { 1893da8d2748580b2575e368e203ce2c7f8d34dea05Brian Andersonpublic: 1903da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson // Create a new FenceTime with that wraps the provided Fence. 1913da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson std::shared_ptr<FenceTime> createFenceTimeForTest(const sp<Fence>& fence); 1923da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson 1933da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson // Signals all FenceTimes created through this class that are wrappers 1943da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson // around |fence|. 1953da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson void signalAllForTest(const sp<Fence>& fence, nsecs_t signalTime); 1963da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson 1973da8d2748580b2575e368e203ce2c7f8d34dea05Brian Andersonprivate: 1983da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson // Cleans up the entries that no longer have a strong reference. 1993da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson void garbageCollectLocked(); 2003da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson 2013da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson mutable std::mutex mMutex; 2023da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson std::unordered_map<Fence*, std::vector<std::weak_ptr<FenceTime>>> mMap; 2033da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson}; 2043da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson 2053da8d2748580b2575e368e203ce2c7f8d34dea05Brian Anderson 206221de2a33d456738f7f64db0b015a960211d4834Brian Anderson}; // namespace android 207221de2a33d456738f7f64db0b015a960211d4834Brian Anderson 208221de2a33d456738f7f64db0b015a960211d4834Brian Anderson#endif // ANDROID_FENCE_TIME_H 209