Merge branch 'new_spawn' of https://github.com/Araq/Nimrod into new_spawn
This commit is contained in:
commit
be229163af
38 changed files with 1923 additions and 159 deletions
|
|
@ -179,7 +179,8 @@ when not defined(nimmixin):
|
|||
# internal proc used for destroying sequences and arrays
|
||||
for i in countup(0, r.len - 1): destroy(r[i])
|
||||
else:
|
||||
# XXX Why is this exported and no compilerproc?
|
||||
# XXX Why is this exported and no compilerproc? -> compilerprocs cannot be
|
||||
# generic for now
|
||||
proc nimDestroyRange*[T](r: T) =
|
||||
# internal proc used for destroying sequences and arrays
|
||||
mixin destroy
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2012 Andreas Rumpf
|
||||
# (c) Copyright 2014 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
## Atomic operations for Nimrod.
|
||||
{.push stackTrace:off.}
|
||||
|
||||
when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport:
|
||||
type
|
||||
|
|
@ -203,3 +204,31 @@ proc atomicDec*(memLoc: var int, x: int = 1): int =
|
|||
else:
|
||||
dec(memLoc, x)
|
||||
result = memLoc
|
||||
|
||||
when defined(windows) and not defined(gcc):
|
||||
proc interlockedCompareExchange(p: pointer; exchange, comparand: int32): int32
|
||||
{.importc: "InterlockedCompareExchange", header: "<windows.h>", cdecl.}
|
||||
|
||||
proc cas*[T: bool|int|ptr](p: ptr T; oldValue, newValue: T): bool =
|
||||
interlockedCompareExchange(p, newValue.int32, oldValue.int32) != 0
|
||||
# XXX fix for 64 bit build
|
||||
else:
|
||||
# this is valid for GCC and Intel C++
|
||||
proc cas*[T: bool|int|ptr](p: ptr T; oldValue, newValue: T): bool
|
||||
{.importc: "__sync_bool_compare_and_swap", nodecl.}
|
||||
# XXX is this valid for 'int'?
|
||||
|
||||
|
||||
when (defined(x86) or defined(amd64)) and defined(gcc):
|
||||
proc cpuRelax {.inline.} =
|
||||
{.emit: """asm volatile("pause" ::: "memory");""".}
|
||||
elif (defined(x86) or defined(amd64)) and defined(vcc):
|
||||
proc cpuRelax {.importc: "YieldProcessor", header: "<windows.h>".}
|
||||
elif defined(intelc):
|
||||
proc cpuRelax {.importc: "_mm_pause", header: "xmmintrin.h".}
|
||||
elif false:
|
||||
from os import sleep
|
||||
|
||||
proc cpuRelax {.inline.} = os.sleep(1)
|
||||
|
||||
{.pop.}
|
||||
|
|
|
|||
|
|
@ -14,30 +14,6 @@ when not defined(NimString):
|
|||
|
||||
{.push stackTrace:off.}
|
||||
|
||||
when (defined(x86) or defined(amd64)) and defined(gcc):
|
||||
proc cpuRelax {.inline.} =
|
||||
{.emit: """asm volatile("pause" ::: "memory");""".}
|
||||
elif (defined(x86) or defined(amd64)) and defined(vcc):
|
||||
proc cpuRelax {.importc: "YieldProcessor", header: "<windows.h>".}
|
||||
elif defined(intelc):
|
||||
proc cpuRelax {.importc: "_mm_pause", header: "xmmintrin.h".}
|
||||
elif false:
|
||||
from os import sleep
|
||||
|
||||
proc cpuRelax {.inline.} = os.sleep(1)
|
||||
|
||||
when defined(windows) and not defined(gcc):
|
||||
proc interlockedCompareExchange(p: pointer; exchange, comparand: int32): int32
|
||||
{.importc: "InterlockedCompareExchange", header: "<windows.h>", cdecl.}
|
||||
|
||||
proc cas(p: ptr bool; oldValue, newValue: bool): bool =
|
||||
interlockedCompareExchange(p, newValue.int32, oldValue.int32) != 0
|
||||
|
||||
else:
|
||||
# this is valid for GCC and Intel C++
|
||||
proc cas(p: ptr bool; oldValue, newValue: bool): bool
|
||||
{.importc: "__sync_bool_compare_and_swap", nodecl.}
|
||||
|
||||
# We declare our own condition variables here to get rid of the dummy lock
|
||||
# on Windows:
|
||||
|
||||
|
|
@ -54,6 +30,9 @@ proc createCondVar(): CondVar =
|
|||
initSysLock(result.stupidLock)
|
||||
#acquireSys(result.stupidLock)
|
||||
|
||||
proc destroyCondVar(c: var CondVar) {.inline.} =
|
||||
deinitSysCond(c.c)
|
||||
|
||||
proc await(cv: var CondVar) =
|
||||
when defined(posix):
|
||||
acquireSys(cv.stupidLock)
|
||||
|
|
@ -100,6 +79,26 @@ proc signal(cv: var FastCondVar) =
|
|||
#if cas(addr cv.slowPath, true, false):
|
||||
signal(cv.slow)
|
||||
|
||||
type
|
||||
Barrier* {.compilerProc.} = object
|
||||
counter: int
|
||||
cv: CondVar
|
||||
|
||||
proc barrierEnter*(b: ptr Barrier) {.compilerProc.} =
|
||||
atomicInc b.counter
|
||||
|
||||
proc barrierLeave*(b: ptr Barrier) {.compilerProc.} =
|
||||
atomicDec b.counter
|
||||
if b.counter <= 0: signal(b.cv)
|
||||
|
||||
proc openBarrier*(b: ptr Barrier) {.compilerProc.} =
|
||||
b.counter = 0
|
||||
b.cv = createCondVar()
|
||||
|
||||
proc closeBarrier*(b: ptr Barrier) {.compilerProc.} =
|
||||
await(b.cv)
|
||||
destroyCondVar(b.cv)
|
||||
|
||||
{.pop.}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue