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 24namespace android { 25namespace 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 */ 32struct EventFlag { 33 /** 34 * Create an event flag object with mapping information. 35 * 36 * @param fd File descriptor to be mmapped to create the event flag word. 37 * There is no transfer of ownership of the fd. The caller will still 38 * own the fd for the purpose of closing it. 39 * @param offset Offset parameter to mmap. 40 * @param ef Pointer to address of the EventFlag object that gets created. Will be set to 41 * nullptr if unsuccesful. 42 * 43 * @return status Returns a status_t error code. Likely error codes are 44 * NO_ERROR if the method is successful or BAD_VALUE due to invalid 45 * mapping arguments. 46 */ 47 static status_t createEventFlag(int fd, off_t offset, EventFlag** ef); 48 49 /** 50 * Create an event flag object from the address of the flag word. 51 * 52 * @param efWordPtr Pointer to the event flag word. 53 * @param status Returns a status_t error code. Likely error codes are 54 * NO_ERROR if the method is successful or BAD_VALUE if efWordPtr is a null 55 * pointer. 56 * @param ef Pointer to the address of the EventFlag object that gets created. Will be set to 57 * nullptr if unsuccesful. 58 * 59 * @return Returns a status_t error code. Likely error codes are 60 * NO_ERROR if the method is successful or BAD_VALUE if efAddr is a null 61 * pointer. 62 * 63 */ 64 static status_t createEventFlag(std::atomic<uint32_t>* efWordPtr, 65 EventFlag** ef); 66 67 /** 68 * Delete an EventFlag object. 69 * 70 * @param ef A double pointer to the EventFlag object to be destroyed. 71 * 72 * @return Returns a status_t error code. Likely error codes are 73 * NO_ERROR if the method is successful or BAD_VALUE due to 74 * a bad input parameter. 75 */ 76 static status_t deleteEventFlag(EventFlag** ef); 77 78 /** 79 * Set the specified bits of the event flag word here and wake up a thread. 80 * @param bitmask The bits to be set on the event flag word. 81 * 82 * @return Returns a status_t error code. Likely error codes are 83 * NO_ERROR if the method is successful or BAD_VALUE if the bit mask 84 * does not have any bits set. 85 */ 86 status_t wake(uint32_t bitmask); 87 88 /** 89 * Wait for any of the bits in the bit mask to be set. 90 * 91 * @param bitmask The bits to wait on. 92 * @param timeoutNanoSeconds Specifies timeout duration in nanoseconds. It is converted to 93 * an absolute timeout for the wait according to the CLOCK_MONOTONIC clock. 94 * @param efState The event flag bits that caused the return from wake. 95 * @param retry If true, retry automatically for a spurious wake. If false, 96 * will return -EINTR or -EAGAIN for a spurious wake. 97 * 98 * @return Returns a status_t error code. Likely error codes are 99 * NO_ERROR if the method is successful, BAD_VALUE due to bad input 100 * parameters, TIMED_OUT if the wait timedout as per the timeout 101 * parameter, -EAGAIN or -EINTR to indicate that the caller needs to invoke 102 * wait() again. -EAGAIN or -EINTR error codes will not be returned if 103 * 'retry' is true since the method will retry waiting in that case. 104 */ 105 status_t wait(uint32_t bitmask, 106 uint32_t* efState, 107 int64_t timeOutNanoSeconds = 0, 108 bool retry = false); 109private: 110 bool mEfWordNeedsUnmapping = false; 111 std::atomic<uint32_t>* mEfWordPtr = nullptr; 112 113 /* 114 * mmap memory for the event flag word. 115 */ 116 EventFlag(int fd, off_t offset, status_t* status); 117 118 /* 119 * Use this constructor if we already know where the event flag word 120 * lives. 121 */ 122 EventFlag(std::atomic<uint32_t>* efWordPtr, status_t* status); 123 124 /* 125 * Disallow constructor without argument and copying. 126 */ 127 EventFlag(); 128 EventFlag& operator=(const EventFlag& other) = delete; 129 EventFlag(const EventFlag& other) = delete; 130 131 /* 132 * Wait for any of the bits in the bit mask to be set. 133 */ 134 status_t waitHelper(uint32_t bitmask, uint32_t* efState, int64_t timeOutNanoSeconds); 135 136 /* 137 * Utility method to unmap the event flag word. 138 */ 139 static status_t unmapEventFlagWord(std::atomic<uint32_t>* efWordPtr, 140 bool* efWordNeedsUnmapping); 141 142 /* 143 * Utility method to convert timeout duration to an absolute CLOCK_MONOTONIC 144 * clock time which is required by futex syscalls. 145 */ 146 inline void addNanosecondsToCurrentTime(int64_t nanoseconds, struct timespec* timeAbs); 147 ~EventFlag(); 148}; 149} // namespace hardware 150} // namespace android 151#endif 152