1f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis/* 2f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * Copyright (C) 2012 The Android Open Source Project 3f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * 4f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * Licensed under the Apache License, Version 2.0 (the "License"); 5f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * you may not use this file except in compliance with the License. 6f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * You may obtain a copy of the License at 7f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * 8f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * http://www.apache.org/licenses/LICENSE-2.0 9f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * 10f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * Unless required by applicable law or agreed to in writing, software 11f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * distributed under the License is distributed on an "AS IS" BASIS, 12f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * See the License for the specific language governing permissions and 14f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * limitations under the License. 15f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis */ 16f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 17f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#ifndef ANDROID_FENCE_H 18f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#define ANDROID_FENCE_H 19f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 20f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <stdint.h> 21f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 22df1baddb6f4a13e7253ca547549b3157725c3121Chia-I Wu#include <android-base/unique_fd.h> 23f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <utils/Flattenable.h> 24175a7206c5aea70236b916d7707ab25025eb9cd6Brian Anderson#include <utils/RefBase.h> 2582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis#include <utils/Timers.h> 26f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 27f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennisnamespace android { 28f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 29175a7206c5aea70236b916d7707ab25025eb9cd6Brian Andersonclass String8; 30175a7206c5aea70236b916d7707ab25025eb9cd6Brian Anderson 31f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis// =========================================================================== 32f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis// Fence 33f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis// =========================================================================== 34f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 35f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennisclass Fence 36e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian : public LightRefBase<Fence>, public Flattenable<Fence> 37f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis{ 38f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennispublic: 39ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall static const sp<Fence> NO_FENCE; 40221de2a33d456738f7f64db0b015a960211d4834Brian Anderson static constexpr nsecs_t SIGNAL_TIME_PENDING = INT64_MAX; 41221de2a33d456738f7f64db0b015a960211d4834Brian Anderson static constexpr nsecs_t SIGNAL_TIME_INVALID = -1; 42221de2a33d456738f7f64db0b015a960211d4834Brian Anderson static inline bool isValidTimestamp(nsecs_t time) { 43221de2a33d456738f7f64db0b015a960211d4834Brian Anderson return time >= 0 && time < INT64_MAX; 44221de2a33d456738f7f64db0b015a960211d4834Brian Anderson } 45f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 4682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // TIMEOUT_NEVER may be passed to the wait method to indicate that it 4782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // should wait indefinitely for the fence to signal. 4882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis enum { TIMEOUT_NEVER = -1 }; 4982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 50f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // Construct a new Fence object with an invalid file descriptor. This 51f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // should be done when the Fence object will be set up by unflattening 52f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // serialized data. 53df1baddb6f4a13e7253ca547549b3157725c3121Chia-I Wu Fence() = default; 54f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 55f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // Construct a new Fence object to manage a given fence file descriptor. 56f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // When the new Fence object is destructed the file descriptor will be 57f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // closed. 5865d4787875544af168de512d3172777595ab59f7Chih-Hung Hsieh explicit Fence(int fenceFd); 59df1baddb6f4a13e7253ca547549b3157725c3121Chia-I Wu explicit Fence(base::unique_fd fenceFd); 60f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 61175a7206c5aea70236b916d7707ab25025eb9cd6Brian Anderson // Not copyable or movable. 62175a7206c5aea70236b916d7707ab25025eb9cd6Brian Anderson Fence(const Fence& rhs) = delete; 63175a7206c5aea70236b916d7707ab25025eb9cd6Brian Anderson Fence& operator=(const Fence& rhs) = delete; 64175a7206c5aea70236b916d7707ab25025eb9cd6Brian Anderson Fence(Fence&& rhs) = delete; 65175a7206c5aea70236b916d7707ab25025eb9cd6Brian Anderson Fence& operator=(Fence&& rhs) = delete; 66175a7206c5aea70236b916d7707ab25025eb9cd6Brian Anderson 67c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall // Check whether the Fence has an open fence file descriptor. Most Fence 68c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall // methods treat an invalid file descriptor just like a valid fence that 69c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall // is already signalled, so using this is usually not necessary. 70c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall bool isValid() const { return mFenceFd != -1; } 71c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall 72f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // wait waits for up to timeout milliseconds for the fence to signal. If 73f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // the fence signals then NO_ERROR is returned. If the timeout expires 74f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // before the fence signals then -ETIME is returned. A timeout of 75f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // TIMEOUT_NEVER may be used to indicate that the call should wait 76f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // indefinitely for the fence to signal. 77303b9a51239d36d237a7d40c67b5085cdb3c1059Dan Stoza status_t wait(int timeout); 78f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 79ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall // waitForever is a convenience function for waiting forever for a fence to 80ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall // signal (just like wait(TIMEOUT_NEVER)), but issuing an error to the 81ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall // system log and fence state to the kernel log if the wait lasts longer 82ea74d3b78d607cde17790a7bb83e6f68ffd34cfdMathias Agopian // than a warning timeout. 83ea74d3b78d607cde17790a7bb83e6f68ffd34cfdMathias Agopian // The logname argument should be a string identifying 84ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall // the caller and will be included in the log message. 85ea74d3b78d607cde17790a7bb83e6f68ffd34cfdMathias Agopian status_t waitForever(const char* logname); 86ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall 87f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // merge combines two Fence objects, creating a new Fence object that 88f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // becomes signaled when both f1 and f2 are signaled (even if f1 or f2 is 89f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // destroyed before it becomes signaled). The name argument specifies the 90f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // human-readable name to associated with the new Fence object. 91fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack static sp<Fence> merge(const char* name, const sp<Fence>& f1, 92fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack const sp<Fence>& f2); 93fd4c8c38051f9dad028e4e43e0eb39ba412b2c0aMatthew Bouyack 94f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis static sp<Fence> merge(const String8& name, const sp<Fence>& f1, 95f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis const sp<Fence>& f2); 96f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 97f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall // Return a duplicate of the fence file descriptor. The caller is 98f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall // responsible for closing the returned file descriptor. On error, -1 will 99f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall // be returned and errno will indicate the problem. 100f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall int dup() const; 101f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall 10282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // getSignalTime returns the system monotonic clock time at which the 10382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // fence transitioned to the signaled state. If the fence is not signaled 104221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // then SIGNAL_TIME_PENDING is returned. If the fence is invalid or if an 105221de2a33d456738f7f64db0b015a960211d4834Brian Anderson // error occurs then SIGNAL_TIME_INVALID is returned. 10682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis nsecs_t getSignalTime() const; 10782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 108a34320a81c9787958f1b02e93e828472e54864b5Dan Stoza enum class Status { 109a34320a81c9787958f1b02e93e828472e54864b5Dan Stoza Invalid, // Fence is invalid 110a34320a81c9787958f1b02e93e828472e54864b5Dan Stoza Unsignaled, // Fence is valid but has not yet signaled 111a34320a81c9787958f1b02e93e828472e54864b5Dan Stoza Signaled, // Fence is valid and has signaled 112a34320a81c9787958f1b02e93e828472e54864b5Dan Stoza }; 113a34320a81c9787958f1b02e93e828472e54864b5Dan Stoza 114a34320a81c9787958f1b02e93e828472e54864b5Dan Stoza // getStatus() returns whether the fence has signaled yet. Prefer this to 1155736f7dc1535452799ef2ea2026b7d1465567a31Dan Stoza // getSignalTime() or wait() if all you care about is whether the fence has 116a34320a81c9787958f1b02e93e828472e54864b5Dan Stoza // signaled. 117a34320a81c9787958f1b02e93e828472e54864b5Dan Stoza inline Status getStatus() { 1185736f7dc1535452799ef2ea2026b7d1465567a31Dan Stoza // The sync_wait call underlying wait() has been measured to be 1195736f7dc1535452799ef2ea2026b7d1465567a31Dan Stoza // significantly faster than the sync_fence_info call underlying 1205736f7dc1535452799ef2ea2026b7d1465567a31Dan Stoza // getSignalTime(), which might otherwise appear to be the more obvious 1215736f7dc1535452799ef2ea2026b7d1465567a31Dan Stoza // way to check whether a fence has signaled. 1220eeb676e662bd9747ff2fbdb854d3dc3448dfbd7Dan Stoza switch (wait(0)) { 1230eeb676e662bd9747ff2fbdb854d3dc3448dfbd7Dan Stoza case NO_ERROR: 124a34320a81c9787958f1b02e93e828472e54864b5Dan Stoza return Status::Signaled; 1250eeb676e662bd9747ff2fbdb854d3dc3448dfbd7Dan Stoza case -ETIME: 126a34320a81c9787958f1b02e93e828472e54864b5Dan Stoza return Status::Unsignaled; 1270eeb676e662bd9747ff2fbdb854d3dc3448dfbd7Dan Stoza default: 128a34320a81c9787958f1b02e93e828472e54864b5Dan Stoza return Status::Invalid; 1290eeb676e662bd9747ff2fbdb854d3dc3448dfbd7Dan Stoza } 1305736f7dc1535452799ef2ea2026b7d1465567a31Dan Stoza } 1315736f7dc1535452799ef2ea2026b7d1465567a31Dan Stoza 132f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // Flattenable interface 133f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis size_t getFlattenedSize() const; 134f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis size_t getFdCount() const; 135e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const; 136e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count); 137f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 138f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennisprivate: 139f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // Only allow instantiation using ref counting. 140f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis friend class LightRefBase<Fence>; 141df1baddb6f4a13e7253ca547549b3157725c3121Chia-I Wu ~Fence() = default; 142f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 143df1baddb6f4a13e7253ca547549b3157725c3121Chia-I Wu base::unique_fd mFenceFd; 144f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}; 145f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 146f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}; // namespace android 147f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 148f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#endif // ANDROID_FENCE_H 149