Skip to content

Instantly share code, notes, and snippets.

@skeeto
Created March 13, 2022 23:51
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 skeeto/bdb5a0d2aa36b68b6f66ca39989e1444 to your computer and use it in GitHub Desktop.
Save skeeto/bdb5a0d2aa36b68b6f66ca39989e1444 to your computer and use it in GitHub Desktop.
Thread barrier shared between Go and C
package main
// static void barrier_wait(int *barrier)
// {
// int v = __atomic_add_fetch(barrier, 1, __ATOMIC_SEQ_CST);
// if (v & 1) {
// v &= 2;
// while ((__atomic_load_n(barrier, __ATOMIC_SEQ_CST)&2) == v);
// }
// }
//
// static void other(int *barrier, int *x, int n)
// {
// for (int i = 0; i < n; i++) {
// if (*x) *(volatile int *)0 = 0;
// *x = 1;
// barrier_wait(barrier);
// barrier_wait(barrier);
// }
// }
import "C"
import (
"fmt"
"sync/atomic"
)
func BarrierWait(barrier *int32) {
v := atomic.AddInt32(barrier, 1)
if v&1 == 1 {
v &= 2
for atomic.LoadInt32(barrier)&2 == v {
}
}
}
func main() {
const n = 4_000_000
var barrier, x int32
go C.other((*C.int)(&barrier), (*C.int)(&x), n)
for i := 0; i < n; i++ {
BarrierWait(&barrier)
if x != 1 {
panic(x)
}
x = 0
BarrierWait(&barrier)
}
fmt.Println("success")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment