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

Commit 65443895 authored by Hongwei Wang's avatar Hongwei Wang Committed by Android (Google) Code Review
Browse files

Merge "AudioFlinger::Thread ensure proper add / sub" into qt-dev

parents e46a1477 95e3768e
Loading
Loading
Loading
Loading
+8 −25
Original line number Diff line number Diff line
@@ -20,30 +20,13 @@
#include <android-base/macros.h>
#include <private/media/AudioTrackShared.h>
#include <utils/Log.h>
#include <audio_utils/safe_math.h>

#include <linux/futex.h>
#include <sys/syscall.h>

namespace android {

// TODO: consider pulling this into a shared header.
// safe_sub_overflow is used ensure that subtraction occurs in the same native type
// with proper 2's complement overflow.  Without calling this function, it is possible,
// for example, that optimizing compilers may elect to treat 32 bit subtraction
// as 64 bit subtraction when storing into a 64 bit destination as integer overflow is
// technically undefined.
template<typename T,
         typename U,
         typename = std::enable_if_t<std::is_same<std::decay_t<T>,
                                       std::decay_t<U>>{}>>
         // ensure arguments are same type (ignoring volatile, which is used in cblk variables).
auto safe_sub_overflow(const T& a, const U& b) {
    std::decay_t<T> result;
    (void)__builtin_sub_overflow(a, b, &result);
    // note if __builtin_sub_overflow returns true, an overflow occurred.
    return result;
}

// used to clamp a value to size_t.  TODO: move to another file.
template <typename T>
size_t clampToSize(T x) {
@@ -204,7 +187,7 @@ status_t ClientProxy::obtainBuffer(Buffer* buffer, const struct timespec *reques
            front = cblk->u.mStreaming.mFront;
        }
        // write to rear, read from front
        ssize_t filled = safe_sub_overflow(rear, front);
        ssize_t filled = audio_utils::safe_sub_overflow(rear, front);
        // pipe should not be overfull
        if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
            if (mIsOut) {
@@ -702,7 +685,7 @@ void ServerProxy::flushBufferIfNeeded()
        const size_t overflowBit = mFrameCountP2 << 1;
        const size_t mask = overflowBit - 1;
        int32_t newFront = (front & ~mask) | (flush & mask);
        ssize_t filled = safe_sub_overflow(rear, newFront);
        ssize_t filled = audio_utils::safe_sub_overflow(rear, newFront);
        if (filled >= (ssize_t)overflowBit) {
            // front and rear offsets span the overflow bit of the p2 mask
            // so rebasing newFront on the front offset is off by the overflow bit.
@@ -744,7 +727,7 @@ int32_t AudioTrackServerProxy::getRear() const
        const size_t overflowBit = mFrameCountP2 << 1;
        const size_t mask = overflowBit - 1;
        int32_t newRear = (rear & ~mask) | (stop & mask);
        ssize_t filled = safe_sub_overflow(newRear, front);
        ssize_t filled = audio_utils::safe_sub_overflow(newRear, front);
        // overflowBit is unsigned, so cast to signed for comparison.
        if (filled >= (ssize_t)overflowBit) {
            // front and rear offsets span the overflow bit of the p2 mask
@@ -796,7 +779,7 @@ status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush)
        front = android_atomic_acquire_load(&cblk->u.mStreaming.mFront);
        rear = cblk->u.mStreaming.mRear;
    }
    ssize_t filled = safe_sub_overflow(rear, front);
    ssize_t filled = audio_utils::safe_sub_overflow(rear, front);
    // pipe should not already be overfull
    if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
        ALOGE("Shared memory control block is corrupt (filled=%zd, mFrameCount=%zu); shutting down",
@@ -923,7 +906,7 @@ size_t AudioTrackServerProxy::framesReady()
        return mFrameCount;
    }
    const int32_t rear = getRear();
    ssize_t filled = safe_sub_overflow(rear, cblk->u.mStreaming.mFront);
    ssize_t filled = audio_utils::safe_sub_overflow(rear, cblk->u.mStreaming.mFront);
    // pipe should not already be overfull
    if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
        ALOGE("Shared memory control block is corrupt (filled=%zd, mFrameCount=%zu); shutting down",
@@ -949,7 +932,7 @@ size_t AudioTrackServerProxy::framesReadySafe() const
        return mFrameCount;
    }
    const int32_t rear = getRear();
    const ssize_t filled = safe_sub_overflow(rear, cblk->u.mStreaming.mFront);
    const ssize_t filled = audio_utils::safe_sub_overflow(rear, cblk->u.mStreaming.mFront);
    if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
        return 0; // error condition, silently return 0.
    }
@@ -1259,7 +1242,7 @@ size_t AudioRecordServerProxy::framesReadySafe() const
    }
    const int32_t front = android_atomic_acquire_load(&mCblk->u.mStreaming.mFront);
    const int32_t rear = mCblk->u.mStreaming.mRear;
    const ssize_t filled = safe_sub_overflow(rear, front);
    const ssize_t filled = audio_utils::safe_sub_overflow(rear, front);
    if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
        return 0; // error condition, silently return 0.
    }
