Loading services/surfaceflinger/BackgroundExecutor.cpp +21 −3 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ #define LOG_TAG "BackgroundExecutor" #define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <processgroup/sched_policy.h> #include <pthread.h> #include <sched.h> #include <utils/Log.h> #include <mutex> Loading @@ -26,14 +29,24 @@ namespace android { ANDROID_SINGLETON_STATIC_INSTANCE(BackgroundExecutor); namespace { BackgroundExecutor::BackgroundExecutor() : Singleton<BackgroundExecutor>() { void set_thread_priority(bool highPriority) { set_sched_policy(0, highPriority ? SP_FOREGROUND : SP_BACKGROUND); struct sched_param param = {0}; param.sched_priority = highPriority ? 2 : 0 /* must be 0 for non-RT */; sched_setscheduler(gettid(), highPriority ? SCHED_FIFO : SCHED_NORMAL, ¶m); } } // anonymous namespace BackgroundExecutor::BackgroundExecutor(bool highPriority) { // mSemaphore must be initialized before any calls to // BackgroundExecutor::sendCallbacks. For this reason, we initialize it // within the constructor instead of within mThread. LOG_ALWAYS_FATAL_IF(sem_init(&mSemaphore, 0, 0), "sem_init failed"); mThread = std::thread([&]() { mThread = std::thread([&, highPriority]() { set_thread_priority(highPriority); while (!mDone) { LOG_ALWAYS_FATAL_IF(sem_wait(&mSemaphore), "sem_wait failed (%d)", errno); auto callbacks = mCallbacksQueue.pop(); Loading @@ -45,6 +58,11 @@ BackgroundExecutor::BackgroundExecutor() : Singleton<BackgroundExecutor>() { } } }); if (highPriority) { pthread_setname_np(mThread.native_handle(), "BckgrndExec HP"); } else { pthread_setname_np(mThread.native_handle(), "BckgrndExec LP"); } } BackgroundExecutor::~BackgroundExecutor() { Loading services/surfaceflinger/BackgroundExecutor.h +14 −3 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ #include <ftl/small_vector.h> #include <semaphore.h> #include <utils/Singleton.h> #include <thread> #include "LocklessQueue.h" Loading @@ -26,10 +25,20 @@ namespace android { // Executes tasks off the main thread. class BackgroundExecutor : public Singleton<BackgroundExecutor> { class BackgroundExecutor { public: BackgroundExecutor(); ~BackgroundExecutor(); static BackgroundExecutor& getInstance() { static BackgroundExecutor instance(true); return instance; } static BackgroundExecutor& getLowPriorityInstance() { static BackgroundExecutor instance(false); return instance; } using Callbacks = ftl::SmallVector<std::function<void()>, 10>; // Queues callbacks onto a work queue to be executed by a background thread. // This is safe to call from multiple threads. Loading @@ -37,6 +46,8 @@ public: void flushQueue(); private: BackgroundExecutor(bool highPriority); sem_t mSemaphore; std::atomic_bool mDone = false; Loading Loading
services/surfaceflinger/BackgroundExecutor.cpp +21 −3 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ #define LOG_TAG "BackgroundExecutor" #define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <processgroup/sched_policy.h> #include <pthread.h> #include <sched.h> #include <utils/Log.h> #include <mutex> Loading @@ -26,14 +29,24 @@ namespace android { ANDROID_SINGLETON_STATIC_INSTANCE(BackgroundExecutor); namespace { BackgroundExecutor::BackgroundExecutor() : Singleton<BackgroundExecutor>() { void set_thread_priority(bool highPriority) { set_sched_policy(0, highPriority ? SP_FOREGROUND : SP_BACKGROUND); struct sched_param param = {0}; param.sched_priority = highPriority ? 2 : 0 /* must be 0 for non-RT */; sched_setscheduler(gettid(), highPriority ? SCHED_FIFO : SCHED_NORMAL, ¶m); } } // anonymous namespace BackgroundExecutor::BackgroundExecutor(bool highPriority) { // mSemaphore must be initialized before any calls to // BackgroundExecutor::sendCallbacks. For this reason, we initialize it // within the constructor instead of within mThread. LOG_ALWAYS_FATAL_IF(sem_init(&mSemaphore, 0, 0), "sem_init failed"); mThread = std::thread([&]() { mThread = std::thread([&, highPriority]() { set_thread_priority(highPriority); while (!mDone) { LOG_ALWAYS_FATAL_IF(sem_wait(&mSemaphore), "sem_wait failed (%d)", errno); auto callbacks = mCallbacksQueue.pop(); Loading @@ -45,6 +58,11 @@ BackgroundExecutor::BackgroundExecutor() : Singleton<BackgroundExecutor>() { } } }); if (highPriority) { pthread_setname_np(mThread.native_handle(), "BckgrndExec HP"); } else { pthread_setname_np(mThread.native_handle(), "BckgrndExec LP"); } } BackgroundExecutor::~BackgroundExecutor() { Loading
services/surfaceflinger/BackgroundExecutor.h +14 −3 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ #include <ftl/small_vector.h> #include <semaphore.h> #include <utils/Singleton.h> #include <thread> #include "LocklessQueue.h" Loading @@ -26,10 +25,20 @@ namespace android { // Executes tasks off the main thread. class BackgroundExecutor : public Singleton<BackgroundExecutor> { class BackgroundExecutor { public: BackgroundExecutor(); ~BackgroundExecutor(); static BackgroundExecutor& getInstance() { static BackgroundExecutor instance(true); return instance; } static BackgroundExecutor& getLowPriorityInstance() { static BackgroundExecutor instance(false); return instance; } using Callbacks = ftl::SmallVector<std::function<void()>, 10>; // Queues callbacks onto a work queue to be executed by a background thread. // This is safe to call from multiple threads. Loading @@ -37,6 +46,8 @@ public: void flushQueue(); private: BackgroundExecutor(bool highPriority); sem_t mSemaphore; std::atomic_bool mDone = false; Loading