diff options
author | Araq <rumpf_a@web.de> | 2014-06-02 19:03:01 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2014-06-02 19:03:01 +0200 |
commit | fbadbb399ec8a3d01195d4b50f7f73d1e9e5d31b (patch) | |
tree | 98feff70ef00b8a4759fcc6adc1ae7838e107fdb /lib/pure/concurrency | |
parent | b78173788d1f5e45091c31039e82960187db1277 (diff) | |
download | Nim-fbadbb399ec8a3d01195d4b50f7f73d1e9e5d31b.tar.gz |
hopefully faster barrier implementation
Diffstat (limited to 'lib/pure/concurrency')
-rw-r--r-- | lib/pure/concurrency/threadpool.nim | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim index 3a7693791..22f00bc0d 100644 --- a/lib/pure/concurrency/threadpool.nim +++ b/lib/pure/concurrency/threadpool.nim @@ -42,22 +42,30 @@ proc signal(cv: var CondVar) = type Barrier* {.compilerProc.} = object - counter: int + entered: int cv: CondVar + cacheAlign: array[0..20, byte] # ensure 'left' is not on the same + # cache line as 'entered' + left: int proc barrierEnter*(b: ptr Barrier) {.compilerProc.} = - atomicInc b.counter + atomicInc b.entered proc barrierLeave*(b: ptr Barrier) {.compilerProc.} = - atomicDec b.counter - if b.counter <= 0: signal(b.cv) + atomicInc b.left + # these can only be equal if 'closeBarrier' already signaled its interest + # in this event: + if b.left == b.entered: signal(b.cv) proc openBarrier*(b: ptr Barrier) {.compilerProc.} = - b.counter = 0 + b.entered = 0 b.cv = createCondVar() + b.left = -1 proc closeBarrier*(b: ptr Barrier) {.compilerProc.} = - while b.counter > 0: await(b.cv) + # signal interest in the "all done" event: + atomicInc b.left + while b.left != b.entered: await(b.cv) destroyCondVar(b.cv) {.pop.} |