Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d09a9be authored by Glenn Kasten's avatar Glenn Kasten
Browse files

Use mFutex as an event flag rather than semaphore

An event flag can be more fault-tolerant in case of loss of synchronization,
as it cannot overflow.  It also allows more bits to be used in the future.
See http://en.wikipedia.org/wiki/Event_flag

Change-Id: I01ca25d951eb263124da54bb4738f0d94ec4a48b
parent a2cf13c7
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -94,8 +94,9 @@ struct audio_track_cblk_t
                                            // parameter
                                            // renamed to "_" to detect incorrect use

    volatile    int32_t     mFutex;     // semaphore: down (P) by client,
    volatile    int32_t     mFutex;     // event flag: down (P) by client,
                                        // up (V) by server or binderDied() or interrupt()
#define CBLK_FUTEX_WAKE 1               // if event flag bit is set, then a deferred wake is pending

private:

+5 −6
Original line number Diff line number Diff line
@@ -207,15 +207,15 @@ status_t ClientProxy::obtainBuffer(Buffer* buffer, const struct timespec *reques
            ts = NULL;
            break;
        }
        int32_t old = android_atomic_dec(&cblk->mFutex);
        if (old <= 0) {
        int32_t old = android_atomic_and(~CBLK_FUTEX_WAKE, &cblk->mFutex);
        if (!(old & CBLK_FUTEX_WAKE)) {
            int rc;
            if (measure && !beforeIsValid) {
                clock_gettime(CLOCK_MONOTONIC, &before);
                beforeIsValid = true;
            }
            int ret = __futex_syscall4(&cblk->mFutex,
                    mClientInServer ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, old - 1, ts);
                    mClientInServer ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, old & ~CBLK_FUTEX_WAKE, ts);
            // update total elapsed time spent waiting
            if (measure) {
                struct timespec after;
@@ -484,9 +484,8 @@ void ServerProxy::releaseBuffer(Buffer* buffer)
    }
    if (!mDeferWake && mAvailToClient + stepCount >= minimum) {
        ALOGV("mAvailToClient=%u stepCount=%u minimum=%u", mAvailToClient, stepCount, minimum);
        // could client be sleeping, or not need this increment and counter overflows?
        int32_t old = android_atomic_inc(&cblk->mFutex);
        if (old == -1) {
        int32_t old = android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
        if (!(old & CBLK_FUTEX_WAKE)) {
            (void) __futex_syscall3(&cblk->mFutex,
                    mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1);
        }