+7 −5
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@
#include <audio_utils/primitives.h>
#include <audio_utils/format.h>
#include <audio_utils/minifloat.h>
#include <audio_utils/safe_math.h>
#include <system/audio_effects/effect_ns.h>
#include <system/audio_effects/effect_aec.h>
#include <system/audio.h>
@@ -7904,7 +7905,7 @@ void AudioFlinger::RecordThread::ResamplerBufferProvider::sync(
    RecordThread *recordThread = (RecordThread *) threadBase.get();
    const int32_t rear = recordThread->mRsmpInRear;
    const int32_t front = mRsmpInFront;
    const ssize_t filled = rear - front;
    const ssize_t filled = audio_utils::safe_sub_overflow(rear, front);

    size_t framesIn;
    bool overrun = false;
@@ -7918,7 +7919,8 @@ void AudioFlinger::RecordThread::ResamplerBufferProvider::sync(
    } else {
        // client is not keeping up with server, but give it latest data
        framesIn = recordThread->mRsmpInFrames;
        mRsmpInFront = /* front = */ rear - framesIn;
        mRsmpInFront = /* front = */ audio_utils::safe_sub_overflow(
                rear, static_cast<int32_t>(framesIn));
        overrun = true;
    }
    if (framesAvailable != NULL) {
@@ -7942,7 +7944,7 @@ status_t AudioFlinger::RecordThread::ResamplerBufferProvider::getNextBuffer(
    RecordThread *recordThread = (RecordThread *) threadBase.get();
    int32_t rear = recordThread->mRsmpInRear;
    int32_t front = mRsmpInFront;
    ssize_t filled = rear - front;
    ssize_t filled = audio_utils::safe_sub_overflow(rear, front);
    // FIXME should not be P2 (don't want to increase latency)
    // FIXME if client not keeping up, discard
    LOG_ALWAYS_FATAL_IF(!(0 <= filled && (size_t) filled <= recordThread->mRsmpInFrames));
@@ -7975,13 +7977,13 @@ status_t AudioFlinger::RecordThread::ResamplerBufferProvider::getNextBuffer(
void AudioFlinger::RecordThread::ResamplerBufferProvider::releaseBuffer(
        AudioBufferProvider::Buffer* buffer)
{
    size_t stepCount = buffer->frameCount;
    int32_t stepCount = static_cast<int32_t>(buffer->frameCount);
    if (stepCount == 0) {
        return;
    }
    ALOG_ASSERT(stepCount <= mRsmpInUnrel);
    mRsmpInUnrel -= stepCount;
    mRsmpInFront += stepCount;
    mRsmpInFront = audio_utils::safe_add_overflow(mRsmpInFront, stepCount);
    buffer->raw = NULL;
    buffer->frameCount = 0;
}