From 9b460a71cef95cea944d637b7e8bb6c785317a34 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 17 May 2011 23:43:46 +0200 Subject: [PATCH] threads with --gc:boehm may work now :-) --- lib/core/threads.nim | 88 +++++++++++++++++++++----------------------- lib/system/excpt.nim | 9 ++--- 2 files changed, 46 insertions(+), 51 deletions(-) diff --git a/lib/core/threads.nim b/lib/core/threads.nim index ff33394d83..f6ebb40dd7 100755 --- a/lib/core/threads.nim +++ b/lib/core/threads.nim @@ -130,7 +130,6 @@ else: type TThread* {.pure, final.}[TParam] = object ## Nimrod thread. sys: TSysThread - globals: pointer # this allows the GC to track thread local storage! c: TThreadProcClosure[TParam] when nodeadlocks: @@ -251,7 +250,7 @@ proc createThread*[TParam](t: var TThread[TParam], param: TParam) = ## creates a new thread `t` and starts its execution. Entry point is the ## proc `tp`. `param` is passed to `tp`. - t.globals = AllocThreadLocalStorage() + t.c.threadLocalStorage = AllocThreadLocalStorage() t.c.data = param t.c.fn = tp when hostOS == "windows": @@ -271,55 +270,52 @@ when isMainModule: proc doNothing() = nil - {.push stack_trace:off.} proc threadFunc(interval: tuple[a,b: int]) {.procvar.} = doNothing() - when false: - for i in interval.a..interval.b: - when nodeadlocks: - case i mod 6 - of 0: - Aquire(L) # lock stdout - Aquire(M) - Aquire(N) - of 1: - Aquire(L) - Aquire(N) # lock stdout - Aquire(M) - of 2: - Aquire(M) - Aquire(L) - Aquire(N) - of 3: - Aquire(M) - Aquire(N) - Aquire(L) - of 4: - Aquire(N) - Aquire(M) - Aquire(L) - of 5: - Aquire(N) - Aquire(L) - Aquire(M) - else: assert false - else: + for i in interval.a..interval.b: + when nodeadlocks: + case i mod 6 + of 0: Aquire(L) # lock stdout Aquire(M) Aquire(N) - - #echo i - os.sleep(10) - stdout.write(i) - when nodeadlocks: - echo "deadlocks prevented: ", deadlocksPrevented - Release(L) - Release(M) - Release(N) - {.pop.} - #InitLock(L) - #InitLock(M) - #InitLock(N) + of 1: + Aquire(L) + Aquire(N) # lock stdout + Aquire(M) + of 2: + Aquire(M) + Aquire(L) + Aquire(N) + of 3: + Aquire(M) + Aquire(N) + Aquire(L) + of 4: + Aquire(N) + Aquire(M) + Aquire(L) + of 5: + Aquire(N) + Aquire(L) + Aquire(M) + else: assert false + else: + Aquire(L) # lock stdout + Aquire(M) + Aquire(N) + + echo i + os.sleep(10) + when nodeadlocks: + echo "deadlocks prevented: ", deadlocksPrevented + Release(L) + Release(M) + Release(N) + + InitLock(L) + InitLock(M) + InitLock(N) proc main = for i in 0..high(thr): diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index dac5678e0b..01604b2c98 100755 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -67,7 +67,7 @@ when hasThreadSupport: type Tpthread_key {.importc: "pthread_key_t", - header: "".} = distinct int + header: "".} = distinct int32 TThreadVarSlot {.compilerproc.} = Tpthread_key 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 # slot, but to rely on the implementation to assign slot 0 for us... ;-) - var checkSlot = ThreadVarAlloc() - const globalsSlot = TThreadVarSlot(0) - assert checkSlot.int == globalsSlot.int + var globalsSlot = ThreadVarAlloc() + #const globalsSlot = TThreadVarSlot(0) + #assert checkSlot.int == globalsSlot.int proc AtomicAlloc0(size: int): pointer = #AquireSys(heapLock) @@ -145,7 +145,6 @@ when hasThreadSupport: var globals = GetGlobals() template `||`(varname: expr): expr = globals.varname - #ThreadGlobals() else: template ThreadGlobals = nil # nothing template `||`(varname: expr): expr = varname