diff options
author | Araq <rumpf_a@web.de> | 2011-05-16 00:27:47 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2011-05-16 00:27:47 +0200 |
commit | 67a30d837132e8000d1a8b10ce3d32423d149318 (patch) | |
tree | b059b56027b57c45777d15d33e88b3dac9313f14 /lib/system | |
parent | c7b3d828be1bbca81f3576875636ea571e595402 (diff) | |
download | Nim-67a30d837132e8000d1a8b10ce3d32423d149318.tar.gz |
further steps for thread support; bootstrapping should require unzip C sources and ./build.sh
Diffstat (limited to 'lib/system')
-rwxr-xr-x | lib/system/cgprocs.nim | 47 | ||||
-rwxr-xr-x | lib/system/debugger.nim | 40 | ||||
-rwxr-xr-x | lib/system/dyncalls.nim | 5 | ||||
-rwxr-xr-x | lib/system/excpt.nim | 263 | ||||
-rwxr-xr-x | lib/system/gc.nim | 2 | ||||
-rwxr-xr-x | lib/system/hti.nim | 2 | ||||
-rwxr-xr-x | lib/system/systhread.nim | 3 |
7 files changed, 216 insertions, 146 deletions
diff --git a/lib/system/cgprocs.nim b/lib/system/cgprocs.nim index 8509fe3a3..d80747671 100755 --- a/lib/system/cgprocs.nim +++ b/lib/system/cgprocs.nim @@ -23,50 +23,3 @@ proc nimLoadLibraryError(path: string) {.compilerproc, noinline.} proc setStackBottom(theStackBottom: pointer) {.compilerRtl, noinline.} -when false: - # Support for thread local storage: - when defined(windows): - type - TThreadVarSlot {.compilerproc.} = distinct int32 - - proc TlsAlloc(): TThreadVarSlot {. - importc: "TlsAlloc", stdcall, dynlib: "kernel32".} - proc TlsSetValue(dwTlsIndex: TThreadVarSlot, lpTlsValue: pointer) {. - importc: "TlsSetValue", stdcall, dynlib: "kernel32".} - proc TlsGetValue(dwTlsIndex: TThreadVarSlot): pointer {. - importc: "TlsGetValue", stdcall, dynlib: "kernel32".} - - proc ThreadVarAlloc(): TThreadVarSlot {.compilerproc, inline.} = - result = TlsAlloc() - proc ThreadVarSetValue(s: TThreadVarSlot, value: pointer) {. - compilerproc, inline.} = - TlsSetValue(s, value) - proc ThreadVarGetValue(s: TThreadVarSlot): pointer {. - compilerproc, inline.} = - result = TlsGetValue(s) - - else: - type - Tpthread_key {.importc: "pthread_key_t", - header: "<sys/types.h>".} = distinct int - TThreadVarSlot {.compilerproc.} = Tpthread_key - - proc pthread_getspecific(a1: Tpthread_key): pointer {. - importc: "pthread_getspecific", header: "<pthread.h>".} - proc pthread_key_create(a1: ptr Tpthread_key, - destruct: proc (x: pointer) {.noconv.}): int32 {. - importc: "pthread_key_create", header: "<pthread.h>".} - proc pthread_key_delete(a1: Tpthread_key): int32 {. - importc: "pthread_key_delete", header: "<pthread.h>".} - - proc pthread_setspecific(a1: Tpthread_key, a2: pointer): int32 {. - importc: "pthread_setspecific", header: "<pthread.h>".} - - proc ThreadVarAlloc(): TThreadVarSlot {.compilerproc, inline.} = - discard pthread_key_create(addr(result), nil) - proc ThreadVarSetValue(s: TThreadVarSlot, value: pointer) {. - compilerproc, inline.} = - discard pthread_setspecific(s, value) - proc ThreadVarGetValue(s: TThreadVarSlot): pointer {.compilerproc, inline.} = - result = pthread_getspecific(s) - diff --git a/lib/system/debugger.nim b/lib/system/debugger.nim index 01d8bd8a2..2dccd8579 100755 --- a/lib/system/debugger.nim +++ b/lib/system/debugger.nim @@ -85,8 +85,7 @@ proc openAppend(filename: string): TFile = write(result, "----------------------------------------\n") proc dbgRepr(p: pointer, typ: PNimType): string = - var - cl: TReprClosure + var cl: TReprClosure initReprClosure(cl) cl.recDepth = maxDisplayRecDepth # locks for the GC turned out to be a bad idea... @@ -139,8 +138,10 @@ proc dbgShowCurrentProc(dbgFramePointer: PFrame) = write(stdout, "*** endb| (procedure name not available) ***\n") proc dbgShowExecutionPoint() = - write(stdout, "*** endb| " & $framePtr.filename & "(" & $framePtr.line & - ") " & $framePtr.procname & " ***\n") + ThreadGlobals() + write(stdout, "*** endb| " & $(||framePtr).filename & + "(" & $(||framePtr).line & ") " & + $(||framePtr).procname & " ***\n") when defined(windows) or defined(dos) or defined(os2): {.define: FileSystemCaseInsensitive.} @@ -171,9 +172,10 @@ proc fileMatches(c, bp: cstring): bool = return true proc dbgBreakpointReached(line: int): int = + ThreadGlobals() for i in 0..dbgBPlen-1: if line >= dbgBP[i].low and line <= dbgBP[i].high and - fileMatches(framePtr.filename, dbgBP[i].filename): return i + fileMatches((||framePtr).filename, dbgBP[i].filename): return i return -1 proc scanAndAppendWord(src: string, a: var string, start: int): int = @@ -255,6 +257,7 @@ proc hasExt(s: string): bool = return false proc setBreakPoint(s: string, start: int) = + ThreadGlobals() var dbgTemp: string var i = scanWord(s, dbgTemp, start) if i <= start: @@ -269,7 +272,7 @@ proc setBreakPoint(s: string, start: int) = i = scanNumber(s, dbgBP[x].low, i) if dbgBP[x].low == 0: # set to current line: - dbgBP[x].low = framePtr.line + dbgBP[x].low = (||framePtr).line i = scanNumber(s, dbgBP[x].high, i) if dbgBP[x].high == 0: # set to low: dbgBP[x].high = dbgBP[x].low @@ -278,7 +281,7 @@ proc setBreakPoint(s: string, start: int) = if not hasExt(dbgTemp): add(dbgTemp, ".nim") dbgBP[x].filename = dbgTemp else: # use current filename - dbgBP[x].filename = $framePtr.filename + dbgBP[x].filename = $(||framePtr).filename # skip whitespace: while s[i] in {' ', '\t'}: inc(i) if s[i] != '\0': @@ -347,9 +350,10 @@ proc dbgStackFrame(s: string, start: int, currFrame: PExtendedFrame) = proc CommandPrompt() = # if we return from this routine, user code executes again + ThreadGlobals() var again = True - dbgFramePtr = framePtr # for going down and up the stack + dbgFramePtr = ||framePtr # for going down and up the stack dbgDown = 0 # how often we did go down while again: @@ -366,11 +370,11 @@ proc CommandPrompt() = again = false of "n", "next": dbgState = dbStepOver - dbgSkipToFrame = framePtr + dbgSkipToFrame = ||framePtr again = false of "f", "skipcurrent": dbgState = dbSkipCurrent - dbgSkipToFrame = framePtr.prev + dbgSkipToFrame = (||framePtr).prev again = false of "c", "continue": dbgState = dbBreakpoints @@ -401,7 +405,7 @@ proc CommandPrompt() = if dbgDown <= 0: debugOut("[Warning] cannot go up any further ") else: - dbgFramePtr = framePtr + dbgFramePtr = ||framePtr for j in 0 .. dbgDown-2: # BUGFIX dbgFramePtr = dbgFramePtr.prev dec(dbgDown) @@ -442,16 +446,17 @@ proc endbStep() = CommandPrompt() proc checkForBreakpoint() = - var i = dbgBreakpointReached(framePtr.line) + ThreadGlobals() + var i = dbgBreakpointReached((||framePtr).line) if i >= 0: write(stdout, "*** endb| reached ") write(stdout, dbgBP[i].name) write(stdout, " in ") - write(stdout, framePtr.filename) + write(stdout, (||framePtr).filename) write(stdout, "(") - write(stdout, framePtr.line) + write(stdout, (||framePtr).line) write(stdout, ") ") - write(stdout, framePtr.procname) + write(stdout, (||framePtr).procname) write(stdout, " ***\n") CommandPrompt() @@ -482,7 +487,8 @@ proc endb(line: int) {.compilerproc.} = # Thus, it must have as few parameters as possible to keep the # code size small! # Check if we are at an enabled breakpoint or "in the mood" - framePtr.line = line # this is done here for smaller code size! + ThreadGlobals() + (||framePtr).line = line # this is done here for smaller code size! if dbgLineHook != nil: dbgLineHook() case dbgState of dbStepInto: @@ -490,7 +496,7 @@ proc endb(line: int) {.compilerproc.} = dbgShowExecutionPoint() CommandPrompt() of dbSkipCurrent, dbStepOver: # skip current routine - if framePtr == dbgSkipToFrame: + if ||framePtr == dbgSkipToFrame: dbgShowExecutionPoint() CommandPrompt() else: # breakpoints are wanted though (I guess) diff --git a/lib/system/dyncalls.nim b/lib/system/dyncalls.nim index fb1130938..447ce3f95 100755 --- a/lib/system/dyncalls.nim +++ b/lib/system/dyncalls.nim @@ -12,6 +12,8 @@ # However, the interface has been designed to take platform differences into # account and been ported to all major platforms. +{.push stack_trace: off.} + const NilLibHandle: TLibHandle = nil @@ -135,3 +137,6 @@ elif defined(mac): else: {.error: "no implementation for dyncalls".} + +{.pop.} + diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index ed2ec7ff0..9bdc69569 100755 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -13,6 +13,7 @@ var stackTraceNewLine* = "\n" ## undocumented feature; it is replaced by ``<br>`` ## for CGI applications + isMultiThreaded: bool # true when prog created at least 1 thread when not defined(windows) or not defined(guiapp): proc writeToStdErr(msg: CString) = write(stdout, msg) @@ -36,30 +37,139 @@ type TSafePoint {.compilerproc, final.} = object prev: PSafePoint # points to next safe point ON THE STACK status: int - exc: ref E_Base # XXX only needed for bootstrapping; unused context: C_JmpBuf -#when hasThreadSupport: nil +when hasThreadSupport: + # Support for thread local storage: + when defined(windows): + type + TThreadVarSlot {.compilerproc.} = distinct int32 + + proc TlsAlloc(): TThreadVarSlot {. + importc: "TlsAlloc", stdcall, dynlib: "kernel32".} + proc TlsSetValue(dwTlsIndex: TThreadVarSlot, lpTlsValue: pointer) {. + importc: "TlsSetValue", stdcall, dynlib: "kernel32".} + proc TlsGetValue(dwTlsIndex: TThreadVarSlot): pointer {. + importc: "TlsGetValue", stdcall, dynlib: "kernel32".} + + proc ThreadVarAlloc(): TThreadVarSlot {.compilerproc, inline.} = + result = TlsAlloc() + proc ThreadVarSetValue(s: TThreadVarSlot, value: pointer) {. + compilerproc, inline.} = + TlsSetValue(s, value) + proc ThreadVarGetValue(s: TThreadVarSlot): pointer {. + compilerproc, inline.} = + result = TlsGetValue(s) + + else: + {.passL: "-pthread".} + {.passC: "-pthread".} + + type + Tpthread_key {.importc: "pthread_key_t", + header: "<sys/types.h>".} = distinct int + TThreadVarSlot {.compilerproc.} = Tpthread_key + + proc pthread_getspecific(a1: Tpthread_key): pointer {. + importc: "pthread_getspecific", header: "<pthread.h>".} + proc pthread_key_create(a1: ptr Tpthread_key, + destruct: proc (x: pointer) {.noconv.}): int32 {. + importc: "pthread_key_create", header: "<pthread.h>".} + proc pthread_key_delete(a1: Tpthread_key): int32 {. + importc: "pthread_key_delete", header: "<pthread.h>".} + + proc pthread_setspecific(a1: Tpthread_key, a2: pointer): int32 {. + importc: "pthread_setspecific", header: "<pthread.h>".} + + proc specificDestroy(mem: pointer) {.noconv.} = dealloc(mem) + + proc ThreadVarAlloc(): TThreadVarSlot {.compilerproc, inline.} = + discard pthread_key_create(addr(result), specificDestroy) + proc ThreadVarSetValue(s: TThreadVarSlot, value: pointer) {. + compilerproc, inline.} = + discard pthread_setspecific(s, value) + proc ThreadVarGetValue(s: TThreadVarSlot): pointer {.compilerproc, inline.} = + result = pthread_getspecific(s) + + type + TGlobals {.final, pure.} = object + excHandler: PSafePoint + currException: ref E_Base + framePtr: PFrame + 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 + gAssertionFailed: ref EAssertionFailed + tempFrames: array [0..127, PFrame] # cannot be allocated on the stack! + data: float # compiler should add thread local variables here! + PGlobals = ptr TGlobals + + var globalsSlot = ThreadVarAlloc() + proc CreateThreadLocalStorage*() {.inl.} = + isMultiThreaded = true + ThreadVarSetValue(globalsSlot, alloc0(sizeof(TGlobals))) + + proc GetGlobals(): PGlobals {.compilerRtl, inl.} = + result = cast[PGlobals](ThreadVarGetValue(globalsSlot)) + + # create for the main thread: + ThreadVarSetValue(globalsSlot, alloc0(sizeof(TGlobals))) + +when hasThreadSupport: + template ThreadGlobals = + var globals = GetGlobals() + template `||`(varname: expr): expr = globals.varname + + ThreadGlobals() +else: + template ThreadGlobals = nil # nothing + template `||`(varname: expr): expr = varname -var - excHandler {.threadvar, compilerproc.}: PSafePoint = nil - # list of exception handlers - # a global variable for the root of all try blocks - currException {.threadvar.}: ref E_Base + var + framePtr {.compilerproc.}: PFrame # XXX only temporarily a compilerproc + excHandler: PSafePoint = nil + # list of exception handlers + # a global variable for the root of all try blocks + currException: ref E_Base + + 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 + tempFrames: array [0..127, PFrame] # cannot be allocated on the stack! + gAssertionFailed: ref EAssertionFailed + +proc pushFrame(s: PFrame) {.compilerRtl, inl.} = + ThreadGlobals() + s.prev = ||framePtr + ||framePtr = s + +proc popFrame {.compilerRtl, inl.} = + ThreadGlobals() + ||framePtr = (||framePtr).prev + +proc setFrame(s: PFrame) {.compilerRtl, inl.} = + ThreadGlobals() + ||framePtr = s proc pushSafePoint(s: PSafePoint) {.compilerRtl, inl.} = - s.prev = excHandler - excHandler = s + ThreadGlobals() + s.prev = ||excHandler + ||excHandler = s proc popSafePoint {.compilerRtl, inl.} = - excHandler = excHandler.prev + ThreadGlobals() + ||excHandler = (||excHandler).prev proc pushCurrentException(e: ref E_Base) {.compilerRtl, inl.} = - e.parent = currException - currException = e + ThreadGlobals() + e.parent = ||currException + ||currException = e proc popCurrentException {.compilerRtl, inl.} = - currException = currException.parent + ThreadGlobals() + ||currException = (||currException).parent # some platforms have native support for stack traces: const @@ -80,11 +190,16 @@ when defined(nativeStacktrace) and nativeStackTraceSupported: proc dladdr(addr1: pointer, info: ptr TDl_info): int {. importc: "dladdr", header: "<dlfcn.h>".} - var - tempAddresses: array [0..127, pointer] # cannot be allocated on the stack! - tempDlInfo: TDl_info + when not hasThreadSupport: + var + tempAddresses: array [0..127, pointer] # should not be alloc'd on stack + tempDlInfo: TDl_info proc auxWriteStackTraceWithBacktrace(s: var string) = + when hasThreadSupport: + var + tempAddresses: array [0..127, pointer] # but better than a threadvar + tempDlInfo: TDl_info # This is allowed to be expensive since it only happens during crashes # (but this way you don't need manual stack tracing) var size = backtrace(cast[ptr pointer](addr(tempAddresses)), @@ -108,24 +223,18 @@ when defined(nativeStacktrace) and nativeStackTraceSupported: # Once we're past signalHandler, we're at what the user is # interested in enabled = true - -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 - tempFrames: array [0..127, PFrame] # cannot be allocated on the stack! proc auxWriteStackTrace(f: PFrame, s: var string) = const firstCalls = 32 + ThreadGlobals() var it = f i = 0 total = 0 - while it != nil and i <= high(tempFrames)-(firstCalls-1): + while it != nil and i <= high(||tempFrames)-(firstCalls-1): # the (-1) is for a nil entry that marks where the '...' should occur - tempFrames[i] = it + (||tempFrames)[i] = it inc(i) inc(total) it = it.prev @@ -136,37 +245,38 @@ proc auxWriteStackTrace(f: PFrame, s: var string) = for j in 1..total-i-(firstCalls-1): if b != nil: b = b.prev if total != i: - tempFrames[i] = nil + (||tempFrames)[i] = nil inc(i) - while b != nil and i <= high(tempFrames): - tempFrames[i] = b + while b != nil and i <= high(||tempFrames): + (||tempFrames)[i] = b inc(i) b = b.prev for j in countdown(i-1, 0): - if tempFrames[j] == nil: + if (||tempFrames)[j] == nil: add(s, "(") add(s, $(total-i-1)) add(s, " calls omitted) ...") else: var oldLen = s.len - add(s, tempFrames[j].filename) - if tempFrames[j].line > 0: + add(s, (||tempFrames)[j].filename) + if (||tempFrames)[j].line > 0: add(s, '(') - add(s, $tempFrames[j].line) + add(s, $(||tempFrames)[j].line) add(s, ')') for k in 1..max(1, 25-(s.len-oldLen)): add(s, ' ') - add(s, tempFrames[j].procname) + add(s, (||tempFrames)[j].procname) add(s, stackTraceNewLine) proc rawWriteStackTrace(s: var string) = when nimrodStackTrace: - if framePtr == nil: + ThreadGlobals() + if ||framePtr == nil: add(s, "No stack traceback available") add(s, stackTraceNewLine) else: add(s, "Traceback (most recent call last)") add(s, stackTraceNewLine) - auxWriteStackTrace(framePtr, s) + auxWriteStackTrace(||framePtr, s) elif defined(nativeStackTrace) and nativeStackTraceSupported: add(s, "Traceback from system (most recent call last)") add(s, stackTraceNewLine) @@ -184,53 +294,53 @@ proc quitOrDebug() {.inline.} = proc raiseException(e: ref E_Base, ename: CString) {.compilerRtl.} = GC_disable() # a bad thing is an error in the GC while raising an exception e.name = ename - if excHandler != nil: + ThreadGlobals() + if ||excHandler != nil: pushCurrentException(e) - c_longjmp(excHandler.context, 1) + c_longjmp((||excHandler).context, 1) else: - if not isNil(buf): - setLen(buf, 0) - rawWriteStackTrace(buf) + if not isNil(||buf): + setLen(||buf, 0) + rawWriteStackTrace(||buf) if e.msg != nil and e.msg[0] != '\0': - add(buf, "Error: unhandled exception: ") - add(buf, $e.msg) + add(||buf, "Error: unhandled exception: ") + add(||buf, $e.msg) else: - add(buf, "Error: unhandled exception") - add(buf, " [") - add(buf, $ename) - add(buf, "]\n") - writeToStdErr(buf) + add(||buf, "Error: unhandled exception") + add(||buf, " [") + add(||buf, $ename) + add(||buf, "]\n") + writeToStdErr(||buf) else: writeToStdErr(ename) quitOrDebug() GC_enable() proc reraiseException() {.compilerRtl.} = - if currException == nil: + ThreadGlobals() + if ||currException == nil: raise newException(ENoExceptionToReraise, "no exception to reraise") else: - raiseException(currException, currException.name) - -var - gAssertionFailed: ref EAssertionFailed + raiseException(||currException, (||currException).name) proc internalAssert(file: cstring, line: int, cond: bool) {.compilerproc.} = if not cond: + ThreadGlobals() #c_fprintf(c_stdout, "Assertion failure: file %s line %ld\n", file, line) #quit(1) GC_disable() # BUGFIX: `$` allocates a new string object! - if not isNil(assertBuf): + if not isNil(||assertBuf): # BUGFIX: when debugging the GC, assertBuf may be nil - setLen(assertBuf, 0) - add(assertBuf, "[Assertion failure] file: ") - add(assertBuf, file) - add(assertBuf, " line: ") - add(assertBuf, $line) - add(assertBuf, "\n") - gAssertionFailed.msg = assertBuf + setLen(||assertBuf, 0) + add(||assertBuf, "[Assertion failure] file: ") + add(||assertBuf, file) + add(||assertBuf, " line: ") + add(||assertBuf, $line) + add(||assertBuf, "\n") + (||gAssertionFailed).msg = ||assertBuf GC_enable() - if gAssertionFailed != nil: - raise gAssertionFailed + if ||gAssertionFailed != nil: + raise ||gAssertionFailed else: c_fprintf(c_stdout, "Assertion failure: file %s line %ld\n", file, line) quit(1) @@ -245,23 +355,24 @@ var proc signalHandler(sig: cint) {.exportc: "signalHandler", noconv.} = # print stack trace and quit + ThreadGlobals() var s = sig GC_disable() - setLen(buf, 0) - rawWriteStackTrace(buf) + setLen(||buf, 0) + rawWriteStackTrace(||buf) - if s == SIGINT: add(buf, "SIGINT: Interrupted by Ctrl-C.\n") + if s == SIGINT: add(||buf, "SIGINT: Interrupted by Ctrl-C.\n") elif s == SIGSEGV: - add(buf, "SIGSEGV: Illegal storage access. (Attempt to read from nil?)\n") + add(||buf, "SIGSEGV: Illegal storage access. (Attempt to read from nil?)\n") elif s == SIGABRT: if dbgAborting: return # the debugger wants to abort - add(buf, "SIGABRT: Abnormal termination.\n") - elif s == SIGFPE: add(buf, "SIGFPE: Arithmetic error.\n") - elif s == SIGILL: add(buf, "SIGILL: Illegal operation.\n") + add(||buf, "SIGABRT: Abnormal termination.\n") + elif s == SIGFPE: add(||buf, "SIGFPE: Arithmetic error.\n") + elif s == SIGILL: add(||buf, "SIGILL: Illegal operation.\n") elif s == SIGBUS: - add(buf, "SIGBUS: Illegal storage access. (Attempt to read from nil?)\n") - else: add(buf, "unknown signal\n") - writeToStdErr(buf) + add(||buf, "SIGBUS: Illegal storage access. (Attempt to read from nil?)\n") + else: add(||buf, "unknown signal\n") + writeToStdErr(||buf) dbgAborting = True # play safe here... GC_enable() quit(1) # always quit when SIGABRT @@ -278,11 +389,9 @@ when not defined(noSignalHandler): registerSignalHandler() # call it in initialization section # for easier debugging of the GC, this memory is only allocated after the # signal handlers have been registered -new(gAssertionFailed) -buf = newString(2048) -assertBuf = newString(2048) -setLen(buf, 0) -setLen(assertBuf, 0) +new(||gAssertionFailed) +||buf = newStringOfCap(2000) +||assertBuf = newStringOfCap(2000) proc raiseRangeError(val: biggestInt) {.compilerproc, noreturn, noinline.} = raise newException(EOutOfRange, "value " & $val & " out of range") diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 7c70ccf85..52de66d48 100755 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -391,7 +391,7 @@ proc newObj(typ: PNimType, size: int): pointer {.compilerRtl.} = assert((cast[TAddress](res) and (MemAlign-1)) == 0) # now it is buffered in the ZCT res.typ = typ - when debugGC: + when debugGC and not hasThreadSupport: if framePtr != nil and framePtr.prev != nil: res.filename = framePtr.prev.filename res.line = framePtr.prev.line diff --git a/lib/system/hti.nim b/lib/system/hti.nim index d22109061..c6ea0bc44 100755 --- a/lib/system/hti.nim +++ b/lib/system/hti.nim @@ -1,7 +1,7 @@ # # # Nimrod's Runtime Library -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. diff --git a/lib/system/systhread.nim b/lib/system/systhread.nim index fa2d75704..d9b340ce2 100755 --- a/lib/system/systhread.nim +++ b/lib/system/systhread.nim @@ -23,9 +23,6 @@ else: inc(p, val) result = p -var - isMultiThreaded: bool # true when prog created at least 1 thread - proc atomicInc(memLoc: var int, x: int): int = when hasThreadSupport: result = sync_add_and_fetch(memLoc, x) |