From fa494718d4d3d543d9dcaf8903a6729ade2c7104 Mon Sep 17 00:00:00 2001 From: mtklein Date: Wed, 29 Oct 2014 09:21:47 -0700 Subject: [PATCH] SkTaskGroup::add(fn, arg) NOTREECHECKS=true BUG=skia: Review URL: https://codereview.chromium.org/687953003 --- src/utils/SkTaskGroup.cpp | 29 ++++++++++++++++++++--------- src/utils/SkTaskGroup.h | 6 ++++-- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/utils/SkTaskGroup.cpp b/src/utils/SkTaskGroup.cpp index a93b34f..f1ec7f4 100644 --- a/src/utils/SkTaskGroup.cpp +++ b/src/utils/SkTaskGroup.cpp @@ -26,7 +26,14 @@ public: if (!gGlobal) { // If we have no threads, run synchronously. return task->run(); } - gGlobal->add(task, pending); + gGlobal->add(&CallRunnable, task, pending); + } + + static void Add(void (*fn)(void*), void* arg, int32_t* pending) { + if (!gGlobal) { + return fn(arg); + } + gGlobal->add(fn, arg, pending); } static void Wait(int32_t* pending) { @@ -48,7 +55,7 @@ public: } // This Work isn't necessarily part of our SkTaskGroup of interest, but that's fine. // We threads gotta stick together. We're always making forward progress. - work.task->run(); + work.fn(work.arg); sk_atomic_dec(work.pending); // Release pairs with the sk_acquire_load() just above. } } @@ -61,9 +68,12 @@ private: SkCondVar* fC; }; + static void CallRunnable(void* arg) { static_cast(arg)->run(); } + struct Work { - SkRunnable* task; // A task to ->run(), - int32_t* pending; // then sk_atomic_dec(pending) afterwards. + void (*fn)(void*); // A function to call, + void* arg; // its argument, + int32_t* pending; // then sk_atomic_dec(pending) afterwards. }; explicit ThreadPool(int threads) : fDraining(false) { @@ -90,8 +100,8 @@ private: fThreads.deleteAll(); } - void add(SkRunnable* task, int32_t* pending) { - Work work = { task, pending }; + void add(void (*fn)(void*), void* arg, int32_t* pending) { + Work work = { fn, arg, pending }; sk_atomic_inc(pending); // No barrier needed. { AutoLock lock(&fReady); @@ -114,7 +124,7 @@ private: } pool->fWork.pop(&work); } - work.task->run(); + work.fn(work.arg); sk_atomic_dec(work.pending); // Release pairs with sk_acquire_load() in Wait(). } } @@ -144,6 +154,7 @@ SkTaskGroup::Enabler::~Enabler() { SkTaskGroup::SkTaskGroup() : fPending(0) {} -void SkTaskGroup::add(SkRunnable* task) { ThreadPool::Add(task, &fPending); } -void SkTaskGroup::wait() { ThreadPool::Wait(&fPending); } +void SkTaskGroup::add(SkRunnable* task) { ThreadPool::Add(task, &fPending); } +void SkTaskGroup::add(void (*fn)(void*), void* arg) { ThreadPool::Add(fn, arg, &fPending); } +void SkTaskGroup::wait() { ThreadPool::Wait(&fPending); } diff --git a/src/utils/SkTaskGroup.h b/src/utils/SkTaskGroup.h index dddd4ad..c60ceda 100644 --- a/src/utils/SkTaskGroup.h +++ b/src/utils/SkTaskGroup.h @@ -22,10 +22,12 @@ public: SkTaskGroup(); ~SkTaskGroup() { this->wait(); } - // Add a task to this SkTaskGroup. It will likely run() on another thread. + // Add a task to this SkTaskGroup. It will likely run on another thread. + // Neither add() method takes owership of any of its parameters. void add(SkRunnable*); + void add(void (*fn)(void*), void* arg); - // Block until all Tasks previously add()ed to this SkTaskGroup have run(). + // Block until all Tasks previously add()ed to this SkTaskGroup have run. // You may safely reuse this SkTaskGroup after wait() returns. void wait(); -- 2.7.4