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