common taskScheduler: thread sync optmization

replaced future/promise with mutex since they use a lot of memory allocation number.

plus, binary size is reduced from 2094896 -> 1746864
This commit is contained in:
Hermet Park 2020-11-09 14:36:22 +09:00 committed by GitHub
parent e445b7f579
commit 9872cf066d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 31 deletions

View file

@ -139,7 +139,7 @@ SwRenderer::~SwRenderer()
bool SwRenderer::clear() bool SwRenderer::clear()
{ {
for (auto task : tasks) task->get(); for (auto task : tasks) task->done();
tasks.clear(); tasks.clear();
return true; return true;
@ -181,7 +181,7 @@ bool SwRenderer::postRender()
bool SwRenderer::render(const Shape& shape, void *data) bool SwRenderer::render(const Shape& shape, void *data)
{ {
auto task = static_cast<SwTask*>(data); auto task = static_cast<SwTask*>(data);
task->get(); task->done();
uint8_t r, g, b, a; uint8_t r, g, b, a;
if (auto fill = task->sdata->fill()) { if (auto fill = task->sdata->fill()) {
@ -205,7 +205,7 @@ bool SwRenderer::dispose(TVG_UNUSED const Shape& sdata, void *data)
auto task = static_cast<SwTask*>(data); auto task = static_cast<SwTask*>(data);
if (!task) return true; if (!task) return true;
task->get(); task->done();
shapeFree(&task->shape); shapeFree(&task->shape);
if (task->transform) free(task->transform); if (task->transform) free(task->transform);
delete(task); delete(task);
@ -226,13 +226,13 @@ void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform*
if (flags == RenderUpdateFlag::None) return task; if (flags == RenderUpdateFlag::None) return task;
//Finish previous task if it has duplicated request. //Finish previous task if it has duplicated request.
if (task->valid()) task->get(); task->done();
task->sdata = &sdata; task->sdata = &sdata;
if (compList.size() > 0) { if (compList.size() > 0) {
//Guarantee composition targets get ready. //Guarantee composition targets get ready.
for (auto comp : compList) static_cast<SwTask*>(comp.edata)->get(); for (auto comp : compList) static_cast<SwTask*>(comp.edata)->done();
task->compList.assign(compList.begin(), compList.end()); task->compList.assign(compList.begin(), compList.end());
} }

View file

@ -22,6 +22,8 @@
#include <deque> #include <deque>
#include <thread> #include <thread>
#include <vector> #include <vector>
#include <atomic>
#include <condition_variable>
#include "tvgTaskScheduler.h" #include "tvgTaskScheduler.h"
/************************************************************************/ /************************************************************************/
@ -179,7 +181,12 @@ void TaskScheduler::term()
void TaskScheduler::request(Task* task) void TaskScheduler::request(Task* task)
{ {
if (inst) { if (inst) inst->request(task);
inst->request(task);
}
} }
unsigned TaskScheduler::threads()
{
if (inst) return inst->threadCnt;
return 0;
}

View file

@ -22,31 +22,40 @@
#ifndef _TVG_TASK_SCHEDULER_H_ #ifndef _TVG_TASK_SCHEDULER_H_
#define _TVG_TASK_SCHEDULER_H_ #define _TVG_TASK_SCHEDULER_H_
#include <future> #include <mutex>
#include "tvgCommon.h" #include "tvgCommon.h"
namespace tvg namespace tvg
{ {
struct Task;
struct TaskScheduler
{
static unsigned threads();
static void init(unsigned threads);
static void term();
static void request(Task* task);
};
struct Task struct Task
{ {
private: private:
promise<void> sender; mutex mtx;
future<void> receiver; bool working = false;
public: public:
virtual ~Task() = default; virtual ~Task() = default;
void get() void done()
{ {
if (receiver.valid()) { if (!working) return;
receiver.get();
}
}
bool valid() if (TaskScheduler::threads() > 0) {
{ mtx.lock();
return receiver.valid(); working = false;
mtx.unlock();
}
} }
protected: protected:
@ -56,25 +65,23 @@ private:
void operator()(unsigned tid) void operator()(unsigned tid)
{ {
run(tid); run(tid);
sender.set_value();
if (TaskScheduler::threads() > 0) mtx.unlock();
} }
void prepare() void prepare()
{ {
sender = promise<void>(); if (TaskScheduler::threads() > 0) {
receiver = sender.get_future(); working = true;
mtx.lock();
}
} }
friend class TaskSchedulerImpl; friend class TaskSchedulerImpl;
}; };
struct TaskScheduler
{
static void init(unsigned threads);
static void term();
static void request(Task* task);
};
} }
#endif //_TVG_TASK_SCHEDULER_H_ #endif //_TVG_TASK_SCHEDULER_H_

View file

@ -2518,7 +2518,7 @@ bool SvgLoader::read()
bool SvgLoader::close() bool SvgLoader::close()
{ {
this->get(); this->done();
if (loaderData.svgParse) { if (loaderData.svgParse) {
free(loaderData.svgParse); free(loaderData.svgParse);
@ -2541,7 +2541,7 @@ bool SvgLoader::close()
unique_ptr<Scene> SvgLoader::data() unique_ptr<Scene> SvgLoader::data()
{ {
this->get(); this->done();
if (root) return move(root); if (root) return move(root);
else return nullptr; else return nullptr;
} }