Loading services/audioflinger/AudioFlinger.cpp +22 −6 Original line number Original line Diff line number Diff line Loading @@ -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), Loading @@ -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) { Loading Loading @@ -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 { { Loading services/audioflinger/AudioFlinger.h +2 −3 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading
services/audioflinger/AudioFlinger.cpp +22 −6 Original line number Original line Diff line number Diff line Loading @@ -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), Loading @@ -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) { Loading Loading @@ -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 { { Loading
services/audioflinger/AudioFlinger.h +2 −3 Original line number Original line Diff line number Diff line Loading @@ -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; Loading