// callee-save registers for gcc and returns to GoF, which returns to f.
void *initcgo; /* filled in by dynamic linker when Cgo is available */
-int64 ncgocall;
static void unlockm(void);
static void unwindm(void);
if(fn == 0)
runtime·throw("cgocall nil");
- ncgocall++;
+ m->ncgocall++;
/*
* Lock g to m to ensure we stay on the same stack if we do a
void
runtime·Cgocalls(int64 ret)
{
- ret = ncgocall;
+ M *m;
+
+ ret = 0;
+ for(m=runtime·atomicloadp(&runtime·allm); m; m=m->alllink)
+ ret += m->ncgocall;
FLUSH(&ret);
}
// Add to runtime·allm so garbage collector doesn't free m
// when it is just in a register or thread-local storage.
m->alllink = runtime·allm;
- runtime·allm = m;
+ // runtime·Cgocalls() iterates over allm w/o schedlock,
+ // so we need to publish it safely.
+ runtime·atomicstorep(&runtime·allm, m);
m->id = runtime·sched.mcount++;
m->fastrand = 0x49f6428aUL + m->id;