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