mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
better test program
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user