diff options
author | Araq <rumpf_a@web.de> | 2010-09-19 21:35:44 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2010-09-19 21:35:44 +0200 |
commit | 93b3c03dbd104786a2aaa46f924e1c2c479c1fa1 (patch) | |
tree | cd95778c0581a2c0897b41269db2be08ec3db982 /lib/system | |
parent | c06569459819a2aba1a287c7f38904c40c5152d4 (diff) | |
download | Nim-93b3c03dbd104786a2aaa46f924e1c2c479c1fa1.tar.gz |
threading code deactivated; tiny C bugfix: don't report warnings to error callback
Diffstat (limited to 'lib/system')
-rwxr-xr-x | lib/system/ecmasys.nim | 77 | ||||
-rwxr-xr-x | lib/system/excpt.nim | 72 | ||||
-rwxr-xr-x | lib/system/gc.nim | 28 | ||||
-rwxr-xr-x | lib/system/systhread.nim | 21 |
4 files changed, 119 insertions, 79 deletions
diff --git a/lib/system/ecmasys.nim b/lib/system/ecmasys.nim index c0d0a5fd6..e2ecb370a 100755 --- a/lib/system/ecmasys.nim +++ b/lib/system/ecmasys.nim @@ -1,26 +1,12 @@ # # # Nimrod's Runtime Library -# (c) Copyright 2008 Andreas Rumpf +# (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # -## Stubs for the GC interface: - -proc GC_disable() = nil -proc GC_enable() = nil -proc GC_fullCollect() = nil -proc GC_setStrategy(strategy: TGC_Strategy) = nil -proc GC_enableMarkAndSweep() = nil -proc GC_disableMarkAndSweep() = nil -proc GC_getStatistics(): string = return "" - -proc getOccupiedMem(): int = return -1 -proc getFreeMem(): int = return -1 -proc getTotalMem(): int = return -1 - proc alert(s: cstring) {.importc, nodecl.} type @@ -130,8 +116,6 @@ proc raiseIndexError() {.compilerproc, noreturn.} = proc raiseFieldError(f: string) {.compilerproc, noreturn.} = raise newException(EInvalidField, f & " is not accessible") - - proc SetConstr() {.varargs, pure, compilerproc.} = asm """ var result = {}; @@ -317,61 +301,58 @@ proc ewriteln(x: cstring) = else: raise newException(EInvalidValue, "<body> element does not exist yet!") -proc echo*(x: int) = ewriteln($x) -proc echo*(x: float) = ewriteln($x) -proc echo*(x: bool) = ewriteln(if x: cstring("true") else: cstring("false")) -proc echo*(x: string) = ewriteln(x) -proc echo*(x: cstring) = ewriteln(x) - -proc echo[Ty](x: Ty) = - echo(x) - -proc echo[Ty](x: openArray[Ty]) = - for a in items(x): echo(a) +proc rawEcho {.compilerproc.} = + var node = document.getElementsByTagName("body")[0] + if node == nil: raise newException(EIO, "<body> element does not exist yet!") + asm """ + for (var i = 0; i < arguments.length; ++i) { + var x = `toEcmaStr`(arguments[i]); + `node`.appendChild(document.createTextNode(x)) + } + """ + node.appendChild(document.createElement("br")) # Arithmetic: proc addInt(a, b: int): int {.pure, compilerproc.} = asm """ var result = `a` + `b`; - if (result > 2147483647 || result < -2147483648) raiseOverflow(); + if (result > 2147483647 || result < -2147483648) `raiseOverflow`(); return result; """ proc subInt(a, b: int): int {.pure, compilerproc.} = asm """ var result = `a` - `b`; - if (result > 2147483647 || result < -2147483648) raiseOverflow(); + if (result > 2147483647 || result < -2147483648) `raiseOverflow`(); return result; """ proc mulInt(a, b: int): int {.pure, compilerproc.} = asm """ var result = `a` * `b`; - if (result > 2147483647 || result < -2147483648) raiseOverflow(); + if (result > 2147483647 || result < -2147483648) `raiseOverflow`(); return result; """ proc divInt(a, b: int): int {.pure, compilerproc.} = asm """ - if (`b` == 0) raiseDivByZero(); - if (`b` == -1 && `a` == 2147483647) raiseOverflow(); + if (`b` == 0) `raiseDivByZero`(); + if (`b` == -1 && `a` == 2147483647) `raiseOverflow`(); return Math.floor(`a` / `b`); """ proc modInt(a, b: int): int {.pure, compilerproc.} = asm """ - if (`b` == 0) raiseDivByZero(); - if (`b` == -1 && `a` == 2147483647) raiseOverflow(); + if (`b` == 0) `raiseDivByZero`(); + if (`b` == -1 && `a` == 2147483647) `raiseOverflow`(); return Math.floor(`a` % `b`); """ - - proc addInt64(a, b: int): int {.pure, compilerproc.} = asm """ var result = `a` + `b`; if (result > 9223372036854775807 - || result < -9223372036854775808) raiseOverflow(); + || result < -9223372036854775808) `raiseOverflow`(); return result; """ @@ -379,7 +360,7 @@ proc subInt64(a, b: int): int {.pure, compilerproc.} = asm """ var result = `a` - `b`; if (result > 9223372036854775807 - || result < -9223372036854775808) raiseOverflow(); + || result < -9223372036854775808) `raiseOverflow`(); return result; """ @@ -387,21 +368,21 @@ proc mulInt64(a, b: int): int {.pure, compilerproc.} = asm """ var result = `a` * `b`; if (result > 9223372036854775807 - || result < -9223372036854775808) raiseOverflow(); + || result < -9223372036854775808) `raiseOverflow`(); return result; """ proc divInt64(a, b: int): int {.pure, compilerproc.} = asm """ - if (`b` == 0) raiseDivByZero(); - if (`b` == -1 && `a` == 9223372036854775807) raiseOverflow(); + if (`b` == 0) `raiseDivByZero`(); + if (`b` == -1 && `a` == 9223372036854775807) `raiseOverflow`(); return Math.floor(`a` / `b`); """ proc modInt64(a, b: int): int {.pure, compilerproc.} = asm """ - if (`b` == 0) raiseDivByZero(); - if (`b` == -1 && `a` == 9223372036854775807) raiseOverflow(); + if (`b` == 0) `raiseDivByZero`(); + if (`b` == -1 && `a` == 9223372036854775807) `raiseOverflow`(); return Math.floor(`a` % `b`); """ @@ -415,13 +396,13 @@ proc internalAssert(file: cstring, line: int) {.pure, compilerproc.} = asm """`e`.message = "[Assertion failure] file: "+`file`+", line: "+`line`""" raise e -include hti +include "system/hti" proc isFatPointer(ti: PNimType): bool = # This has to be consistent with the code generator! - return ti.base.kind notin {tyRecord, tyRecordConstr, tyObject, + return ti.base.kind notin {tyObject, tyArray, tyArrayConstr, tyPureObject, tyTuple, - tyEmptySet, tyOpenArray, tySet, tyVar, tyRef, tyPtr} + tyOpenArray, tySet, tyVar, tyRef, tyPtr} proc NimCopy(x: pointer, ti: PNimType): pointer {.compilerproc.} @@ -452,7 +433,7 @@ proc NimCopy(x: pointer, ti: PNimType): pointer = `result`[0] = `x`[0]; `result`[1] = `x`[1]; """ - of tyEmptySet, tySet: + of tySet: asm """ `result` = {}; for (var key in `x`) { `result`[key] = `x`[key]; } diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index c473c42f0..65e233476 100755 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -10,6 +10,10 @@ # Exception handling code. This is difficult because it has # to work if there is no more memory (but it doesn't yet!). +var + stackTraceNewLine* = "\n" ## undocumented feature; it is replaced by ``<br>`` + ## for CGI applications + when not defined(windows) or not defined(guiapp): proc writeToStdErr(msg: CString) = write(stdout, msg) @@ -32,7 +36,7 @@ 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 + exc: ref E_Base # XXX only needed for bootstrapping; unused context: C_JmpBuf var @@ -55,6 +59,58 @@ proc pushCurrentException(e: ref E_Base) {.compilerRtl, inl.} = proc popCurrentException {.compilerRtl, inl.} = currException = currException.parent +# some platforms have native support for stack traces: +const + nimrodStackTrace = compileOption("stacktrace") + nativeStackTrace = (defined(macosx) or defined(linux)) and + not nimrodStackTrace and false + +# `nativeStackTrace` does not work for me --> deactivated for now. Maybe for +# the next release version. + +when nativeStacktrace: + type + TDl_info {.importc: "Dl_info", header: "<dlfcn.h>", + final, pure.} = object + dli_fname: CString + dli_fbase: pointer + dli_sname: CString + dli_saddr: pointer + + proc backtrace(symbols: ptr pointer, size: int): int {. + importc: "backtrace", header: "<execinfo.h>".} + 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 + + proc auxWriteStackTraceWithBacktrace(s: var string) = + # 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)), + len(tempAddresses)) + var enabled = false + for i in 0..size-1: + var dlresult = dladdr(tempAddresses[i], addr(tempDlInfo)) + if enabled: + if dlresult != 0: + var oldLen = s.len + add(s, tempDlInfo.dli_fname) + if tempDlInfo.dli_sname != nil: + for k in 1..max(1, 25-(s.len-oldLen)): add(s, ' ') + add(s, tempDlInfo.dli_sname) + else: + add(s, '?') + add(s, stackTraceNewLine) + else: + if dlresult != 0 and tempDlInfo.dli_sname != nil and + c_strcmp(tempDlInfo.dli_sname, "signalHandler") == 0'i32: + # Once we're past signalHandler, we're at what the user is + # interested in + enabled = true + type PFrame = ptr TFrame TFrame {.importc, nodecl, final.} = object @@ -74,9 +130,6 @@ var tempFrames: array [0..127, PFrame] # cannot be allocated on the stack! - stackTraceNewLine* = "\n" ## undocumented feature; it is replaced by ``<br>`` - ## for CGI applications - proc auxWriteStackTrace(f: PFrame, s: var string) = const firstCalls = 32 @@ -120,7 +173,7 @@ proc auxWriteStackTrace(f: PFrame, s: var string) = add(s, stackTraceNewLine) proc rawWriteStackTrace(s: var string) = - when compileOption("stacktrace") or compileOption("linetrace"): + when nimrodStackTrace: if framePtr == nil: add(s, "No stack traceback available") add(s, stackTraceNewLine) @@ -128,6 +181,10 @@ proc rawWriteStackTrace(s: var string) = add(s, "Traceback (most recent call last)") add(s, stackTraceNewLine) auxWriteStackTrace(framePtr, s) + elif nativeStackTrace: + add(s, "Traceback from system (most recent call last)") + add(s, stackTraceNewLine) + auxWriteStackTraceWithBacktrace(s) else: add(s, "No stack traceback available") add(s, stackTraceNewLine) @@ -197,11 +254,6 @@ proc WriteStackTrace() = rawWriteStackTrace(s) writeToStdErr(s) -#proc stackTraceWrapper {.noconv.} = -# writeStackTrace() - -#addQuitProc(stackTraceWrapper) - var dbgAborting: bool # whether the debugger wants to abort diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 0c403b4bc..c0461d89d 100755 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -77,14 +77,16 @@ var # collection, not a lock for threads! proc lock(gch: var TGcHeap) {.inline.} = - if isMultiThreaded: - Lock(gch.zctLock) - lock(gch.cycleRootsLock) + when hasThreadSupport: + if isMultiThreaded: + Lock(gch.zctLock) + lock(gch.cycleRootsLock) proc unlock(gch: var TGcHeap) {.inline.} = - if isMultiThreaded: - unlock(gch.zctLock) - unlock(gch.cycleRootsLock) + when hasThreadSupport: + if isMultiThreaded: + unlock(gch.zctLock) + unlock(gch.cycleRootsLock) proc addZCT(s: var TCellSeq, c: PCell) {.noinline.} = if (c.refcount and rcZct) == 0: @@ -202,15 +204,19 @@ proc prepareDealloc(cell: PCell) = proc rtlAddCycleRoot(c: PCell) {.rtl, inl.} = # we MUST access gch as a global here, because this crosses DLL boundaries! - if isMultiThreaded: Lock(gch.cycleRootsLock) + when hasThreadSupport: + if isMultiThreaded: Lock(gch.cycleRootsLock) incl(gch.cycleRoots, c) - if isMultiThreaded: Unlock(gch.cycleRootsLock) + when hasThreadSupport: + if isMultiThreaded: Unlock(gch.cycleRootsLock) proc rtlAddZCT(c: PCell) {.rtl, inl.} = # we MUST access gch as a global here, because this crosses DLL boundaries! - if isMultiThreaded: Lock(gch.zctLock) + when hasThreadSupport: + if isMultiThreaded: Lock(gch.zctLock) addZCT(gch.zct, c) - if isMultiThreaded: Unlock(gch.zctLock) + when hasThreadSupport: + if isMultiThreaded: Unlock(gch.zctLock) proc decRef(c: PCell) {.inline.} = when stressGC: @@ -480,7 +486,7 @@ proc gcMark(p: pointer) {.inline.} = add(gch.decStack, cell) proc markThreadStacks(gch: var TGcHeap) = - when isMultiThreaded: + when hasThreadSupport: nil # ----------------- stack management -------------------------------------- diff --git a/lib/system/systhread.nim b/lib/system/systhread.nim index 583cd2a43..af001985e 100755 --- a/lib/system/systhread.nim +++ b/lib/system/systhread.nim @@ -7,12 +7,17 @@ # distribution, for details about the copyright. # -when defined(gcc) or defined(llvm_gcc): +const + hasThreadSupport = false # deactivate for now: thread stack walking + # is missing! + maxThreads = 256 + +when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport: proc sync_add_and_fetch(p: var int, val: int): int {. importc: "__sync_add_and_fetch", nodecl.} proc sync_sub_and_fetch(p: var int, val: int): int {. importc: "__sync_sub_and_fetch", nodecl.} -elif defined(vcc): +elif defined(vcc) and hasThreadSupport: proc sync_add_and_fetch(p: var int, val: int): int {. importc: "NimXadd", nodecl.} else: @@ -20,19 +25,18 @@ else: inc(p, val) result = p -const - isMultiThreaded* = true - maxThreads = 256 +var + isMultiThreaded: bool # true when prog created at least 1 thread proc atomicInc(memLoc: var int, x: int): int = - when isMultiThreaded: + when hasThreadSupport: result = sync_add_and_fetch(memLoc, x) else: inc(memLoc, x) result = memLoc proc atomicDec(memLoc: var int, x: int): int = - when isMultiThreaded: + when hasThreadSupport: when defined(sync_sub_and_fetch): result = sync_sub_and_fetch(memLoc, x) else: @@ -85,11 +89,8 @@ type TThreadFunc* = proc (closure: pointer) {.cdecl.} proc createThread*(t: var TThread, fn: TThreadFunc) = - nil proc destroyThread*(t: var TThread) = nil - - |