mirror of
https://github.com/Alcaro/Flips.git
synced 2026-09-07 10:06:09 -05:00
Update Arlib
This commit is contained in:
95
arlib/thread/split-thr.cpp
Normal file
95
arlib/thread/split-thr.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#include "thread.h"
|
||||
|
||||
#ifdef ARLIB_THREAD
|
||||
namespace {
|
||||
|
||||
//TODO: there is no procedure for destroying threads
|
||||
struct threadpool {
|
||||
mutex lock;
|
||||
|
||||
multievent* wake;
|
||||
multievent* started;
|
||||
uint32_t numthreads;
|
||||
uint32_t numidle;
|
||||
|
||||
//these vary between each piece of work
|
||||
function<void(unsigned int id)> work;
|
||||
uint32_t id;
|
||||
multievent* done;
|
||||
};
|
||||
|
||||
static struct threadpool * pool;
|
||||
|
||||
void threadproc(struct threadpool * This)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
This->wake->wait();
|
||||
lock_decr(&This->numidle);
|
||||
|
||||
function<void(unsigned int id)> work = This->work;
|
||||
unsigned int id = lock_incr(&This->id);
|
||||
multievent* done = This->done;
|
||||
|
||||
This->started->signal();
|
||||
work(id);
|
||||
done->signal();
|
||||
lock_incr(&This->numidle);
|
||||
}
|
||||
}
|
||||
|
||||
struct threadpool* pool_create()
|
||||
{
|
||||
struct threadpool * pool = new threadpool;
|
||||
|
||||
pool->wake=new multievent();
|
||||
pool->started=new multievent();
|
||||
pool->numthreads=0;
|
||||
pool->numidle=0;
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
void pool_delete(struct threadpool* pool)
|
||||
{
|
||||
delete pool->wake;
|
||||
delete pool->started;
|
||||
delete pool;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void thread_split(unsigned int count, function<void(unsigned int id)> work)
|
||||
{
|
||||
if (!count) return;
|
||||
if (count==1)
|
||||
{
|
||||
work(0);
|
||||
return;
|
||||
}
|
||||
struct threadpool * This = thread_once_undo(&pool, bind(pool_create), bind(pool_delete));
|
||||
|
||||
This->lock.lock();
|
||||
multievent* done=new multievent();
|
||||
|
||||
This->work=work;
|
||||
This->id=1;
|
||||
This->done=done;
|
||||
|
||||
while (lock_read(&This->numidle) < count-1)
|
||||
{
|
||||
This->numthreads++;
|
||||
lock_incr(&This->numidle);
|
||||
thread_create(bind_ptr(threadproc, This));
|
||||
}
|
||||
|
||||
This->wake->signal(count-1);
|
||||
This->started->wait(count-1);
|
||||
This->lock.unlock();
|
||||
|
||||
work(0);
|
||||
|
||||
done->wait(count-1);
|
||||
delete done;
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user