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