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

Commit 88bd61e3 authored by Glenn Kasten's avatar Glenn Kasten Committed by Android (Google) Code Review
Browse files

Merge "Reduce rollovers of unique ID generator" into nyc-dev

parents 3f5eba44 d2e67e1e
Loading
Loading
Loading
Loading
+22 −6
Original line number Original line Diff line number Diff line
@@ -176,7 +176,7 @@ AudioFlinger::AudioFlinger()
      mHardwareStatus(AUDIO_HW_IDLE),
      mHardwareStatus(AUDIO_HW_IDLE),
      mMasterVolume(1.0f),
      mMasterVolume(1.0f),
      mMasterMute(false),
      mMasterMute(false),
      mNextUniqueId(AUDIO_UNIQUE_ID_USE_MAX),   // zero has a special meaning, so unavailable
      // mNextUniqueId(AUDIO_UNIQUE_ID_USE_MAX),
      mMode(AUDIO_MODE_INVALID),
      mMode(AUDIO_MODE_INVALID),
      mBtNrecIsOff(false),
      mBtNrecIsOff(false),
      mIsLowRamDevice(true),
      mIsLowRamDevice(true),
@@ -184,6 +184,12 @@ AudioFlinger::AudioFlinger()
      mGlobalEffectEnableTime(0),
      mGlobalEffectEnableTime(0),
      mSystemReady(false)
      mSystemReady(false)
{
{
    // unsigned instead of audio_unique_id_use_t, because ++ operator is unavailable for enum
    for (unsigned use = AUDIO_UNIQUE_ID_USE_UNSPECIFIED; use < AUDIO_UNIQUE_ID_USE_MAX; use++) {
        // zero ID has a special meaning, so unavailable
        mNextUniqueIds[use] = AUDIO_UNIQUE_ID_USE_MAX;
    }

    getpid_cached = getpid();
    getpid_cached = getpid();
    const bool doLog = property_get_bool("ro.test_harness", false);
    const bool doLog = property_get_bool("ro.test_harness", false);
    if (doLog) {
    if (doLog) {
@@ -2440,14 +2446,24 @@ AudioFlinger::RecordThread *AudioFlinger::checkRecordThread_l(audio_io_handle_t


audio_unique_id_t AudioFlinger::nextUniqueId(audio_unique_id_use_t use)
audio_unique_id_t AudioFlinger::nextUniqueId(audio_unique_id_use_t use)
{
{
    int32_t base = android_atomic_add(AUDIO_UNIQUE_ID_USE_MAX, &mNextUniqueId);
    // We have no way of recovering from wraparound
    LOG_ALWAYS_FATAL_IF(base == 0, "unique ID overflow");
    // This is the internal API, so it is OK to assert on bad parameter.
    // This is the internal API, so it is OK to assert on bad parameter.
    LOG_ALWAYS_FATAL_IF((unsigned) use >= (unsigned) AUDIO_UNIQUE_ID_USE_MAX);
    LOG_ALWAYS_FATAL_IF((unsigned) use >= (unsigned) AUDIO_UNIQUE_ID_USE_MAX);
    const int maxRetries = use == AUDIO_UNIQUE_ID_USE_SESSION ? 3 : 1;
    for (int retry = 0; retry < maxRetries; retry++) {
        // The cast allows wraparound from max positive to min negative instead of abort
        uint32_t base = (uint32_t) atomic_fetch_add_explicit(&mNextUniqueIds[use],
                (uint_fast32_t) AUDIO_UNIQUE_ID_USE_MAX, memory_order_acq_rel);
        ALOG_ASSERT(audio_unique_id_get_use(base) == AUDIO_UNIQUE_ID_USE_UNSPECIFIED);
        ALOG_ASSERT(audio_unique_id_get_use(base) == AUDIO_UNIQUE_ID_USE_UNSPECIFIED);
        // allow wrap by skipping 0 and -1 for session ids
        if (!(base == 0 || base == (~0u & ~AUDIO_UNIQUE_ID_USE_MASK))) {
            ALOGW_IF(retry != 0, "unique ID overflow for use %d", use);
            return (audio_unique_id_t) (base | use);
            return (audio_unique_id_t) (base | use);
        }
        }
    }
    // We have no way of recovering from wraparound
    LOG_ALWAYS_FATAL("unique ID overflow for use %d", use);
    // TODO Use a floor after wraparound.  This may need a mutex.
}


AudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l() const
AudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l() const
{
{
+2 −3
Original line number Original line Diff line number Diff line
@@ -679,9 +679,8 @@ private:
                // protected by mClientLock
                // protected by mClientLock
                DefaultKeyedVector< pid_t, sp<NotificationClient> >    mNotificationClients;
                DefaultKeyedVector< pid_t, sp<NotificationClient> >    mNotificationClients;


                volatile int32_t                    mNextUniqueId;  // updated by android_atomic_inc
                // updated by atomic_fetch_add_explicit
                // nextUniqueId() returns uint32_t, but this is declared int32_t
                volatile atomic_uint_fast32_t       mNextUniqueIds[AUDIO_UNIQUE_ID_USE_MAX];
                // because the atomic operations require an int32_t


                audio_mode_t                        mMode;
                audio_mode_t                        mMode;
                bool                                mBtNrecIsOff;
                bool                                mBtNrecIsOff;