diff options
author | Araq <rumpf_a@web.de> | 2015-06-11 15:17:28 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2015-06-14 22:51:29 +0200 |
commit | 1452edfbb9d7de1d654248cc709a7436d8d404c2 (patch) | |
tree | e378dfb8f190dd4e52dd52d6fa36876a2ade1b7b | |
parent | 69f2b67b5ed9c992d180b37bb9c3e92ba2eb78c2 (diff) | |
download | Nim-1452edfbb9d7de1d654248cc709a7436d8d404c2.tar.gz |
better test program
-rw-r--r-- | tests/parallel/tptr_to_ref.nim | 53 |
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 |