Abi fields byref (#21)
* barriers: add abi fields ...allowing compile-time sizeof discovery * `bycopy` * barrier init actually takes a barrier attr * use byref for barrier * note mapping safety issues * add PR link
This commit is contained in:
parent
d74d4afadc
commit
17e8479a74
|
@ -43,7 +43,7 @@ else:
|
||||||
proc init*(syncBarrier: var SyncBarrier, threadCount: range[0'i32..high(int32)]) {.inline.} =
|
proc init*(syncBarrier: var SyncBarrier, threadCount: range[0'i32..high(int32)]) {.inline.} =
|
||||||
## Initialize a synchronization barrier that will block ``threadCount`` threads
|
## Initialize a synchronization barrier that will block ``threadCount`` threads
|
||||||
## before release.
|
## before release.
|
||||||
let err {.used.} = pthread_barrier_init(syncBarrier, nil, threadCount)
|
let err {.used.} = pthread_barrier_init(syncBarrier, nil, cuint threadCount)
|
||||||
when compileOption("assertions"):
|
when compileOption("assertions"):
|
||||||
if err != 0:
|
if err != 0:
|
||||||
raiseOSError(OSErrorCode(err))
|
raiseOSError(OSErrorCode(err))
|
||||||
|
|
|
@ -13,11 +13,9 @@
|
||||||
import locks
|
import locks
|
||||||
|
|
||||||
type
|
type
|
||||||
Natural32 = range[0'i32..high(int32)]
|
|
||||||
|
|
||||||
Errno* = cint
|
Errno* = cint
|
||||||
|
|
||||||
PthreadAttr* = object
|
PthreadBarrierAttr* = object
|
||||||
## Dummy
|
## Dummy
|
||||||
PthreadBarrier* = object
|
PthreadBarrier* = object
|
||||||
## Implementation of a sense reversing barrier
|
## Implementation of a sense reversing barrier
|
||||||
|
@ -26,8 +24,8 @@ type
|
||||||
lock: Lock # Alternatively spinlock on Atomic
|
lock: Lock # Alternatively spinlock on Atomic
|
||||||
cond {.guard: lock.}: Cond
|
cond {.guard: lock.}: Cond
|
||||||
sense {.guard: lock.}: bool # Choose int32 to avoid zero-expansion cost in registers?
|
sense {.guard: lock.}: bool # Choose int32 to avoid zero-expansion cost in registers?
|
||||||
left {.guard: lock.}: Natural32 # Number of threads missing at the barrier before opening
|
left {.guard: lock.}: cuint # Number of threads missing at the barrier before opening
|
||||||
count: Natural32 # Total number of threads that need to arrive before opening the barrier
|
count: cuint # Total number of threads that need to arrive before opening the barrier
|
||||||
|
|
||||||
const
|
const
|
||||||
PTHREAD_BARRIER_SERIAL_THREAD* = Errno(1)
|
PTHREAD_BARRIER_SERIAL_THREAD* = Errno(1)
|
||||||
|
@ -41,8 +39,8 @@ proc broadcast(cond: var Cond) {.inline.}=
|
||||||
|
|
||||||
func pthread_barrier_init*(
|
func pthread_barrier_init*(
|
||||||
barrier: var PthreadBarrier,
|
barrier: var PthreadBarrier,
|
||||||
attr: ptr PthreadAttr,
|
attr: ptr PthreadBarrierAttr,
|
||||||
count: range[0'i32..high(int32)]
|
count: cuint
|
||||||
): Errno =
|
): Errno =
|
||||||
barrier.lock.initLock()
|
barrier.lock.initLock()
|
||||||
{.locks: [barrier.lock].}:
|
{.locks: [barrier.lock].}:
|
||||||
|
|
|
@ -15,11 +15,15 @@ when not compileOption("threads"):
|
||||||
|
|
||||||
when defined(osx):
|
when defined(osx):
|
||||||
import ./barriers_macos
|
import ./barriers_macos
|
||||||
export PthreadAttr, PthreadBarrier, Errno, PTHREAD_BARRIER_SERIAL_THREAD
|
export PthreadBarrierAttr, PthreadBarrier, Errno, PTHREAD_BARRIER_SERIAL_THREAD
|
||||||
else:
|
else:
|
||||||
type
|
type
|
||||||
PthreadAttr* {.byref, importc: "pthread_attr_t", header: "<sys/types.h>".} = object
|
PthreadBarrierAttr* {.importc: "pthread_barrierattr_t", header: "<sys/types.h>", byref.} = object
|
||||||
PthreadBarrier* {.byref, importc: "pthread_barrier_t", header: "<sys/types.h>".} = object
|
when (defined(linux) and not defined(android)) and defined(amd64):
|
||||||
|
abi: array[4 div sizeof(cint), cint] # https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/nptl/bits/pthreadtypes-arch.h;h=dd06d6753ebc80d94ede6c3c18227a3ad3104570;hb=HEAD#l45
|
||||||
|
PthreadBarrier* {.importc: "pthread_barrier_t", header: "<sys/types.h>", byref.} = object
|
||||||
|
when (defined(linux) and not defined(android)) and defined(amd64):
|
||||||
|
abi: array[32 div sizeof(clong), clong] # https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/nptl/bits/pthreadtypes-arch.h;h=dd06d6753ebc80d94ede6c3c18227a3ad3104570;hb=HEAD#l28
|
||||||
|
|
||||||
Errno* = cint
|
Errno* = cint
|
||||||
|
|
||||||
|
@ -30,14 +34,19 @@ else:
|
||||||
when defined(osx):
|
when defined(osx):
|
||||||
export pthread_barrier_init, pthread_barrier_wait, pthread_barrier_destroy
|
export pthread_barrier_init, pthread_barrier_wait, pthread_barrier_destroy
|
||||||
else:
|
else:
|
||||||
|
# TODO careful, this function mutates `barrier` without it being `var` which
|
||||||
|
# is allowed as a consequence of `byref` - it is also different from the
|
||||||
|
# one in barriers_macos
|
||||||
|
# see https://github.com/status-im/nim-taskpools/pull/20#discussion_r923843093
|
||||||
proc pthread_barrier_init*(
|
proc pthread_barrier_init*(
|
||||||
barrier: PthreadBarrier,
|
barrier: PthreadBarrier,
|
||||||
attr: PthreadAttr or ptr PthreadAttr,
|
attr: ptr PthreadBarrierAttr,
|
||||||
count: range[0'i32..high(int32)]
|
count: cuint
|
||||||
): Errno {.header: "<pthread.h>".}
|
): Errno {.header: "<pthread.h>".}
|
||||||
## Initialize `barrier` with the attributes `attr`.
|
## Initialize `barrier` with the attributes `attr`.
|
||||||
## The barrier is opened when `count` waiters arrived.
|
## The barrier is opened when `count` waiters arrived.
|
||||||
|
|
||||||
|
# TODO the macos signature is var instead of sink
|
||||||
proc pthread_barrier_destroy*(
|
proc pthread_barrier_destroy*(
|
||||||
barrier: sink PthreadBarrier): Errno {.header: "<pthread.h>".}
|
barrier: sink PthreadBarrier): Errno {.header: "<pthread.h>".}
|
||||||
## Destroy a previously dynamically initialized `barrier`.
|
## Destroy a previously dynamically initialized `barrier`.
|
||||||
|
|
Loading…
Reference in New Issue