• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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