summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-06-11 15:17:28 +0200
committerAraq <rumpf_a@web.de>2015-06-14 22:51:29 +0200
commit1452edfbb9d7de1d654248cc709a7436d8d404c2 (patch)
treee378dfb8f190dd4e52dd52d6fa36876a2ade1b7b
parent69f2b67b5ed9c992d180b37bb9c3e92ba2eb78c2 (diff)
downloadNim-1452edfbb9d7de1d654248cc709a7436d8d404c2.tar.gz
better test program
-rw-r--r--tests/parallel/tptr_to_ref.nim53
1 files changed, 49 insertions, 4 deletions
diff --git a/tests/parallel/tptr_to_ref.nim b/tests/parallel/tptr_to_ref.nim
index 66d618481..229c247ce 100644
--- a/tests/parallel/tptr_to_ref.nim
+++ b/tests/parallel/tptr_to_ref.nim
@@ -1,21 +1,26 @@
 # bug #2854
 
+# Test case for the compiler correctly detecting if a type used by a shared
+# global is gcsafe.
+
 import locks, threadpool, osproc
 
-const MAX_WORKERS = 10
+const MAX_WORKERS = 50
 
 type
-  Killer = object
-    lock: Lock
-    bailed {.guard: lock.}: bool
+  Killer* = object
+    lock:                      Lock
+    bailed    {.guard: lock.}: bool
     processes {.guard: lock.}: array[0..MAX_WORKERS-1, foreign ptr Process]
 
+# Hold a lock for a statement.
 template hold(lock: Lock, body: stmt) =
   lock.acquire
   defer: lock.release
   {.locks: [lock].}:
     body
 
+# Return an initialized Killer.
 proc initKiller*(): Killer =
   initLock(result.lock)
   result.lock.hold:
@@ -23,4 +28,44 @@ proc initKiller*(): Killer =
     for i, _ in result.processes:
       result.processes[i] = nil
 
+# Global Killer instance.
 var killer = initKiller()
+
+# remember that a process has been launched, killing it if we have bailed.
+proc launched*(process: foreign ptr Process): int {.gcsafe.} =
+  result = killer.processes.high + 1
+  killer.lock.hold:
+    if killer.bailed:
+      process[].terminate()
+    else:
+      for i, _ in killer.processes:
+        if killer.processes[i] == nil:
+          killer.processes[i] = process
+          result = i
+      assert(result <= killer.processes.high)
+
+
+# A process has been finished with - remove the process from death row.
+# Return true if the process was still present, which will be the
+# case unless we have bailed.
+proc completed*(index: int): bool {.gcsafe.} =
+  result = true
+  if index <= killer.processes.high:
+    killer.lock.hold:
+      result = false
+      if killer.processes[index] != nil:
+        result = true
+        killer.processes[index] = nil
+
+
+# Terminate all the processes killer knows about, doing nothing if
+# already bailed.
+proc bail(): bool {.gcsafe.} =
+  killer.lock.hold:
+    result = not killer.bailed
+    if not killer.bailed:
+      killer.bailed = true
+      for i, process in killer.processes:
+        if process != nil:
+          process[].terminate
+          killer.processes[i] = nil