basic thread support; still broken on Windows; untested on Mac OS X
This commit is contained in:
parent
0f743e0183
commit
66cfc851a1
17 changed files with 521 additions and 127 deletions
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2010 Andreas Rumpf
|
||||
# (c) Copyright 2011 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
|
|
@ -40,10 +40,10 @@ type
|
|||
context: C_JmpBuf
|
||||
|
||||
var
|
||||
excHandler {.compilerproc.}: PSafePoint = nil
|
||||
excHandler {.threadvar, compilerproc.}: PSafePoint = nil
|
||||
# list of exception handlers
|
||||
# a global variable for the root of all try blocks
|
||||
currException: ref E_Base
|
||||
currException {.threadvar.}: ref E_Base
|
||||
|
||||
proc pushSafePoint(s: PSafePoint) {.compilerRtl, inl.} =
|
||||
s.prev = excHandler
|
||||
|
|
@ -107,23 +107,11 @@ when nativeStacktrace:
|
|||
# interested in
|
||||
enabled = true
|
||||
|
||||
type
|
||||
PFrame = ptr TFrame
|
||||
TFrame {.importc, nodecl, final.} = object
|
||||
prev: PFrame
|
||||
procname: CString
|
||||
line: int # current line number
|
||||
filename: CString
|
||||
len: int # length of slots (when not debugging always zero)
|
||||
|
||||
var
|
||||
buf: string # cannot be allocated on the stack!
|
||||
assertBuf: string # we need a different buffer for
|
||||
# assert, as it raises an exception and
|
||||
# exception handler needs the buffer too
|
||||
|
||||
framePtr {.exportc.}: PFrame
|
||||
|
||||
tempFrames: array [0..127, PFrame] # cannot be allocated on the stack!
|
||||
|
||||
proc auxWriteStackTrace(f: PFrame, s: var string) =
|
||||
|
|
|
|||
|
|
@ -61,8 +61,9 @@ type
|
|||
decStack: TCellSeq # cells in the stack that are to decref again
|
||||
cycleRoots: TCellSet
|
||||
tempStack: TCellSeq # temporary stack for recursion elimination
|
||||
cycleRootsLock: TSysLock
|
||||
zctLock: TSysLock
|
||||
when hasThreadSupport:
|
||||
cycleRootsLock: TSysLock
|
||||
zctLock: TSysLock
|
||||
stat: TGcStat
|
||||
|
||||
var
|
||||
|
|
@ -281,8 +282,9 @@ proc initGC() =
|
|||
init(gch.tempStack)
|
||||
Init(gch.cycleRoots)
|
||||
Init(gch.decStack)
|
||||
InitLock(gch.cycleRootsLock)
|
||||
InitLock(gch.zctLock)
|
||||
when hasThreadSupport:
|
||||
InitLock(gch.cycleRootsLock)
|
||||
InitLock(gch.zctLock)
|
||||
new(gOutOfMem) # reserve space for the EOutOfMemory exception here!
|
||||
|
||||
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) =
|
||||
|
|
|
|||
|
|
@ -44,83 +44,4 @@ proc atomicDec(memLoc: var int, x: int): int =
|
|||
else:
|
||||
dec(memLoc, x)
|
||||
result = memLoc
|
||||
|
||||
when defined(Windows):
|
||||
type
|
||||
THandle = int
|
||||
TSysThread = THandle
|
||||
TSysLock {.final, pure.} = object # CRITICAL_SECTION in WinApi
|
||||
DebugInfo: pointer
|
||||
LockCount: int32
|
||||
RecursionCount: int32
|
||||
OwningThread: int
|
||||
LockSemaphore: int
|
||||
Reserved: int32
|
||||
|
||||
proc InitLock(L: var TSysLock) {.stdcall,
|
||||
dynlib: "kernel32", importc: "InitializeCriticalSection".}
|
||||
proc Aquire(L: var TSysLock) {.stdcall,
|
||||
dynlib: "kernel32", importc: "EnterCriticalSection".}
|
||||
proc Release(L: var TSysLock) {.stdcall,
|
||||
dynlib: "kernel32", importc: "LeaveCriticalSection".}
|
||||
|
||||
proc CreateThread(lpThreadAttributes: Pointer, dwStackSize: int32,
|
||||
lpStartAddress: pointer, lpParameter: Pointer,
|
||||
dwCreationFlags: int32, lpThreadId: var int32): THandle {.
|
||||
stdcall, dynlib: "kernel32", importc: "CreateThread".}
|
||||
|
||||
proc winSuspendThread(hThread: TSysThread): int32 {.
|
||||
stdcall, dynlib: "kernel32", importc: "SuspendThread".}
|
||||
|
||||
proc winResumeThread(hThread: TSysThread): int32 {.
|
||||
stdcall, dynlib: "kernel32", importc: "ResumeThread".}
|
||||
|
||||
proc WaitForMultipleObjects(nCount: int32,
|
||||
lpHandles: ptr array[0..10, THandle],
|
||||
bWaitAll: int32,
|
||||
dwMilliseconds: int32): int32 {.
|
||||
stdcall, dynlib: "kernel32", importc: "WaitForMultipleObjects".}
|
||||
|
||||
proc WaitForSingleObject(hHandle: THANDLE, dwMilliseconds: int32): int32 {.
|
||||
stdcall, dynlib: "kernel32", importc: "WaitForSingleObject".}
|
||||
|
||||
else:
|
||||
type
|
||||
TSysLock {.importc: "pthread_mutex_t", header: "<sys/types.h>".} = int
|
||||
TSysThread {.importc: "pthread_t", header: "<sys/types.h>".} = int
|
||||
|
||||
proc InitLock(L: var TSysLock, attr: pointer = nil) {.
|
||||
importc: "pthread_mutex_init", header: "<pthread.h>".}
|
||||
proc Aquire(L: var TSysLock) {.
|
||||
importc: "pthread_mutex_lock", header: "<pthread.h>".}
|
||||
proc Release(L: var TSysLock) {.
|
||||
importc: "pthread_mutex_unlock", header: "<pthread.h>".}
|
||||
|
||||
proc pthread_create(a1: ptr TSysThread, a2: ptr int,
|
||||
a3: proc (x: pointer): pointer {.noconv.},
|
||||
a4: pointer): cint {.importc: "pthread_create",
|
||||
header: "<pthread.h>".}
|
||||
proc pthread_join(a1: TSysThread, a2: ptr pointer): cint {.
|
||||
importc, header: "<pthread.h>".}
|
||||
|
||||
|
||||
type
|
||||
TThread* = TSysThread
|
||||
TLock* = TSysLock
|
||||
TThreadFunc* = proc (closure: pointer) {.cdecl.}
|
||||
|
||||
proc createThread*(t: var TThread, fn: TThreadFunc, closure: pointer) =
|
||||
when defined(windows):
|
||||
nil
|
||||
else:
|
||||
nil
|
||||
#pthread_create(
|
||||
|
||||
proc joinThread*(t: TThread) =
|
||||
nil
|
||||
|
||||
#proc pthread_exit(void *value_ptr)
|
||||
|
||||
proc destroyThread*(t: var TThread) =
|
||||
nil
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue