diff options
Diffstat (limited to 'lib/system')
-rw-r--r-- | lib/system/ansi_c.nim | 10 | ||||
-rw-r--r-- | lib/system/atomics.nim | 20 | ||||
-rw-r--r-- | lib/system/excpt.nim | 9 | ||||
-rw-r--r-- | lib/system/jssys.nim | 2 | ||||
-rw-r--r-- | lib/system/syslocks.nim | 119 | ||||
-rw-r--r-- | lib/system/threads.nim | 34 |
6 files changed, 152 insertions, 42 deletions
diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim index 52065531b..b2f6d314f 100644 --- a/lib/system/ansi_c.nim +++ b/lib/system/ansi_c.nim @@ -26,8 +26,14 @@ proc c_memset(p: pointer, value: cint, size: csize): pointer {. proc c_strcmp(a, b: cstring): cint {. importc: "strcmp", header: "<string.h>", noSideEffect.} -type - C_JmpBuf {.importc: "jmp_buf", header: "<setjmp.h>".} = object +when defined(linux) and defined(amd64): + type + C_JmpBuf {.importc: "jmp_buf", header: "<setjmp.h>", bycopy.} = object + abi: array[200 div sizeof(clong), clong] +else: + type + C_JmpBuf {.importc: "jmp_buf", header: "<setjmp.h>".} = object + when defined(windows): const diff --git a/lib/system/atomics.nim b/lib/system/atomics.nim index 3a43729dc..885b01621 100644 --- a/lib/system/atomics.nim +++ b/lib/system/atomics.nim @@ -165,8 +165,22 @@ when someGcc and hasThreadSupport: template fence*() = atomicThreadFence(ATOMIC_SEQ_CST) elif defined(vcc) and hasThreadSupport: - proc addAndFetch*(p: ptr int, val: int): int {. - importc: "_InterlockedExchangeAdd", header: "<intrin.h>".} + when defined(cpp): + when sizeof(int) == 8: + proc addAndFetch*(p: ptr int, val: int): int {. + importcpp: "_InterlockedExchangeAdd64(static_cast<NI volatile *>(#), #)", + header: "<intrin.h>".} + else: + proc addAndFetch*(p: ptr int, val: int): int {. + importcpp: "_InterlockedExchangeAdd(static_cast<NI volatile *>(#), #)", + header: "<intrin.h>".} + else: + when sizeof(int) == 8: + proc addAndFetch*(p: ptr int, val: int): int {. + importc: "_InterlockedExchangeAdd64", header: "<intrin.h>".} + else: + proc addAndFetch*(p: ptr int, val: int): int {. + importc: "_InterlockedExchangeAdd", header: "<intrin.h>".} proc fence*() {.importc: "_ReadWriteBarrier", header: "<intrin.h>".} @@ -180,6 +194,7 @@ proc atomicInc*(memLoc: var int, x: int = 1): int = result = atomic_add_fetch(memLoc.addr, x, ATOMIC_RELAXED) elif defined(vcc) and hasThreadSupport: result = addAndFetch(memLoc.addr, x) + inc(result, x) else: inc(memLoc, x) result = memLoc @@ -192,6 +207,7 @@ proc atomicDec*(memLoc: var int, x: int = 1): int = result = atomic_add_fetch(memLoc.addr, -x, ATOMIC_RELAXED) elif defined(vcc) and hasThreadSupport: result = addAndFetch(memLoc.addr, -x) + dec(result, x) else: dec(memLoc, x) result = memLoc diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index 8ed1fbb38..096d01845 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -282,8 +282,13 @@ proc raiseExceptionAux(e: ref Exception) = proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} = if e.name.isNil: e.name = ename when hasSomeStackTrace: - e.trace = "" - rawWriteStackTrace(e.trace) + if e.trace.isNil: + e.trace = "" + rawWriteStackTrace(e.trace) + elif framePtr != nil: + e.trace.add "[[reraised from:\n" + auxWriteStackTrace(framePtr, e.trace) + e.trace.add "]]\n" raiseExceptionAux(e) proc reraiseException() {.compilerRtl.} = diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index 9ef4a02f2..8a81a550a 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -172,7 +172,7 @@ proc raiseIndexError() {.compilerproc, noreturn.} = proc raiseFieldError(f: string) {.compilerproc, noreturn.} = raise newException(FieldError, f & " is not accessible") -proc SetConstr() {.varargs, asmNoStackFrame, compilerproc.} = +proc setConstr() {.varargs, asmNoStackFrame, compilerproc.} = when defined(nimphp): asm """ $args = func_get_args(); diff --git a/lib/system/syslocks.nim b/lib/system/syslocks.nim index 9d056611f..f61b887ad 100644 --- a/lib/system/syslocks.nim +++ b/lib/system/syslocks.nim @@ -99,19 +99,82 @@ elif defined(genode): else: type - SysLock {.importc: "pthread_mutex_t", pure, final, + SysLockObj {.importc: "pthread_mutex_t", pure, final, header: """#include <sys/types.h> #include <pthread.h>""".} = object + when defined(linux) and defined(amd64): + abi: array[40 div sizeof(clong), clong] + SysLockAttr {.importc: "pthread_mutexattr_t", pure, final header: """#include <sys/types.h> #include <pthread.h>""".} = object - SysCond {.importc: "pthread_cond_t", pure, final, + when defined(linux) and defined(amd64): + abi: array[4 div sizeof(cint), cint] # actually a cint + + SysCondObj {.importc: "pthread_cond_t", pure, final, header: """#include <sys/types.h> #include <pthread.h>""".} = object + when defined(linux) and defined(amd64): + abi: array[48 div sizeof(clonglong), clonglong] + SysLockType = distinct cint - proc initSysLock(L: var SysLock, attr: ptr SysLockAttr = nil) {. + proc initSysLockAux(L: var SysLockObj, attr: ptr SysLockAttr) {. importc: "pthread_mutex_init", header: "<pthread.h>", noSideEffect.} + proc deinitSysAux(L: var SysLockObj) {.noSideEffect, + importc: "pthread_mutex_destroy", header: "<pthread.h>".} + + proc acquireSysAux(L: var SysLockObj) {.noSideEffect, + importc: "pthread_mutex_lock", header: "<pthread.h>".} + proc tryAcquireSysAux(L: var SysLockObj): cint {.noSideEffect, + importc: "pthread_mutex_trylock", header: "<pthread.h>".} + + proc releaseSysAux(L: var SysLockObj) {.noSideEffect, + importc: "pthread_mutex_unlock", header: "<pthread.h>".} + + when defined(ios): + # iOS will behave badly if sync primitives are moved in memory. In order + # to prevent this once and for all, we're doing an extra malloc when + # initializing the primitive. + type + SysLock = ptr SysLockObj + SysCond = ptr SysCondObj + + when not declared(c_malloc): + proc c_malloc(size: csize): pointer {. + importc: "malloc", header: "<stdlib.h>".} + proc c_free(p: pointer) {. + importc: "free", header: "<stdlib.h>".} + + proc initSysLock(L: var SysLock, attr: ptr SysLockAttr = nil) = + L = cast[SysLock](c_malloc(sizeof(SysLockObj))) + initSysLockAux(L[], attr) + + proc deinitSys(L: var SysLock) = + deinitSysAux(L[]) + c_free(L) + + template acquireSys(L: var SysLock) = + acquireSysAux(L[]) + template tryAcquireSys(L: var SysLock): bool = + tryAcquireSysAux(L[]) == 0'i32 + template releaseSys(L: var SysLock) = + releaseSysAux(L[]) + else: + type + SysLock = SysLockObj + SysCond = SysCondObj + + template initSysLock(L: var SysLock, attr: ptr SysLockAttr = nil) = + initSysLockAux(L, attr) + template deinitSys(L: var SysLock) = + deinitSysAux(L) + template acquireSys(L: var SysLock) = + acquireSysAux(L) + template tryAcquireSys(L: var SysLock): bool = + tryAcquireSysAux(L) == 0'i32 + template releaseSys(L: var SysLock) = + releaseSysAux(L) when insideRLocksModule: proc SysLockType_Reentrant: SysLockType = @@ -121,27 +184,39 @@ else: proc setSysLockType(a: var SysLockAttr, t: SysLockType) {. importc: "pthread_mutexattr_settype", header: "<pthread.h>", noSideEffect.} - proc acquireSys(L: var SysLock) {.noSideEffect, - importc: "pthread_mutex_lock", header: "<pthread.h>".} - proc tryAcquireSysAux(L: var SysLock): cint {.noSideEffect, - importc: "pthread_mutex_trylock", header: "<pthread.h>".} - - proc tryAcquireSys(L: var SysLock): bool {.inline.} = - result = tryAcquireSysAux(L) == 0'i32 - - proc releaseSys(L: var SysLock) {.noSideEffect, - importc: "pthread_mutex_unlock", header: "<pthread.h>".} - proc deinitSys(L: var SysLock) {.noSideEffect, - importc: "pthread_mutex_destroy", header: "<pthread.h>".} - - when not insideRLocksModule: - proc initSysCond(cond: var SysCond, cond_attr: pointer = nil) {. + else: + proc initSysCondAux(cond: var SysCondObj, cond_attr: pointer) {. importc: "pthread_cond_init", header: "<pthread.h>", noSideEffect.} - proc waitSysCond(cond: var SysCond, lock: var SysLock) {. + proc deinitSysCondAux(cond: var SysCondObj) {.noSideEffect, + importc: "pthread_cond_destroy", header: "<pthread.h>".} + + proc waitSysCondAux(cond: var SysCondObj, lock: var SysLockObj) {. importc: "pthread_cond_wait", header: "<pthread.h>", noSideEffect.} - proc signalSysCond(cond: var SysCond) {. + proc signalSysCondAux(cond: var SysCondObj) {. importc: "pthread_cond_signal", header: "<pthread.h>", noSideEffect.} - proc deinitSysCond(cond: var SysCond) {.noSideEffect, - importc: "pthread_cond_destroy", header: "<pthread.h>".} + + when defined(ios): + proc initSysCond(cond: var SysCond, cond_attr: pointer = nil) = + cond = cast[SysCond](c_malloc(sizeof(SysCondObj))) + initSysCondAux(cond[], cond_attr) + + proc deinitSysCond(cond: var SysCond) = + deinitSysCondAux(cond[]) + c_free(cond) + + template waitSysCond(cond: var SysCond, lock: var SysLock) = + waitSysCondAux(cond[], lock[]) + template signalSysCond(cond: var SysCond) = + signalSysCondAux(cond[]) + else: + template initSysCond(cond: var SysCond, cond_attr: pointer = nil) = + initSysCondAux(cond, cond_attr) + template deinitSysCond(cond: var SysCond) = + deinitSysCondAux(cond) + + template waitSysCond(cond: var SysCond, lock: var SysLock) = + waitSysCondAux(cond, lock) + template signalSysCond(cond: var SysCond) = + signalSysCondAux(cond) {.pop.} diff --git a/lib/system/threads.nim b/lib/system/threads.nim index 7743fffff..d1012e9c5 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -177,18 +177,28 @@ else: else: type Time = int + when defined(linux) and defined(amd64): + type + SysThread* {.importc: "pthread_t", + header: "<sys/types.h>" .} = distinct culong + Pthread_attr {.importc: "pthread_attr_t", + header: "<sys/types.h>".} = object + abi: array[56 div sizeof(clong), clong] + ThreadVarSlot {.importc: "pthread_key_t", + header: "<sys/types.h>".} = distinct cuint + else: + type + SysThread* {.importc: "pthread_t", header: "<sys/types.h>".} = object + Pthread_attr {.importc: "pthread_attr_t", + header: "<sys/types.h>".} = object + ThreadVarSlot {.importc: "pthread_key_t", + header: "<sys/types.h>".} = object type - SysThread* {.importc: "pthread_t", header: "<sys/types.h>", - final, pure.} = object - Pthread_attr {.importc: "pthread_attr_t", - header: "<sys/types.h>", final, pure.} = object - - Timespec {.importc: "struct timespec", - header: "<time.h>", final, pure.} = object + Timespec {.importc: "struct timespec", header: "<time.h>".} = object tv_sec: Time tv_nsec: clong {.deprecated: [TSysThread: SysThread, Tpthread_attr: PThreadAttr, - Ttimespec: Timespec].} + Ttimespec: Timespec, TThreadVarSlot: ThreadVarSlot].} proc pthread_attr_init(a1: var PthreadAttr) {. importc, header: pthreadh.} @@ -205,11 +215,6 @@ else: proc pthread_cancel(a1: SysThread): cint {. importc: "pthread_cancel", header: pthreadh.} - type - ThreadVarSlot {.importc: "pthread_key_t", pure, final, - header: "<sys/types.h>".} = object - {.deprecated: [TThreadVarSlot: ThreadVarSlot].} - proc pthread_getspecific(a1: ThreadVarSlot): pointer {. importc: "pthread_getspecific", header: pthreadh.} proc pthread_key_create(a1: ptr ThreadVarSlot, @@ -234,6 +239,9 @@ else: importc: "pthread_attr_setstack", header: pthreadh.} type CpuSet {.importc: "cpu_set_t", header: schedh.} = object + when defined(linux) and defined(amd64): + abi: array[1024 div (8 * sizeof(culong)), culong] + proc cpusetZero(s: var CpuSet) {.importc: "CPU_ZERO", header: schedh.} proc cpusetIncl(cpu: cint; s: var CpuSet) {. importc: "CPU_SET", header: schedh.} |