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

Commit d2e67e1e authored by Glenn Kasten's avatar Glenn Kasten
Browse files

Reduce rollovers of unique ID generator

Bug: 28119934
Change-Id: I6c57d5555f6c5ddc4d4eee1e6f27fc4aaeb31c83
parent 5cc32c5e
Loading
Loading
Loading
Loading
+22 −6
Original line number Diff line number Diff line
@@ -176,7 +176,7 @@ AudioFlinger::AudioFlinger()
      mHardwareStatus(AUDIO_HW_IDLE),
      mMasterVolume(1.0f),
      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),
      mBtNrecIsOff(false),
      mIsLowRamDevice(true),
@@ -184,6 +184,12 @@ AudioFlinger::AudioFlinger()
      mGlobalEffectEnableTime(0),
      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();
    const bool doLog = property_get_bool("ro.test_harness", false);
    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)
{
    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.
    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);
        // 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);
        }
    }
    // 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
{
+2 −3
Original line number Diff line number Diff line
@@ -679,9 +679,8 @@ private:
                // protected by mClientLock
                DefaultKeyedVector< pid_t, sp<NotificationClient> >    mNotificationClients;

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

                audio_mode_t                        mMode;
                bool                                mBtNrecIsOff;