18b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju/* 28b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * Copyright (C) 2016 The Android Open Source Project 38b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * 48b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * Licensed under the Apache License, Version 2.0 (the "License"); 58b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * you may not use this file except in compliance with the License. 68b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * You may obtain a copy of the License at 78b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * 88b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * http://www.apache.org/licenses/LICENSE-2.0 98b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * 108b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * Unless required by applicable law or agreed to in writing, software 118b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * distributed under the License is distributed on an "AS IS" BASIS, 128b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * See the License for the specific language governing permissions and 148b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * limitations under the License. 158b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 168b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 178b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju#ifndef HIDL_EVENTFLAG_H 188b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju#define HIDL_EVENTFLAG_H 198b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 208b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju#include <time.h> 218b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju#include <utils/Errors.h> 228b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju#include <atomic> 238b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 248b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsarajunamespace android { 258b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsarajunamespace hardware { 268b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 278b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju/** 288b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * EventFlag is an abstraction that application code utilizing FMQ can use to wait on 298b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * conditions like full, empty, data available etc. The same EventFlag object 308b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * can be used with multiple FMQs. 318b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 328b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsarajustruct EventFlag { 338b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju /** 348b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * Create an event flag object with mapping information. 358b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * 368b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * @param fd File descriptor to be mmapped to create the event flag word. 378b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * There is no transfer of ownership of the fd. The caller will still 388b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * own the fd for the purpose of closing it. 398b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * @param offset Offset parameter to mmap. 408b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * @param ef Pointer to address of the EventFlag object that gets created. Will be set to 418b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * nullptr if unsuccesful. 428b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * 438b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * @return status Returns a status_t error code. Likely error codes are 448b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * NO_ERROR if the method is successful or BAD_VALUE due to invalid 458b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * mapping arguments. 468b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 478b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju static status_t createEventFlag(int fd, off_t offset, EventFlag** ef); 488b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 498b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju /** 508b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * Create an event flag object from the address of the flag word. 518b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * 528b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * @param efWordPtr Pointer to the event flag word. 538b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * @param status Returns a status_t error code. Likely error codes are 548b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * NO_ERROR if the method is successful or BAD_VALUE if efWordPtr is a null 558b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * pointer. 568b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * @param ef Pointer to the address of the EventFlag object that gets created. Will be set to 578b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * nullptr if unsuccesful. 588b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * 598b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * @return Returns a status_t error code. Likely error codes are 608b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * NO_ERROR if the method is successful or BAD_VALUE if efAddr is a null 618b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * pointer. 628b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * 638b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 648b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju static status_t createEventFlag(std::atomic<uint32_t>* efWordPtr, 658b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju EventFlag** ef); 668b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 678b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju /** 688b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * Delete an EventFlag object. 698b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * 708b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * @param ef A double pointer to the EventFlag object to be destroyed. 718b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * 728b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * @return Returns a status_t error code. Likely error codes are 738b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * NO_ERROR if the method is successful or BAD_VALUE due to 748b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * a bad input parameter. 758b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 768b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju static status_t deleteEventFlag(EventFlag** ef); 778b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 788b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju /** 798b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * Set the specified bits of the event flag word here and wake up a thread. 808b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * @param bitmask The bits to be set on the event flag word. 818b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * 828b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * @return Returns a status_t error code. Likely error codes are 838b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * NO_ERROR if the method is successful or BAD_VALUE if the bit mask 848b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * does not have any bits set. 858b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 868b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju status_t wake(uint32_t bitmask); 878b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 888b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju /** 898b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * Wait for any of the bits in the bit mask to be set. 908b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * 918b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * @param bitmask The bits to wait on. 9210f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju * @param timeoutNanoSeconds Specifies timeout duration in nanoseconds. It is converted to 9310f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju * an absolute timeout for the wait according to the CLOCK_MONOTONIC clock. 948b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * @param efState The event flag bits that caused the return from wake. 95f1aa0581d51ba0cf562bc67c7be28d55df6700bcHridya Valsaraju * @param retry If true, retry automatically for a spurious wake. If false, 96f1aa0581d51ba0cf562bc67c7be28d55df6700bcHridya Valsaraju * will return -EINTR or -EAGAIN for a spurious wake. 978b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * 988b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * @return Returns a status_t error code. Likely error codes are 998b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * NO_ERROR if the method is successful, BAD_VALUE due to bad input 1008b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * parameters, TIMED_OUT if the wait timedout as per the timeout 10177c8aba447488b2507f9531fa17e80b06c5bb0dfHridya Valsaraju * parameter, -EAGAIN or -EINTR to indicate that the caller needs to invoke 102f1aa0581d51ba0cf562bc67c7be28d55df6700bcHridya Valsaraju * wait() again. -EAGAIN or -EINTR error codes will not be returned if 103f1aa0581d51ba0cf562bc67c7be28d55df6700bcHridya Valsaraju * 'retry' is true since the method will retry waiting in that case. 1048b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 105f1aa0581d51ba0cf562bc67c7be28d55df6700bcHridya Valsaraju status_t wait(uint32_t bitmask, 106f1aa0581d51ba0cf562bc67c7be28d55df6700bcHridya Valsaraju uint32_t* efState, 107f1aa0581d51ba0cf562bc67c7be28d55df6700bcHridya Valsaraju int64_t timeOutNanoSeconds = 0, 108f1aa0581d51ba0cf562bc67c7be28d55df6700bcHridya Valsaraju bool retry = false); 1098b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsarajuprivate: 1108b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju bool mEfWordNeedsUnmapping = false; 1118b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju std::atomic<uint32_t>* mEfWordPtr = nullptr; 1128b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 1138b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju /* 1148b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * mmap memory for the event flag word. 1158b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 1168b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju EventFlag(int fd, off_t offset, status_t* status); 1178b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 1188b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju /* 1198b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * Use this constructor if we already know where the event flag word 1208b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * lives. 1218b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 1228b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju EventFlag(std::atomic<uint32_t>* efWordPtr, status_t* status); 1238b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 1248b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju /* 1258b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * Disallow constructor without argument and copying. 1268b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 1278b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju EventFlag(); 1288b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju EventFlag& operator=(const EventFlag& other) = delete; 1298b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju EventFlag(const EventFlag& other) = delete; 1308b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 1318b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju /* 132f1aa0581d51ba0cf562bc67c7be28d55df6700bcHridya Valsaraju * Wait for any of the bits in the bit mask to be set. 133f1aa0581d51ba0cf562bc67c7be28d55df6700bcHridya Valsaraju */ 134f1aa0581d51ba0cf562bc67c7be28d55df6700bcHridya Valsaraju status_t waitHelper(uint32_t bitmask, uint32_t* efState, int64_t timeOutNanoSeconds); 135f1aa0581d51ba0cf562bc67c7be28d55df6700bcHridya Valsaraju 136f1aa0581d51ba0cf562bc67c7be28d55df6700bcHridya Valsaraju /* 1378b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * Utility method to unmap the event flag word. 1388b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 1398b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju static status_t unmapEventFlagWord(std::atomic<uint32_t>* efWordPtr, 1408b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju bool* efWordNeedsUnmapping); 141f1aa0581d51ba0cf562bc67c7be28d55df6700bcHridya Valsaraju 14210f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju /* 143f1aa0581d51ba0cf562bc67c7be28d55df6700bcHridya Valsaraju * Utility method to convert timeout duration to an absolute CLOCK_MONOTONIC 144f1aa0581d51ba0cf562bc67c7be28d55df6700bcHridya Valsaraju * clock time which is required by futex syscalls. 14510f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju */ 14610f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju inline void addNanosecondsToCurrentTime(int64_t nanoseconds, struct timespec* timeAbs); 1478b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju ~EventFlag(); 1488b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju}; 1498b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju} // namespace hardware 1508b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju} // namespace android 1518b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju#endif 152