summary refs log tree commit diff stats
path: root/lib/pure/concurrency
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-06-02 16:21:55 +0200
committerAraq <rumpf_a@web.de>2015-06-02 16:21:55 +0200
commit3312d49a489e50e5c5f2275f7c0e400208eb8a5d (patch)
tree0e3b1b62a8f7e16b642da8b5d43963aeaa069af0 /lib/pure/concurrency
parent21ea8e6913fbfc16192ad3fd157e8e18e559219d (diff)
downloadNim-3312d49a489e50e5c5f2275f7c0e400208eb8a5d.tar.gz
proper waiting for the pinned thread
Diffstat (limited to 'lib/pure/concurrency')
-rw-r--r--lib/pure/concurrency/threadpool.nim9
1 files changed, 6 insertions, 3 deletions
diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim
index 10117183a..0059e3897 100644
--- a/lib/pure/concurrency/threadpool.nim
+++ b/lib/pure/concurrency/threadpool.nim
@@ -128,6 +128,7 @@ type
     initialized: bool # whether it has even been initialized
     shutdown: bool # the pool requests to shut down this worker thread
     q: ToFreeQueue
+    readyForTask: Semaphore
 
 proc await*(fv: FlowVarBase) =
   ## waits until the value for the flowVar arrives. Usually it is not necessary
@@ -301,6 +302,7 @@ proc distinguishedSlave(w: ptr Worker) {.thread.} =
       atomicStoreN(addr(w.ready), true, ATOMIC_SEQ_CST)
     else:
       w.ready = true
+    signal(w.readyForTask)
     await(w.taskArrived)
     assert(not w.ready)
     w.f(w, w.data)
@@ -340,6 +342,7 @@ proc activateDistinguishedThread(i: int) {.noinline.} =
   distinguishedData[i].initialized = true
   distinguishedData[i].q.empty = createSemaphore()
   initLock(distinguishedData[i].q.lock)
+  distinguishedData[i].readyForTask = createSemaphore()
   createThread(distinguished[i], distinguishedSlave, addr(distinguishedData[i]))
 
 proc setup() =
@@ -429,11 +432,11 @@ proc nimSpawn4(fn: WorkerProc; data: pointer; id: ThreadId) {.compilerProc.} =
   acquire(distinguishedLock)
   if not distinguishedData[id].initialized:
     activateDistinguishedThread(id)
+  release(distinguishedLock)
   while true:
     if selectWorker(addr(distinguishedData[id]), fn, data): break
-    cpuRelax()
-    # XXX exponential backoff?
-  release(distinguishedLock)
+    await(distinguishedData[id].readyForTask)
+
 
 proc sync*() =
   ## a simple barrier to wait for all spawn'ed tasks. If you need more elaborate