1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef HIDL_EVENTFLAG_H 18 #define HIDL_EVENTFLAG_H 19 20 #include <time.h> 21 #include <utils/Errors.h> 22 #include <atomic> 23 24 namespace android { 25 namespace hardware { 26 27 /** 28 * EventFlag is an abstraction that application code utilizing FMQ can use to wait on 29 * conditions like full, empty, data available etc. The same EventFlag object 30 * can be used with multiple FMQs. 31 */ 32 struct EventFlag { 33 /** 34 * Create an event flag object from the address of the flag word. 35 * 36 * @param efWordPtr Pointer to the event flag word. 37 * @param status Returns a status_t error code. Likely error codes are 38 * NO_ERROR if the method is successful or BAD_VALUE if efWordPtr is a null 39 * pointer. 40 * @param ef Pointer to the address of the EventFlag object that gets created. Will be set to 41 * nullptr if unsuccesful. 42 * 43 * @return Returns a status_t error code. Likely error codes are 44 * NO_ERROR if the method is successful or BAD_VALUE if efAddr is a null 45 * pointer. 46 * 47 */ 48 static status_t createEventFlag(std::atomic<uint32_t>* efWordPtr, 49 EventFlag** ef); 50 51 /** 52 * Delete an EventFlag object. 53 * 54 * @param ef A double pointer to the EventFlag object to be destroyed. 55 * 56 * @return Returns a status_t error code. Likely error codes are 57 * NO_ERROR if the method is successful or BAD_VALUE due to 58 * a bad input parameter. 59 */ 60 static status_t deleteEventFlag(EventFlag** ef); 61 62 /** 63 * Set the specified bits of the event flag word here and wake up a thread. 64 * @param bitmask The bits to be set on the event flag word. 65 * 66 * @return Returns a status_t error code. Likely error codes are 67 * NO_ERROR if the method is successful or BAD_VALUE if the bit mask 68 * does not have any bits set. 69 */ 70 status_t wake(uint32_t bitmask); 71 72 /** 73 * Wait for any of the bits in the bit mask to be set. 74 * 75 * @param bitmask The bits to wait on. 76 * @param timeoutNanoSeconds Specifies timeout duration in nanoseconds. It is converted to 77 * an absolute timeout for the wait according to the CLOCK_MONOTONIC clock. 78 * @param efState The event flag bits that caused the return from wake. 79 * @param retry If true, retry automatically for a spurious wake. If false, 80 * will return -EINTR or -EAGAIN for a spurious wake. 81 * 82 * @return Returns a status_t error code. Likely error codes are 83 * NO_ERROR if the method is successful, BAD_VALUE due to bad input 84 * parameters, TIMED_OUT if the wait timedout as per the timeout 85 * parameter, -EAGAIN or -EINTR to indicate that the caller needs to invoke 86 * wait() again. -EAGAIN or -EINTR error codes will not be returned if 87 * 'retry' is true since the method will retry waiting in that case. 88 */ 89 status_t wait(uint32_t bitmask, 90 uint32_t* efState, 91 int64_t timeOutNanoSeconds = 0, 92 bool retry = false); 93 private: 94 bool mEfWordNeedsUnmapping = false; 95 std::atomic<uint32_t>* mEfWordPtr = nullptr; 96 97 /* 98 * Use this constructor if we already know where the event flag word 99 * lives. 100 */ 101 EventFlag(std::atomic<uint32_t>* efWordPtr, status_t* status); 102 103 /* 104 * Disallow constructor without argument and copying. 105 */ 106 EventFlag(); 107 EventFlag& operator=(const EventFlag& other) = delete; 108 EventFlag(const EventFlag& other) = delete; 109 110 /* 111 * Wait for any of the bits in the bit mask to be set. 112 */ 113 status_t waitHelper(uint32_t bitmask, uint32_t* efState, int64_t timeOutNanoSeconds); 114 115 /* 116 * Utility method to unmap the event flag word. 117 */ 118 static status_t unmapEventFlagWord(std::atomic<uint32_t>* efWordPtr, 119 bool* efWordNeedsUnmapping); 120 121 /* 122 * Utility method to convert timeout duration to an absolute CLOCK_MONOTONIC 123 * clock time which is required by futex syscalls. 124 */ 125 inline void addNanosecondsToCurrentTime(int64_t nanoseconds, struct timespec* timeAbs); 126 ~EventFlag(); 127 }; 128 } // namespace hardware 129 } // namespace android 130 #endif 131