Merge branch 'devel' into araq

This commit is contained in:
Andreas Rumpf 2017-05-16 15:43:09 +02:00
commit c3c37dbb15
29 changed files with 517 additions and 277 deletions

View file

@ -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

View file

@ -299,8 +299,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.} =

View file

@ -99,7 +99,7 @@ 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):
@ -111,7 +111,7 @@ else:
when defined(linux) and defined(amd64):
abi: array[4 div sizeof(cint), cint] # actually a cint
SysCond {.importc: "pthread_cond_t", pure, final,
SysCondObj {.importc: "pthread_cond_t", pure, final,
header: """#include <sys/types.h>
#include <pthread.h>""".} = object
when defined(linux) and defined(amd64):
@ -119,8 +119,62 @@ else:
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 =
@ -130,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) {.
importc: "pthread_cond_wait", header: "<pthread.h>", noSideEffect.}
proc signalSysCond(cond: var SysCond) {.
importc: "pthread_cond_signal", header: "<pthread.h>", noSideEffect.}
proc deinitSysCond(cond: var SysCond) {.noSideEffect,
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 signalSysCondAux(cond: var SysCondObj) {.
importc: "pthread_cond_signal", header: "<pthread.h>", noSideEffect.}
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.}