1f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten/*
2f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten * Copyright (C) 2014 The Android Open Source Project
3f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten *
4f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
5f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten * you may not use this file except in compliance with the License.
6f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten * You may obtain a copy of the License at
7f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten *
8f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
9f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten *
10f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten * Unless required by applicable law or agreed to in writing, software
11f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
12f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten * See the License for the specific language governing permissions and
14f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten * limitations under the License.
15f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten */
16f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
17f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten#define LOG_TAG "FastCapture"
18f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten//#define LOG_NDEBUG 0
19f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
20f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten#define ATRACE_TAG ATRACE_TAG_AUDIO
21f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
22f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten#include "Configuration.h"
23f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten#include <linux/futex.h>
24f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten#include <sys/syscall.h>
25f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten#include <media/AudioBufferProvider.h>
26f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten#include <utils/Log.h>
27f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten#include <utils/Trace.h>
28f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten#include "FastCapture.h"
29f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
30f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kastennamespace android {
31f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
32e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten/*static*/ const FastCaptureState FastCapture::sInitial;
33f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
34f9715e43ea73361321663514c44129c939c5db2fGlenn KastenFastCapture::FastCapture() : FastThread("cycleC_ms", "loadC_us"),
35e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    mInputSource(NULL), mInputSourceGen(0), mPipeSink(NULL), mPipeSinkGen(0),
36e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    mReadBuffer(NULL), mReadBufferState(-1), mFormat(Format_Invalid), mSampleRate(0),
37e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    // mDummyDumpState
38e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    mTotalNativeFramesRead(0)
39f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten{
40e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    mPrevious = &sInitial;
41e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    mCurrent = &sInitial;
42f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
43e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    mDummyDumpState = &mDummyFastCaptureDumpState;
44f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten}
45f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
46f91df1b368a140abd37c80b204bd48d78778cc43Glenn KastenFastCapture::~FastCapture()
47f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten{
48f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten}
49f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
50f91df1b368a140abd37c80b204bd48d78778cc43Glenn KastenFastCaptureStateQueue* FastCapture::sq()
51f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten{
52f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    return &mSQ;
53f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten}
54f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
55f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kastenconst FastThreadState *FastCapture::poll()
56f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten{
57f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    return mSQ.poll();
58f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten}
59f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
60f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kastenvoid FastCapture::setLog(NBLog::Writer *logWriter __unused)
61f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten{
62f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten}
63f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
64f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kastenvoid FastCapture::onIdle()
65f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten{
66e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    mPreIdle = *(const FastCaptureState *)mCurrent;
67e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    mCurrent = &mPreIdle;
68f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten}
69f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
70f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kastenvoid FastCapture::onExit()
71f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten{
725115777127bb4d2d50833537e09054dcdffdfc76Glenn Kasten    free(mReadBuffer);
73f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten}
74f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
75f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kastenbool FastCapture::isSubClassCommand(FastThreadState::Command command)
76f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten{
77f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    switch ((FastCaptureState::Command) command) {
78f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    case FastCaptureState::READ:
79f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    case FastCaptureState::WRITE:
80f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    case FastCaptureState::READ_WRITE:
81f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        return true;
82f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    default:
83f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        return false;
84f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    }
85f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten}
86f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
87f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kastenvoid FastCapture::onStateChange()
88f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten{
894dd03b5b68dcd8eb5f5ffe2cfe93d26b8f08b848Glenn Kasten    const FastCaptureState * const current = (const FastCaptureState *) mCurrent;
904dd03b5b68dcd8eb5f5ffe2cfe93d26b8f08b848Glenn Kasten    const FastCaptureState * const previous = (const FastCaptureState *) mPrevious;
914dd03b5b68dcd8eb5f5ffe2cfe93d26b8f08b848Glenn Kasten    FastCaptureDumpState * const dumpState = (FastCaptureDumpState *) mDumpState;
92f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    const size_t frameCount = current->mFrameCount;
93f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
94f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    bool eitherChanged = false;
95f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
96f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    // check for change in input HAL configuration
97e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    NBAIO_Format previousFormat = mFormat;
98e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    if (current->mInputSourceGen != mInputSourceGen) {
99e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten        mInputSource = current->mInputSource;
100e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten        mInputSourceGen = current->mInputSourceGen;
101e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten        if (mInputSource == NULL) {
102e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mFormat = Format_Invalid;
103e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mSampleRate = 0;
104f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        } else {
105e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mFormat = mInputSource->format();
106e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mSampleRate = Format_sampleRate(mFormat);
10757c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#if !LOG_NDEBUG
108e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            unsigned channelCount = Format_channelCount(mFormat);
109d330ee46022f34da76d14d0c4d2910526ecc2321Andy Hung            ALOG_ASSERT(channelCount >= 1 && channelCount <= FCC_8);
11057c4e6f7464d458eb52d209c2a63524913d6406dGlenn Kasten#endif
111f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        }
112e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten        dumpState->mSampleRate = mSampleRate;
113f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        eitherChanged = true;
114f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    }
115f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
116f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    // check for change in pipe
117e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    if (current->mPipeSinkGen != mPipeSinkGen) {
118e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten        mPipeSink = current->mPipeSink;
119e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten        mPipeSinkGen = current->mPipeSinkGen;
120f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        eitherChanged = true;
121f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    }
122f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
123f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    // input source and pipe sink must be compatible
124e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    if (eitherChanged && mInputSource != NULL && mPipeSink != NULL) {
125e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten        ALOG_ASSERT(Format_isEqual(mFormat, mPipeSink->format()));
126f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    }
127f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
128e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    if ((!Format_isEqual(mFormat, previousFormat)) || (frameCount != previous->mFrameCount)) {
1295115777127bb4d2d50833537e09054dcdffdfc76Glenn Kasten        // FIXME to avoid priority inversion, don't free here
1305115777127bb4d2d50833537e09054dcdffdfc76Glenn Kasten        free(mReadBuffer);
131e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten        mReadBuffer = NULL;
132e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten        if (frameCount > 0 && mSampleRate > 0) {
133f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten            // FIXME new may block for unbounded time at internal mutex of the heap
134f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten            //       implementation; it would be better to have normal capture thread allocate for
135f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten            //       us to avoid blocking here and to prevent possible priority inversion
1360a01c2fb68e6f35905de8dfaf938d099cd48587dAndy Hung            size_t bufferSize = frameCount * Format_frameSize(mFormat);
1370a01c2fb68e6f35905de8dfaf938d099cd48587dAndy Hung            (void)posix_memalign(&mReadBuffer, 32, bufferSize);
1380a01c2fb68e6f35905de8dfaf938d099cd48587dAndy Hung            memset(mReadBuffer, 0, bufferSize); // if posix_memalign fails, will segv here.
139e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mPeriodNs = (frameCount * 1000000000LL) / mSampleRate;      // 1.00
140e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mUnderrunNs = (frameCount * 1750000000LL) / mSampleRate;    // 1.75
141e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mOverrunNs = (frameCount * 500000000LL) / mSampleRate;      // 0.50
142e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mForceNs = (frameCount * 950000000LL) / mSampleRate;        // 0.95
143e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mWarmupNsMin = (frameCount * 750000000LL) / mSampleRate;    // 0.75
144e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mWarmupNsMax = (frameCount * 1250000000LL) / mSampleRate;   // 1.25
145f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        } else {
146e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mPeriodNs = 0;
147e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mUnderrunNs = 0;
148e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mOverrunNs = 0;
149e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mForceNs = 0;
150e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mWarmupNsMin = 0;
151e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mWarmupNsMax = LONG_MAX;
152f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        }
153e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten        mReadBufferState = -1;
154f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        dumpState->mFrameCount = frameCount;
155f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    }
156f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
157f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten}
158f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
159f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kastenvoid FastCapture::onWork()
160f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten{
1614dd03b5b68dcd8eb5f5ffe2cfe93d26b8f08b848Glenn Kasten    const FastCaptureState * const current = (const FastCaptureState *) mCurrent;
1624dd03b5b68dcd8eb5f5ffe2cfe93d26b8f08b848Glenn Kasten    FastCaptureDumpState * const dumpState = (FastCaptureDumpState *) mDumpState;
1634dd03b5b68dcd8eb5f5ffe2cfe93d26b8f08b848Glenn Kasten    const FastCaptureState::Command command = mCommand;
164f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    const size_t frameCount = current->mFrameCount;
165f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
166f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    if ((command & FastCaptureState::READ) /*&& isWarm*/) {
167e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten        ALOG_ASSERT(mInputSource != NULL);
168e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten        ALOG_ASSERT(mReadBuffer != NULL);
169f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        dumpState->mReadSequence++;
170f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        ATRACE_BEGIN("read");
171d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kasten        ssize_t framesRead = mInputSource->read(mReadBuffer, frameCount);
172f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        ATRACE_END();
173f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        dumpState->mReadSequence++;
174f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        if (framesRead >= 0) {
175f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten            LOG_ALWAYS_FATAL_IF((size_t) framesRead > frameCount);
176e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mTotalNativeFramesRead += framesRead;
177e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            dumpState->mFramesRead = mTotalNativeFramesRead;
178e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mReadBufferState = framesRead;
179f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        } else {
180f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten            dumpState->mReadErrors++;
181e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mReadBufferState = 0;
182f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        }
183f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        // FIXME rename to attemptedIO
184e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten        mAttemptedWrite = true;
185f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    }
186f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
187f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    if (command & FastCaptureState::WRITE) {
188e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten        ALOG_ASSERT(mPipeSink != NULL);
189e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten        ALOG_ASSERT(mReadBuffer != NULL);
190e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten        if (mReadBufferState < 0) {
1915115777127bb4d2d50833537e09054dcdffdfc76Glenn Kasten            memset(mReadBuffer, 0, frameCount * Format_frameSize(mFormat));
192e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            mReadBufferState = frameCount;
193f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        }
194e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten        if (mReadBufferState > 0) {
195e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten            ssize_t framesWritten = mPipeSink->write(mReadBuffer, mReadBufferState);
196f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten            // FIXME This supports at most one fast capture client.
197f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten            //       To handle multiple clients this could be converted to an array,
198f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten            //       or with a lot more work the control block could be shared by all clients.
199f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten            audio_track_cblk_t* cblk = current->mCblk;
200f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten            if (cblk != NULL && framesWritten > 0) {
201f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten                int32_t rear = cblk->u.mStreaming.mRear;
202f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten                android_atomic_release_store(framesWritten + rear, &cblk->u.mStreaming.mRear);
203f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten                cblk->mServer += framesWritten;
204f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten                int32_t old = android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
205f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten                if (!(old & CBLK_FUTEX_WAKE)) {
206f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten                    // client is never in server process, so don't use FUTEX_WAKE_PRIVATE
207f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten                    (void) syscall(__NR_futex, &cblk->mFutex, FUTEX_WAKE, 1);
208f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten                }
209f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten            }
210f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten        }
211f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten    }
212f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten}
213f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten
214f91df1b368a140abd37c80b204bd48d78778cc43Glenn Kasten}   // namespace android
215