1 /** 2 Copyright: Copyright (c) 2013-2016 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 module voxelman.utils.workergroup; 7 8 import core.atomic : atomicStore; 9 import std.concurrency : Tid, spawn, send, prioritySend; 10 11 struct WorkerGroup(alias workerFun) 12 { 13 import std.traits : ParameterTypeTuple; 14 15 private bool _areWorkersStarted; 16 private uint _nextWorker; 17 private Tid[] _workers; 18 private uint _numWorkers; 19 private shared bool _areWorkersRunning; 20 21 void startWorkers(uint numWorkers, ParameterTypeTuple!workerFun args) 22 { 23 if (_areWorkersStarted) return; 24 _numWorkers = numWorkers; 25 atomicStore(_areWorkersRunning, true); 26 foreach(_; 0.._numWorkers) 27 _workers ~= spawn(&workerFun, args); 28 foreach(worker; _workers) 29 worker.send(&_areWorkersRunning); 30 _areWorkersStarted = true; 31 } 32 33 Tid nextWorker() @property 34 { 35 _nextWorker %= _numWorkers; 36 return _workers[_nextWorker++]; 37 } 38 39 void stopWorkersWhenDone() 40 { 41 atomicStore(_areWorkersRunning, false); 42 foreach(worker; _workers) 43 worker.send(0); 44 _areWorkersStarted = false; 45 } 46 47 void stopWorkers() 48 { 49 foreach(worker; _workers) 50 worker.prioritySend(0); 51 atomicStore(_areWorkersRunning, false); 52 _areWorkersStarted = false; 53 } 54 } 55 56 void atomicStoreLocal(T)(ref T var, auto ref T value) 57 { 58 atomicStore(*cast(shared(T)*)(&var), cast(shared(T))value); 59 } 60 61 T atomicLoadLocal(T)(ref const T var) 62 { 63 return cast(T)atomicLoad(*cast(shared(const T)*)(&var)); 64 }