Skip to content

Instantly share code, notes, and snippets.

@Araq
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Araq/a37c1b27e1900bd2ca2a to your computer and use it in GitHub Desktop.
Save Araq/a37c1b27e1900bd2ca2a to your computer and use it in GitHub Desktop.
const CacheLineSize = 32 # true for most archs
type
Barrier {.compilerProc.} = object
entered: int
cv: CondVar # condvar takes 3 words at least
when sizeof(int) < 8:
cacheAlign: array[CacheLineSize-4*sizeof(int), byte]
left: int
cacheAlign2: array[CacheLineSize-sizeof(int), byte]
interest: bool ## wether the master is interested in the "all done" event
proc barrierEnter(b: ptr Barrier) {.compilerProc, inline.} =
# due to the signaling between threads, it is ensured we are the only
# one with access to 'entered' so we don't need 'atomicInc' here:
inc b.entered
# also we need no 'fence' instructions here as soon 'nimArgsPassingDone'
# will be called which already will perform a fence for us.
proc barrierLeave(b: ptr Barrier) {.compilerProc, inline.} =
atomicInc b.left
when not defined(x86): fence()
if b.interest and b.left == b.entered: signal(b.cv)
proc openBarrier(b: ptr Barrier) {.compilerProc, inline.} =
b.entered = 0
b.left = 0
b.interest = false
proc closeBarrier(b: ptr Barrier) {.compilerProc.} =
fence()
if b.left != b.entered:
b.cv = createCondVar()
fence()
b.interest = true
fence()
while b.left != b.entered: await(b.cv)
destroyCondVar(b.cv)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment