mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
Core: CoWorkerResources
git-svn-id: svn://ultimatepp.org/upp/trunk@10520 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
7a3d8522b8
commit
58db8a02bc
3 changed files with 93 additions and 6 deletions
|
|
@ -10,7 +10,7 @@ namespace Upp {
|
|||
#define LHITCOUNT(x) // RHITCOUNT(x)
|
||||
|
||||
thread_local bool CoWork::Pool::finlock;
|
||||
thread_local bool CoWork::is_worker;
|
||||
thread_local int CoWork::worker_index = -1;
|
||||
|
||||
CoWork::Pool& CoWork::GetPool()
|
||||
{
|
||||
|
|
@ -28,7 +28,7 @@ void CoWork::Pool::InitThreads(int nthreads)
|
|||
{
|
||||
LLOG("Pool::InitThreads: " << nthreads);
|
||||
for(int i = 0; i < nthreads; i++)
|
||||
CHECK(threads.Add().Run([=] { is_worker = true; ThreadRun(i); }, true));
|
||||
CHECK(threads.Add().Run([=] { worker_index = i; ThreadRun(i); }, true));
|
||||
}
|
||||
|
||||
void CoWork::Pool::ExitThreads()
|
||||
|
|
@ -46,9 +46,15 @@ void CoWork::Pool::ExitThreads()
|
|||
lock.Leave();
|
||||
}
|
||||
|
||||
int CoWork::GetPoolSize()
|
||||
{
|
||||
int n = GetPool().threads.GetCount();
|
||||
return n ? n : CPU_Cores() + 2;
|
||||
}
|
||||
|
||||
CoWork::Pool::Pool()
|
||||
{
|
||||
ASSERT(!is_worker);
|
||||
ASSERT(!IsWorker());
|
||||
|
||||
InitThreads(CPU_Cores() + 2);
|
||||
|
||||
|
|
|
|||
|
|
@ -40,9 +40,8 @@ public:
|
|||
|
||||
static Pool& GetPool();
|
||||
|
||||
static thread_local bool is_worker;
|
||||
static thread_local int worker_index;
|
||||
|
||||
// byte magic[sizeof(ConditionVariable)];
|
||||
ConditionVariable waitforfinish;
|
||||
Link<MJob, 2> jobs; // global stack and CoWork stack as double-linked lists
|
||||
int todo;
|
||||
|
|
@ -72,13 +71,35 @@ public:
|
|||
|
||||
bool IsFinished();
|
||||
|
||||
static bool IsWorker() { return is_worker; }
|
||||
static bool IsWorker() { return worker_index >= 0; }
|
||||
static int GetWorkerIndex() { return worker_index; }
|
||||
static int GetPoolSize();
|
||||
static void SetPoolSize(int n);
|
||||
|
||||
CoWork();
|
||||
~CoWork();
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class CoWorkerResources {
|
||||
int workercount;
|
||||
Buffer<T> res;
|
||||
|
||||
public:
|
||||
int GetCount() const { return workercount + 1; }
|
||||
T& operator[](int i) { return res[i]; }
|
||||
|
||||
T& Get() { int i = CoWork::GetWorkerIndex(); return res[i < 0 ? workercount : i]; }
|
||||
T& operator~() { return Get(); }
|
||||
|
||||
CoWorkerResources() { workercount = CoWork::GetPoolSize(); res.Alloc(GetCount()); }
|
||||
|
||||
CoWorkerResources(Event<T&> initializer) : CoWorkerResources() {
|
||||
for(int i = 0; i < GetCount(); i++)
|
||||
initializer(res[i]);
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
class CoWork : NoCopy {
|
||||
|
|
|
|||
|
|
@ -108,8 +108,68 @@ non`-blocking variant of Finish).&]
|
|||
[s2;%% Returns true if current thread is CoWork worker thread.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:CoWork`:`:GetWorkerIndex`(`): [@(0.0.255) static] [@(0.0.255) int]_[* GetWorker
|
||||
Index]()&]
|
||||
[s2;%% Returns the index of worker `- index is >`= 0 and < GetPoolSize().
|
||||
This is useful if there is a need for per`-thread resources.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:CoWork`:`:GetPoolSize`(`): [@(0.0.255) static] [@(0.0.255) int]_[* GetPoolSize](
|
||||
)&]
|
||||
[s2;%% Returns the current count of worker threads.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:CoWork`:`:SetPoolSize`(int`): [@(0.0.255) static void]_[* SetPoolSize]([@(0.0.255) i
|
||||
nt]_[*@3 n])&]
|
||||
[s2;%% Adjusts the thread pool size (default pool size is CPU`_Cores()
|
||||
`+ 2).&]
|
||||
[s0; &]
|
||||
[s0; &]
|
||||
[ {{10000@(113.42.0) [s0;%% [*@7;4 CoWorkerResources]]}}&]
|
||||
[s3; &]
|
||||
[s1;:noref: [@(0.0.255)3 template][3 _<][@(0.0.255)3 class][3 _][*@4;3 T][3 >]&]
|
||||
[s1;:Upp`:`:CoWorkerResources`:`:class: [@(0.0.255) class]_[* CoWorkerResources]&]
|
||||
[s2;%% This is a simple helper class that provides per`-worker resources.
|
||||
For example, certain calculation requires the instance of computation
|
||||
model that is not immutable, but can be reused over iterations.
|
||||
In single`-thread code, a single instance of such model would
|
||||
be used over the whole loop, however in multi`-threaded code,
|
||||
each worker thread, plus thread that created CoWork need its
|
||||
own instance. CoWorkerResources helps to manage such situation.&]
|
||||
[s0;%% &]
|
||||
[ {{10000F(128)G(128)@1 [s0;%% [* Public Method List]]}}&]
|
||||
[s3; &]
|
||||
[s5;:Upp`:`:CoWorkerResources`:`:CoWorkerResources`(`): [* CoWorkerResources]()&]
|
||||
[s2;%% Creates a required number of instances so that each sub`-job
|
||||
of CoWork has its unique instance.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:CoWorkerResources`:`:CoWorkerResources`(Upp`:`:Event`<T`&`>`): [* CoWorkerR
|
||||
esources]([_^Upp`:`:Event^ Event]<[*@4 T][@(0.0.255) `&]>_[*@3 initializer])&]
|
||||
[s2;%% Creates a required number of instances so that each sub`-job
|
||||
of CoWork has its unique instance.and initializes them using
|
||||
[%-*@3 initializer].&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:CoWorkerResources`:`:GetCount`(`)const: [@(0.0.255) int]_[* GetCount]()_[@(0.0.255) c
|
||||
onst]&]
|
||||
[s2;%% Returns the number of instances. Note that this is equal to
|
||||
CoWork`::GetPoolSize() if thread that created CoWorkerResources
|
||||
is itself CoWork worker, or CoWork`::GetPoolSize() `+ 1 if it
|
||||
is any other thread. The reason for this is that CoWork owner
|
||||
can execute CoWork jobs too (while waiting in Finish).&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:CoWorkerResources`:`:operator`[`]`(int`): [*@4 T][@(0.0.255) `&]_[* operator`[`]
|
||||
]([@(0.0.255) int]_[*@3 i])&]
|
||||
[s2;%% Returns instance [%-*@3 i]. Together with GetCount can be used
|
||||
to initialize resources (alternative method to using constructor
|
||||
with [%-*@3 initializer].&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:CoWorkerResources`:`:Get`(`): [*@4 T][@(0.0.255) `&]_[* Get]()&]
|
||||
[s5;:Upp`:`:CoWorkerResources`:`:operator`~`(`): [*@4 T][@(0.0.255) `&]_[* operator`~]()&]
|
||||
[s2;%% Supposed to be called in CoWork job, returns a reference to
|
||||
resources unique for the thread.&]
|
||||
[s3; &]
|
||||
[s0; ]]
|
||||
Loading…
Add table
Add a link
Reference in a new issue