diff options
author | 2024-06-18 18:31:36 +0000 | |
---|---|---|
committer | 2024-06-18 18:31:36 +0000 | |
commit | f9335c655da143ecb3eb2bb5f82cc6fa6d8fdff1 (patch) | |
tree | 5600e2b1a94591954d327da1c9ebd465dc97ba7f /libs/binder/IPCThreadState.cpp | |
parent | e70d4bdebb50e362991b72d77b7a003930cf468c (diff) | |
parent | 263507f9e3709bb4fff70ddd8e26c5dff46152ac (diff) |
Merge "binder: remove mutex from transaction processing loop" into main
Diffstat (limited to 'libs/binder/IPCThreadState.cpp')
-rw-r--r-- | libs/binder/IPCThreadState.cpp | 76 |
1 files changed, 37 insertions, 39 deletions
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp index fbc812571a..8b65d630ec 100644 --- a/libs/binder/IPCThreadState.cpp +++ b/libs/binder/IPCThreadState.cpp @@ -613,16 +613,20 @@ bool IPCThreadState::flushIfNeeded() void IPCThreadState::blockUntilThreadAvailable() { - pthread_mutex_lock(&mProcess->mThreadCountLock); - mProcess->mWaitingForThreads++; - while (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads) { - ALOGW("Waiting for thread to be free. mExecutingThreadsCount=%lu mMaxThreads=%lu\n", - static_cast<unsigned long>(mProcess->mExecutingThreadsCount), - static_cast<unsigned long>(mProcess->mMaxThreads)); - pthread_cond_wait(&mProcess->mThreadCountDecrement, &mProcess->mThreadCountLock); - } - mProcess->mWaitingForThreads--; - pthread_mutex_unlock(&mProcess->mThreadCountLock); + std::unique_lock lock_guard_(mProcess->mOnThreadAvailableLock); + mProcess->mOnThreadAvailableWaiting++; + mProcess->mOnThreadAvailableCondVar.wait(lock_guard_, [&] { + size_t max = mProcess->mMaxThreads; + size_t cur = mProcess->mExecutingThreadsCount; + if (cur < max) { + return true; + } + ALOGW("Waiting for thread to be free. mExecutingThreadsCount=%" PRId64 + " mMaxThreads=%" PRId64 "\n", + cur, max); + return false; + }); + mProcess->mOnThreadAvailableWaiting--; } status_t IPCThreadState::getAndExecuteCommand() @@ -642,34 +646,33 @@ status_t IPCThreadState::getAndExecuteCommand() ALOGI("%s", message.c_str()); } - pthread_mutex_lock(&mProcess->mThreadCountLock); - mProcess->mExecutingThreadsCount++; - if (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads && - mProcess->mStarvationStartTimeMs == 0) { - mProcess->mStarvationStartTimeMs = uptimeMillis(); + size_t newThreadsCount = mProcess->mExecutingThreadsCount.fetch_add(1) + 1; + if (newThreadsCount >= mProcess->mMaxThreads) { + int64_t expected = 0; + mProcess->mStarvationStartTimeMs.compare_exchange_strong(expected, uptimeMillis()); } - pthread_mutex_unlock(&mProcess->mThreadCountLock); result = executeCommand(cmd); - pthread_mutex_lock(&mProcess->mThreadCountLock); - mProcess->mExecutingThreadsCount--; - if (mProcess->mExecutingThreadsCount < mProcess->mMaxThreads && - mProcess->mStarvationStartTimeMs != 0) { - int64_t starvationTimeMs = uptimeMillis() - mProcess->mStarvationStartTimeMs; - if (starvationTimeMs > 100) { - ALOGE("binder thread pool (%zu threads) starved for %" PRId64 " ms", - mProcess->mMaxThreads, starvationTimeMs); + size_t maxThreads = mProcess->mMaxThreads; + newThreadsCount = mProcess->mExecutingThreadsCount.fetch_sub(1) - 1; + if (newThreadsCount < maxThreads) { + size_t starvationStartTimeMs = mProcess->mStarvationStartTimeMs.exchange(0); + if (starvationStartTimeMs != 0) { + int64_t starvationTimeMs = uptimeMillis() - starvationStartTimeMs; + if (starvationTimeMs > 100) { + ALOGE("binder thread pool (%zu threads) starved for %" PRId64 " ms", maxThreads, + starvationTimeMs); + } } - mProcess->mStarvationStartTimeMs = 0; } // Cond broadcast can be expensive, so don't send it every time a binder // call is processed. b/168806193 - if (mProcess->mWaitingForThreads > 0) { - pthread_cond_broadcast(&mProcess->mThreadCountDecrement); + if (mProcess->mOnThreadAvailableWaiting > 0) { + std::lock_guard lock_guard_(mProcess->mOnThreadAvailableLock); + mProcess->mOnThreadAvailableCondVar.notify_all(); } - pthread_mutex_unlock(&mProcess->mThreadCountLock); } return result; @@ -727,10 +730,9 @@ void IPCThreadState::processPostWriteDerefs() void IPCThreadState::joinThreadPool(bool isMain) { - LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid()); - pthread_mutex_lock(&mProcess->mThreadCountLock); + LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), + getpid()); mProcess->mCurrentThreads++; - pthread_mutex_unlock(&mProcess->mThreadCountLock); mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); mIsLooper = true; @@ -758,13 +760,11 @@ void IPCThreadState::joinThreadPool(bool isMain) mOut.writeInt32(BC_EXIT_LOOPER); mIsLooper = false; talkWithDriver(false); - pthread_mutex_lock(&mProcess->mThreadCountLock); - LOG_ALWAYS_FATAL_IF(mProcess->mCurrentThreads == 0, - "Threadpool thread count = 0. Thread cannot exist and exit in empty " - "threadpool\n" + size_t oldCount = mProcess->mCurrentThreads.fetch_sub(1); + LOG_ALWAYS_FATAL_IF(oldCount == 0, + "Threadpool thread count underflowed. Thread cannot exist and exit in " + "empty threadpool\n" "Misconfiguration. Increase threadpool max threads configuration\n"); - mProcess->mCurrentThreads--; - pthread_mutex_unlock(&mProcess->mThreadCountLock); } status_t IPCThreadState::setupPolling(int* fd) @@ -776,9 +776,7 @@ status_t IPCThreadState::setupPolling(int* fd) mOut.writeInt32(BC_ENTER_LOOPER); flushCommands(); *fd = mProcess->mDriverFD; - pthread_mutex_lock(&mProcess->mThreadCountLock); mProcess->mCurrentThreads++; - pthread_mutex_unlock(&mProcess->mThreadCountLock); return 0; } |