xref: /aosp_15_r20/system/libfmq/include/fmq/EventFlag.h (revision be431cd81a9a2349eaea34eb56fcf6d1608da596)
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