FastCapture.cpp revision c263ca0ad8b6bdf5b0693996bc5f2f5916e0cd49
14f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber/*
24f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * Copyright (C) 2014 The Android Open Source Project
34f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber *
44f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
54f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * you may not use this file except in compliance with the License.
64f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * You may obtain a copy of the License at
74f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber *
84f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
94f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber *
104f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * Unless required by applicable law or agreed to in writing, software
114f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
124f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * See the License for the specific language governing permissions and
144f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * limitations under the License.
154f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber */
164f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
174f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#define LOG_TAG "FastCapture"
184f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber//#define LOG_NDEBUG 0
194f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
204f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#define ATRACE_TAG ATRACE_TAG_AUDIO
214f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
224f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#include "Configuration.h"
234f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#include <linux/futex.h>
244f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#include <sys/syscall.h>
254f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#include <media/AudioBufferProvider.h>
264f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#include <utils/Log.h>
274f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#include <utils/Trace.h>
284f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber#include "FastCapture.h"
294f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
304f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Hubernamespace android {
314f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
324f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber/*static*/ const FastCaptureState FastCapture::initial;
334f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
344f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas HuberFastCapture::FastCapture() : FastThread(),
354f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    inputSource(NULL), inputSourceGen(0), pipeSink(NULL), pipeSinkGen(0),
364f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    readBuffer(NULL), readBufferState(-1), format(Format_Invalid), sampleRate(0),
374f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    // dummyDumpState
384f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    totalNativeFramesRead(0)
394f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber{
404f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    previous = &initial;
414f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    current = &initial;
424f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
434f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    mDummyDumpState = &dummyDumpState;
444f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber}
454f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
464f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas HuberFastCapture::~FastCapture()
474f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber{
484f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber}
494f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
504f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas HuberFastCaptureStateQueue* FastCapture::sq()
514f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber{
524f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    return &mSQ;
534f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber}
544f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
554f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberconst FastThreadState *FastCapture::poll()
564f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber{
574f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    return mSQ.poll();
584f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber}
594f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
604f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Hubervoid FastCapture::setLog(NBLog::Writer *logWriter __unused)
614f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber{
624f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber}
634f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
644f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Hubervoid FastCapture::onIdle()
654f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber{
664f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    preIdle = *(const FastCaptureState *)current;
674f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    current = &preIdle;
684f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber}
694f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
704f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Hubervoid FastCapture::onExit()
714f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber{
724f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    delete[] readBuffer;
734f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber}
744f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
754f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberbool FastCapture::isSubClassCommand(FastThreadState::Command command)
764f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber{
774f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    switch ((FastCaptureState::Command) command) {
784f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    case FastCaptureState::READ:
794f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    case FastCaptureState::WRITE:
804f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    case FastCaptureState::READ_WRITE:
814f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        return true;
824f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    default:
834f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        return false;
844f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    }
854f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber}
864f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
874f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Hubervoid FastCapture::onStateChange()
884f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber{
894f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    const FastCaptureState * const current = (const FastCaptureState *) this->current;
904f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    const FastCaptureState * const previous = (const FastCaptureState *) this->previous;
914f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    FastCaptureDumpState * const dumpState = (FastCaptureDumpState *) this->dumpState;
924f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    const size_t frameCount = current->mFrameCount;
934f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
944f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    bool eitherChanged = false;
954f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
964f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    // check for change in input HAL configuration
974f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    NBAIO_Format previousFormat = format;
984f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    if (current->mInputSourceGen != inputSourceGen) {
994f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        inputSource = current->mInputSource;
1004f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        inputSourceGen = current->mInputSourceGen;
1014f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        if (inputSource == NULL) {
1024f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            format = Format_Invalid;
1034f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            sampleRate = 0;
1044f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        } else {
1054f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            format = inputSource->format();
1064f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            sampleRate = Format_sampleRate(format);
1074f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            unsigned channelCount = Format_channelCount(format);
1084f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            ALOG_ASSERT(channelCount == 1 || channelCount == 2);
1094f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        }
1104f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        dumpState->mSampleRate = sampleRate;
1114f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        eitherChanged = true;
1124f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    }
1134f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
1144f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    // check for change in pipe
1154f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    if (current->mPipeSinkGen != pipeSinkGen) {
1164f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        pipeSink = current->mPipeSink;
1174f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        pipeSinkGen = current->mPipeSinkGen;
1184f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        eitherChanged = true;
1194f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    }
1204f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
1214f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    // input source and pipe sink must be compatible
1224f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    if (eitherChanged && inputSource != NULL && pipeSink != NULL) {
1234f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        ALOG_ASSERT(Format_isEqual(format, pipeSink->format()));
1244f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    }
1254f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
1264f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    if ((!Format_isEqual(format, previousFormat)) || (frameCount != previous->mFrameCount)) {
1274f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        // FIXME to avoid priority inversion, don't delete here
1284f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        delete[] readBuffer;
1294f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        readBuffer = NULL;
1304f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        if (frameCount > 0 && sampleRate > 0) {
1314f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            // FIXME new may block for unbounded time at internal mutex of the heap
1324f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            //       implementation; it would be better to have normal capture thread allocate for
1334f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            //       us to avoid blocking here and to prevent possible priority inversion
1344f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            unsigned channelCount = Format_channelCount(format);
1354f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            // FIXME frameSize
1364f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            readBuffer = new short[frameCount * channelCount];
1374f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            periodNs = (frameCount * 1000000000LL) / sampleRate;    // 1.00
1384f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            underrunNs = (frameCount * 1750000000LL) / sampleRate;  // 1.75
1394f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            overrunNs = (frameCount * 500000000LL) / sampleRate;    // 0.50
1404f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            forceNs = (frameCount * 950000000LL) / sampleRate;      // 0.95
1414f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            warmupNs = (frameCount * 500000000LL) / sampleRate;     // 0.50
1424f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        } else {
1434f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            periodNs = 0;
1444f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            underrunNs = 0;
1454f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            overrunNs = 0;
1464f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            forceNs = 0;
1474f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            warmupNs = 0;
1484f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        }
1494f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        readBufferState = -1;
1504f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        dumpState->mFrameCount = frameCount;
1514f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    }
1524f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
1534f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber}
1544f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
1554f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Hubervoid FastCapture::onWork()
1564f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber{
1574f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    const FastCaptureState * const current = (const FastCaptureState *) this->current;
1584f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    FastCaptureDumpState * const dumpState = (FastCaptureDumpState *) this->dumpState;
1594f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    const FastCaptureState::Command command = this->command;
1604f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    const size_t frameCount = current->mFrameCount;
1614f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
1624f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    if ((command & FastCaptureState::READ) /*&& isWarm*/) {
1634f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        ALOG_ASSERT(inputSource != NULL);
1644f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        ALOG_ASSERT(readBuffer != NULL);
1654f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        dumpState->mReadSequence++;
1664f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        ATRACE_BEGIN("read");
1674f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        ssize_t framesRead = inputSource->read(readBuffer, frameCount,
1684f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber                AudioBufferProvider::kInvalidPTS);
1694f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        ATRACE_END();
1704f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        dumpState->mReadSequence++;
1714f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        if (framesRead >= 0) {
1724f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            LOG_ALWAYS_FATAL_IF((size_t) framesRead > frameCount);
1734f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            totalNativeFramesRead += framesRead;
1744f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            dumpState->mFramesRead = totalNativeFramesRead;
1754f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            readBufferState = framesRead;
1764f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        } else {
1774f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            dumpState->mReadErrors++;
1784f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            readBufferState = 0;
1794f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        }
1804f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        // FIXME rename to attemptedIO
1814f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        attemptedWrite = true;
1824f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    }
1834f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
1844f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    if (command & FastCaptureState::WRITE) {
1854f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        ALOG_ASSERT(pipeSink != NULL);
1864f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        ALOG_ASSERT(readBuffer != NULL);
1874f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        if (readBufferState < 0) {
1884f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            unsigned channelCount = Format_channelCount(format);
1894f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            // FIXME frameSize
1904f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            memset(readBuffer, 0, frameCount * channelCount * sizeof(short));
1914f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            readBufferState = frameCount;
1924f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        }
1934f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        if (readBufferState > 0) {
1944f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            ssize_t framesWritten = pipeSink->write(readBuffer, readBufferState);
1954f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            // FIXME This supports at most one fast capture client.
1964f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            //       To handle multiple clients this could be converted to an array,
1974f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            //       or with a lot more work the control block could be shared by all clients.
1984f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            audio_track_cblk_t* cblk = current->mCblk;
1994f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            if (cblk != NULL && framesWritten > 0) {
2004f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber                int32_t rear = cblk->u.mStreaming.mRear;
2014f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber                android_atomic_release_store(framesWritten + rear, &cblk->u.mStreaming.mRear);
2024f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber                cblk->mServer += framesWritten;
2034f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber                int32_t old = android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
2044f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber                if (!(old & CBLK_FUTEX_WAKE)) {
2054f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber                    // client is never in server process, so don't use FUTEX_WAKE_PRIVATE
2064f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber                    (void) syscall(__NR_futex, &cblk->mFutex, FUTEX_WAKE, 1);
2074f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber                }
2084f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber            }
2094f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber        }
2104f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    }
2114f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber}
2124f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
2134f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas HuberFastCaptureDumpState::FastCaptureDumpState() : FastThreadDumpState(),
2144f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber    mReadSequence(0), mFramesRead(0), mReadErrors(0), mSampleRate(0), mFrameCount(0)
2154f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber{
2164f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber}
2174f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
2184f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas HuberFastCaptureDumpState::~FastCaptureDumpState()
2194f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber{
2204f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber}
2214f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber
2224f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber}   // namespace android
2234f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber