• 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 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);
109 private:
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