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

Commit d0afeb7c authored by Pascal Mütschard's avatar Pascal Mütschard
Browse files

Improvements to SF's BackgroundExcecutor.

- stop using utils/Singleton.h (it's marked as DO NOT USE)
- add a low priority instance
- explicitly set the thread priorities for both the HP and LP instances.

Test: manual, libsurfaceflinger_unittest
Bug: http://b/336461947
Change-Id: Ie10f663ed43aad21ba2a5235cd86a1101dec0cd7
parent 3e48aa43
Loading
Loading
Loading
Loading
+21 −3
Original line number Diff line number Diff line
@@ -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>

@@ -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, &param);
}

} // 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();
@@ -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() {
+14 −3
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@

#include <ftl/small_vector.h>
#include <semaphore.h>
#include <utils/Singleton.h>
#include <thread>

#include "LocklessQueue.h"
@@ -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.
@@ -37,6 +46,8 @@ public:
    void flushQueue();

private:
    BackgroundExecutor(bool highPriority);

    sem_t mSemaphore;
    std::atomic_bool mDone = false;