threads with --gc:boehm may work now :-)

This commit is contained in:
Araq 2011-05-17 23:43:46 +02:00
commit 9b460a71ce
2 changed files with 46 additions and 51 deletions

View file

@ -130,7 +130,6 @@ else:
type type
TThread* {.pure, final.}[TParam] = object ## Nimrod thread. TThread* {.pure, final.}[TParam] = object ## Nimrod thread.
sys: TSysThread sys: TSysThread
globals: pointer # this allows the GC to track thread local storage!
c: TThreadProcClosure[TParam] c: TThreadProcClosure[TParam]
when nodeadlocks: when nodeadlocks:
@ -251,7 +250,7 @@ proc createThread*[TParam](t: var TThread[TParam],
param: TParam) = param: TParam) =
## creates a new thread `t` and starts its execution. Entry point is the ## creates a new thread `t` and starts its execution. Entry point is the
## proc `tp`. `param` is passed to `tp`. ## proc `tp`. `param` is passed to `tp`.
t.globals = AllocThreadLocalStorage() t.c.threadLocalStorage = AllocThreadLocalStorage()
t.c.data = param t.c.data = param
t.c.fn = tp t.c.fn = tp
when hostOS == "windows": when hostOS == "windows":
@ -271,10 +270,8 @@ when isMainModule:
proc doNothing() = nil proc doNothing() = nil
{.push stack_trace:off.}
proc threadFunc(interval: tuple[a,b: int]) {.procvar.} = proc threadFunc(interval: tuple[a,b: int]) {.procvar.} =
doNothing() doNothing()
when false:
for i in interval.a..interval.b: for i in interval.a..interval.b:
when nodeadlocks: when nodeadlocks:
case i mod 6 case i mod 6
@ -308,18 +305,17 @@ when isMainModule:
Aquire(M) Aquire(M)
Aquire(N) Aquire(N)
#echo i echo i
os.sleep(10) os.sleep(10)
stdout.write(i)
when nodeadlocks: when nodeadlocks:
echo "deadlocks prevented: ", deadlocksPrevented echo "deadlocks prevented: ", deadlocksPrevented
Release(L) Release(L)
Release(M) Release(M)
Release(N) Release(N)
{.pop.}
#InitLock(L) InitLock(L)
#InitLock(M) InitLock(M)
#InitLock(N) InitLock(N)
proc main = proc main =
for i in 0..high(thr): for i in 0..high(thr):

View file

@ -67,7 +67,7 @@ when hasThreadSupport:
type type
Tpthread_key {.importc: "pthread_key_t", Tpthread_key {.importc: "pthread_key_t",
header: "<sys/types.h>".} = distinct int header: "<sys/types.h>".} = distinct int32
TThreadVarSlot {.compilerproc.} = Tpthread_key TThreadVarSlot {.compilerproc.} = Tpthread_key
proc pthread_getspecific(a1: Tpthread_key): pointer {. proc pthread_getspecific(a1: Tpthread_key): pointer {.
@ -111,9 +111,9 @@ when hasThreadSupport:
# it's more efficient to not use a global variable for the thread storage # it's more efficient to not use a global variable for the thread storage
# slot, but to rely on the implementation to assign slot 0 for us... ;-) # slot, but to rely on the implementation to assign slot 0 for us... ;-)
var checkSlot = ThreadVarAlloc() var globalsSlot = ThreadVarAlloc()
const globalsSlot = TThreadVarSlot(0) #const globalsSlot = TThreadVarSlot(0)
assert checkSlot.int == globalsSlot.int #assert checkSlot.int == globalsSlot.int
proc AtomicAlloc0(size: int): pointer = proc AtomicAlloc0(size: int): pointer =
#AquireSys(heapLock) #AquireSys(heapLock)
@ -145,7 +145,6 @@ when hasThreadSupport:
var globals = GetGlobals() var globals = GetGlobals()
template `||`(varname: expr): expr = globals.varname template `||`(varname: expr): expr = globals.varname
#ThreadGlobals()
else: else:
template ThreadGlobals = nil # nothing template ThreadGlobals = nil # nothing
template `||`(varname: expr): expr = varname template `||`(varname: expr): expr = varname