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()
{
for (auto task : tasks) task->get();
for (auto task : tasks) task->done();
tasks.clear();
return true;
@ -181,7 +181,7 @@ bool SwRenderer::postRender()
bool SwRenderer::render(const Shape& shape, void *data)
{
auto task = static_cast<SwTask*>(data);
task->get();
task->done();
uint8_t r, g, b, a;
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);
if (!task) return true;
task->get();
task->done();
shapeFree(&task->shape);
if (task->transform) free(task->transform);
delete(task);
@ -226,13 +226,13 @@ void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform*
if (flags == RenderUpdateFlag::None) return task;
//Finish previous task if it has duplicated request.
if (task->valid()) task->get();
task->done();
task->sdata = &sdata;
if (compList.size() > 0) {
//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());
}

View file

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

View file

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

View file

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