summary refs log tree commit diff stats
path: root/lib/pure/concurrency
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-05-14 01:51:44 +0200
committerAraq <rumpf_a@web.de>2014-05-14 01:51:44 +0200
commitc43e8df90cc5d52c6c57452a28f433075bf66236 (patch)
treec3b3e85aa6f780363d625dea2c1944b9d993c323 /lib/pure/concurrency
parent6195dbe491ccd864c5dcb59f87826291ac1f1ff4 (diff)
downloadNim-c43e8df90cc5d52c6c57452a28f433075bf66236.tar.gz
progress for the 'parallel' statement
Diffstat (limited to 'lib/pure/concurrency')
-rw-r--r--lib/pure/concurrency/threadpool.nim26
1 files changed, 15 insertions, 11 deletions
diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim
index 856820c6e..86819d25a 100644
--- a/lib/pure/concurrency/threadpool.nim
+++ b/lib/pure/concurrency/threadpool.nim
@@ -74,12 +74,20 @@ type
     data: pointer
     ready: bool # put it here for correct alignment!
     initialized: bool # whether it has even been initialized
+    shutdown: bool # the pool requests to shut down this worker thread
 
 proc nimArgsPassingDone(p: pointer) {.compilerProc.} =
   let w = cast[ptr Worker](p)
   signal(w.taskStarted)
 
+const
+  MaxThreadPoolSize* = 256 ## maximal size of the thread pool. 256 threads
+                           ## should be good enough for anybody ;-)
+
 var
+  currentPoolSize: int
+  maxPoolSize = MaxThreadPoolSize
+  minPoolSize = 4
   gSomeReady = createCondVar()
   readyWorker: ptr Worker
 
@@ -91,15 +99,9 @@ proc slave(w: ptr Worker) {.thread.} =
     await(w.taskArrived)
     assert(not w.ready)
     w.f(w, w.data)
-
-const
-  MaxThreadPoolSize* = 256 ## maximal size of the thread pool. 256 threads
-                           ## should be good enough for anybody ;-)
-
-var
-  currentPoolSize: int
-  maxPoolSize = MaxThreadPoolSize
-  minPoolSize = 4
+    if w.shutdown:
+      w.shutdown = false
+      atomicDec currentPoolSize
 
 proc setMinPoolSize*(size: range[1..MaxThreadPoolSize]) =
   ## sets the minimal thread pool size. The default value of this is 4.
@@ -183,13 +185,15 @@ proc nimSpawn(fn: WorkerProc; data: pointer) {.compilerProc.} =
             if not workersData[currentPoolSize].initialized:
               activateThread(currentPoolSize)
             let w = addr(workersData[currentPoolSize])
-            inc currentPoolSize
+            atomicInc currentPoolSize
             if selectWorker(w, fn, data):
               release(stateLock)
               return
             # else we didn't succeed but some other thread, so do nothing.
         of doShutdownThread:
-          if currentPoolSize > minPoolSize: dec currentPoolSize
+          if currentPoolSize > minPoolSize:
+            let w = addr(workersData[currentPoolSize-1])
+            w.shutdown = true
           # we don't free anything here. Too dangerous.
         release(stateLock)
       # else the acquire failed, but this means some