blob: 3ec4932ac4fd9714f9731f2a1ef1c089772684df [file] [log] [blame]
Hridya Valsaraju8b0d5a52016-12-16 10:29:03 -08001/*
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/**
Hridya Valsaraju8b0d5a52016-12-16 10:29:03 -080034* 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*/
48static status_t createEventFlag(std::atomic<uint32_t>* efWordPtr,
49EventFlag** 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*/
60static 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*/
70status_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.
Hridya Valsaraju10f59dc2016-12-20 12:50:44 -080076* @param timeoutNanoSeconds Specifies timeout duration in nanoseconds. It is converted to
77* an absolute timeout for the wait according to the CLOCK_MONOTONIC clock.
Hridya Valsaraju8b0d5a52016-12-16 10:29:03 -080078* @param efState The event flag bits that caused the return from wake.
Hridya Valsarajuf1aa0582017-03-21 11:33:33 -070079* @param retry If true, retry automatically for a spurious wake. If false,
80* will return -EINTR or -EAGAIN for a spurious wake.
Hridya Valsaraju8b0d5a52016-12-16 10:29:03 -080081*
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
Hridya Valsaraju77c8aba2017-03-03 07:57:37 -080085* parameter, -EAGAIN or -EINTR to indicate that the caller needs to invoke
Hridya Valsarajuf1aa0582017-03-21 11:33:33 -070086* 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.
Hridya Valsaraju8b0d5a52016-12-16 10:29:03 -080088*/
Hridya Valsarajuf1aa0582017-03-21 11:33:33 -070089status_t wait(uint32_t bitmask,
90uint32_t* efState,
91int64_t timeOutNanoSeconds = 0,
92bool retry = false);
Hridya Valsaraju8b0d5a52016-12-16 10:29:03 -080093private:
94bool mEfWordNeedsUnmapping = false;
95std::atomic<uint32_t>* mEfWordPtr = nullptr;
96
97/*
Hridya Valsaraju8b0d5a52016-12-16 10:29:03 -080098* Use this constructor if we already know where the event flag word
99* lives.
100*/
101EventFlag(std::atomic<uint32_t>* efWordPtr, status_t* status);
102
103/*
104* Disallow constructor without argument and copying.
105*/
106EventFlag();
107EventFlag& operator=(const EventFlag& other) = delete;
108EventFlag(const EventFlag& other) = delete;
109
110/*
Hridya Valsarajuf1aa0582017-03-21 11:33:33 -0700111* Wait for any of the bits in the bit mask to be set.
112*/
113status_t waitHelper(uint32_t bitmask, uint32_t* efState, int64_t timeOutNanoSeconds);
114
115/*
Hridya Valsaraju8b0d5a52016-12-16 10:29:03 -0800116* Utility method to unmap the event flag word.
117*/
118static status_t unmapEventFlagWord(std::atomic<uint32_t>* efWordPtr,
119bool* efWordNeedsUnmapping);
Hridya Valsarajuf1aa0582017-03-21 11:33:33 -0700120
Hridya Valsaraju10f59dc2016-12-20 12:50:44 -0800121/*
Hridya Valsarajuf1aa0582017-03-21 11:33:33 -0700122* Utility method to convert timeout duration to an absolute CLOCK_MONOTONIC
123* clock time which is required by futex syscalls.
Hridya Valsaraju10f59dc2016-12-20 12:50:44 -0800124*/
125inline void addNanosecondsToCurrentTime(int64_t nanoseconds, struct timespec* timeAbs);
Hridya Valsaraju8b0d5a52016-12-16 10:29:03 -0800126~EventFlag();
127};
128} // namespace hardware
129} // namespace android
130#endif