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#define LOG_TAG "FMQ_EventFlags" 188b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 198b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju#include <fmq/EventFlag.h> 208b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju#include <linux/futex.h> 218b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju#include <sys/mman.h> 228b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju#include <sys/syscall.h> 2326531e0ec6fa5b80be2be9ea0017b8ee1638f377Steven Moreland#include <unistd.h> 248b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju#include <utils/Log.h> 25f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju#include <utils/SystemClock.h> 268b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju#include <new> 278b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 288b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsarajunamespace android { 298b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsarajunamespace hardware { 308b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 318b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsarajustatus_t EventFlag::createEventFlag(int fd, off_t offset, EventFlag** flag) { 328b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju if (flag == nullptr) { 338b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju return BAD_VALUE; 348b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } 358b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 368b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju status_t status = NO_MEMORY; 378b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju *flag = nullptr; 388b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 398b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju EventFlag* evFlag = new (std::nothrow) EventFlag(fd, offset, &status); 408b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju if (evFlag != nullptr) { 418b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju if (status == NO_ERROR) { 428b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju *flag = evFlag; 438b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } else { 448b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju delete evFlag; 458b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } 468b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } 478b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 488b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju return status; 498b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju} 508b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 518b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsarajustatus_t EventFlag::createEventFlag(std::atomic<uint32_t>* fwAddr, 528b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju EventFlag** flag) { 538b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju if (flag == nullptr) { 548b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju return BAD_VALUE; 558b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } 568b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 578b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju status_t status = NO_MEMORY; 588b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju *flag = nullptr; 598b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 608b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju EventFlag* evFlag = new (std::nothrow) EventFlag(fwAddr, &status); 618b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju if (evFlag != nullptr) { 628b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju if (status == NO_ERROR) { 638b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju *flag = evFlag; 648b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } else { 658b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju delete evFlag; 668b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } 678b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } 688b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 698b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju return status; 708b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju} 718b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 728b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju/* 738b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * mmap memory for the futex word 748b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 758b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya ValsarajuEventFlag::EventFlag(int fd, off_t offset, status_t* status) { 768b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju mEfWordPtr = static_cast<std::atomic<uint32_t>*>(mmap(NULL, 7710f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju sizeof(std::atomic<uint32_t>), 7810f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju PROT_READ | PROT_WRITE, 7910f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju MAP_SHARED, fd, offset)); 808b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju mEfWordNeedsUnmapping = true; 818b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju if (mEfWordPtr != MAP_FAILED) { 828b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju *status = NO_ERROR; 838b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } else { 848b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju *status = -errno; 858b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju ALOGE("Attempt to mmap event flag word failed: %s\n", strerror(errno)); 868b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } 878b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju} 888b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 898b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju/* 908b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * Use this constructor if we already know where the futex word for 918b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * the EventFlag group lives. 928b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 938b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya ValsarajuEventFlag::EventFlag(std::atomic<uint32_t>* fwAddr, status_t* status) { 948b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju *status = NO_ERROR; 958b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju if (fwAddr == nullptr) { 968b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju *status = BAD_VALUE; 978b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } else { 988b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju mEfWordPtr = fwAddr; 998b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } 1008b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju} 1018b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 1028b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju/* 1038b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * Set the specified bits of the futex word here and wake up any 1048b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * thread waiting on any of the bits. 1058b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 1068b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsarajustatus_t EventFlag::wake(uint32_t bitmask) { 1078b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju /* 1088b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * Return early if there are no set bits in bitmask. 1098b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 1108b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju if (bitmask == 0) { 1118b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju return NO_ERROR; 1128b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } 1138b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 1148b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju status_t status = NO_ERROR; 1158b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju uint32_t old = std::atomic_fetch_or(mEfWordPtr, bitmask); 1168b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju /* 117af605d4be8b9a0c190b44b85a582a4b9a5f99f3bHridya Valsaraju * No need to call FUTEX_WAKE_BITSET if there were deferred wakes 118af605d4be8b9a0c190b44b85a582a4b9a5f99f3bHridya Valsaraju * already available for all set bits from bitmask. 1198b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 1208b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju if ((~old & bitmask) != 0) { 1218b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju int ret = syscall(__NR_futex, mEfWordPtr, FUTEX_WAKE_BITSET, 12210f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju INT_MAX, NULL, NULL, bitmask); 1238b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju if (ret == -1) { 1248b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju status = -errno; 1258b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju ALOGE("Error in event flag wake attempt: %s\n", strerror(errno)); 1268b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } 1278b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } 1288b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju return status; 1298b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju} 1308b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 1318b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju/* 1328b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * Wait for any of the bits in the bitmask to be set 1338b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * and return which bits caused the return. 1348b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 135f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsarajustatus_t EventFlag::waitHelper(uint32_t bitmask, uint32_t* efState, int64_t timeoutNanoSeconds) { 1368b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju /* 1378b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * Return early if there are no set bits in bitmask. 1388b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 1398b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju if (bitmask == 0 || efState == nullptr) { 1408b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju return BAD_VALUE; 1418b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } 1428b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 1438b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju status_t status = NO_ERROR; 1448b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju uint32_t old = std::atomic_fetch_and(mEfWordPtr, ~bitmask); 1458b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju uint32_t setBits = old & bitmask; 1468b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju /* 1478b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * If there was a deferred wake available, no need to call FUTEX_WAIT_BITSET. 1488b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 1498b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju if (setBits != 0) { 1508b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju *efState = setBits; 1518b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju return status; 1528b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } 1538b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 1548b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju uint32_t efWord = old & ~bitmask; 1558b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju /* 1568b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * The syscall will put the thread to sleep only 1578b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * if the futex word still contains the expected 1588b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju * value i.e. efWord. If the futex word contents have 1593c2dcb1856d0725f402751e1334044ef8eb1df87Andreas Huber * changed, it fails with the error EAGAIN; If a timeout 1603c2dcb1856d0725f402751e1334044ef8eb1df87Andreas Huber * is specified and exceeded the syscall fails with ETIMEDOUT. 1618b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju */ 16210f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju int ret = 0; 16310f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju if (timeoutNanoSeconds) { 16410f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju struct timespec waitTimeAbsolute; 16510f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju addNanosecondsToCurrentTime(timeoutNanoSeconds, &waitTimeAbsolute); 16610f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju 16710f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju ret = syscall(__NR_futex, mEfWordPtr, FUTEX_WAIT_BITSET, 16810f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju efWord, &waitTimeAbsolute, NULL, bitmask); 16910f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju } else { 17010f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju ret = syscall(__NR_futex, mEfWordPtr, FUTEX_WAIT_BITSET, efWord, NULL, NULL, bitmask); 17110f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju } 1728b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju if (ret == -1) { 1738b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju status = -errno; 1743c2dcb1856d0725f402751e1334044ef8eb1df87Andreas Huber if (status != -EAGAIN && status != -ETIMEDOUT) { 1758b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju ALOGE("Event flag wait was unsuccessful: %s\n", strerror(errno)); 1768b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } 1778b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju *efState = 0; 1788b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } else { 17992b79dc7938ad2b5e36aebef80d78b061db275b3Hridya Valsaraju old = std::atomic_fetch_and(mEfWordPtr, ~bitmask); 18092b79dc7938ad2b5e36aebef80d78b061db275b3Hridya Valsaraju *efState = old & bitmask; 18177c8aba447488b2507f9531fa17e80b06c5bb0dfHridya Valsaraju 18277c8aba447488b2507f9531fa17e80b06c5bb0dfHridya Valsaraju if (*efState == 0) { 18377c8aba447488b2507f9531fa17e80b06c5bb0dfHridya Valsaraju /* Return -EINTR for a spurious wakeup */ 18477c8aba447488b2507f9531fa17e80b06c5bb0dfHridya Valsaraju status = -EINTR; 18577c8aba447488b2507f9531fa17e80b06c5bb0dfHridya Valsaraju } 1868b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } 1878b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju return status; 1888b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju} 1898b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 190f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju/* 191f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju * Wait for any of the bits in the bitmask to be set 192f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju * and return which bits caused the return. If 'retry' 193f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju * is true, wait again on a spurious wake-up. 194f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju */ 195f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsarajustatus_t EventFlag::wait(uint32_t bitmask, 196f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju uint32_t* efState, 197f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju int64_t timeoutNanoSeconds, 198f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju bool retry) { 199f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju if (!retry) { 200f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju return waitHelper(bitmask, efState, timeoutNanoSeconds); 201f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju } 202f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju 203f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju bool shouldTimeOut = timeoutNanoSeconds != 0; 204f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju int64_t prevTimeNs = shouldTimeOut ? android::elapsedRealtimeNano() : 0; 205f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju status_t status; 206f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju while (true) { 207f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju if (shouldTimeOut) { 208f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju int64_t currentTimeNs = android::elapsedRealtimeNano(); 209f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju /* 210f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju * Decrement TimeOutNanos to account for the time taken to complete the last 211f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju * iteration of the while loop. 212f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju */ 213f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju timeoutNanoSeconds -= currentTimeNs - prevTimeNs; 214f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju prevTimeNs = currentTimeNs; 215f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju if (timeoutNanoSeconds <= 0) { 216f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju status = -ETIMEDOUT; 217f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju *efState = 0; 218f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju break; 219f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju } 220f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju } 221f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju 222f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju status = waitHelper(bitmask, efState, timeoutNanoSeconds); 223f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju if ((status != -EAGAIN) && (status != -EINTR)) { 224f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju break; 225f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju } 226f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju } 227f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju return status; 228f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju} 229f542b5a8383ff3d03b1735f72a9524b5edf31071Hridya Valsaraju 2308b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsarajustatus_t EventFlag::unmapEventFlagWord(std::atomic<uint32_t>* efWordPtr, 2318b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju bool* efWordNeedsUnmapping) { 2328b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju status_t status = NO_ERROR; 2338b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju if (*efWordNeedsUnmapping) { 2348b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju int ret = munmap(efWordPtr, sizeof(std::atomic<uint32_t>)); 2358b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju if (ret != 0) { 2368b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju status = -errno; 2378b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju ALOGE("Error in deleting event flag group: %s\n", strerror(errno)); 2388b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } 2398b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju *efWordNeedsUnmapping = false; 2408b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } 2418b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju return status; 2428b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju} 2438b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 2448b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsarajustatus_t EventFlag::deleteEventFlag(EventFlag** evFlag) { 2458b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju if (evFlag == nullptr || *evFlag == nullptr) { 2468b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju return BAD_VALUE; 2478b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju } 2488b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 2498b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju status_t status = unmapEventFlagWord((*evFlag)->mEfWordPtr, 2508b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju &(*evFlag)->mEfWordNeedsUnmapping); 2518b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju delete *evFlag; 2528b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju *evFlag = nullptr; 2538b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 2548b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju return status; 2558b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju} 2568b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 25710f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsarajuvoid EventFlag::addNanosecondsToCurrentTime(int64_t nanoSeconds, struct timespec* waitTime) { 25810f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju static constexpr int64_t kNanosPerSecond = 1000000000; 25910f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju 26010f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju clock_gettime(CLOCK_MONOTONIC, waitTime); 26110f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju waitTime->tv_sec += nanoSeconds / kNanosPerSecond; 26210f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju waitTime->tv_nsec += nanoSeconds % kNanosPerSecond; 26310f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju 26410f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju if (waitTime->tv_nsec >= kNanosPerSecond) { 26510f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju waitTime->tv_sec++; 26610f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju waitTime->tv_nsec -= kNanosPerSecond; 26710f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju } 26810f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju} 26910f59dc950f859119431f0e0c8368a882a7fa586Hridya Valsaraju 2708b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya ValsarajuEventFlag::~EventFlag() { 2718b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju unmapEventFlagWord(mEfWordPtr, &mEfWordNeedsUnmapping); 2728b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju} 2738b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju 2748b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju} // namespace hardware 2758b0d5a5c20cfc786f783e44442787c5ea53f0001Hridya Valsaraju} // namespace android 276