static bool onstack(uintptr argp);
+// We set m->racecall around all calls into race library to trigger fast path in cgocall.
+// Also we increment m->locks to disable preemption and potential rescheduling
+// to ensure that we reset m->racecall on the correct m.
+
uintptr
runtime·raceinit(void)
{
uintptr racectx, start, size;
m->racecall = true;
+ m->locks++;
runtime∕race·Initialize(&racectx);
// Round data segment to page boundaries, because it's used in mmap().
start = (uintptr)noptrdata & ~(PageSize-1);
size = ROUND((uintptr)enoptrbss - start, PageSize);
runtime∕race·MapShadow((void*)start, size);
+ m->locks--;
m->racecall = false;
return racectx;
}
runtime·racefini(void)
{
m->racecall = true;
+ m->locks++;
runtime∕race·Finalize();
+ m->locks--;
m->racecall = false;
}
runtime·racemapshadow(void *addr, uintptr size)
{
m->racecall = true;
+ m->locks++;
runtime∕race·MapShadow(addr, size);
+ m->locks--;
m->racecall = false;
}
{
if(!onstack(addr)) {
m->racecall = true;
+ m->locks++;
runtime∕race·Write(g->racectx, (void*)addr, runtime·getcallerpc(&addr));
+ m->locks--;
m->racecall = false;
}
}
{
if(!onstack(addr)) {
m->racecall = true;
+ m->locks++;
runtime∕race·WriteRange(g->racectx, (void*)addr, sz, runtime·getcallerpc(&addr));
+ m->locks--;
m->racecall = false;
}
}
{
if(!onstack(addr)) {
m->racecall = true;
+ m->locks++;
runtime∕race·Read(g->racectx, (void*)addr, runtime·getcallerpc(&addr));
+ m->locks--;
m->racecall = false;
}
}
{
if(!onstack(addr)) {
m->racecall = true;
+ m->locks++;
runtime∕race·ReadRange(g->racectx, (void*)addr, sz, runtime·getcallerpc(&addr));
+ m->locks--;
m->racecall = false;
}
}
runtime·callers(2, &pc, 1);
m->racecall = true;
+ m->locks++;
runtime∕race·FuncEnter(g->racectx, (void*)pc);
+ m->locks--;
m->racecall = false;
}
runtime·racefuncexit(void)
{
m->racecall = true;
+ m->locks++;
runtime∕race·FuncExit(g->racectx);
+ m->locks--;
m->racecall = false;
}
if(m->curg == nil)
return;
m->racecall = true;
+ m->locks++;
runtime∕race·Malloc(m->curg->racectx, p, sz, /* unused pc */ 0);
+ m->locks--;
m->racecall = false;
}
runtime·racefree(void *p)
{
m->racecall = true;
+ m->locks++;
runtime∕race·Free(p);
+ m->locks--;
m->racecall = false;
}
uintptr racectx;
m->racecall = true;
+ m->locks++;
runtime∕race·GoStart(g->racectx, &racectx, pc);
+ m->locks--;
m->racecall = false;
return racectx;
}
runtime·racegoend(void)
{
m->racecall = true;
+ m->locks++;
runtime∕race·GoEnd(g->racectx);
+ m->locks--;
m->racecall = false;
}
if(!onstack((uintptr)addr)) {
m->racecall = true;
+ m->locks++;
racectx = g->racectx;
if(callpc) {
if(callpc == (uintptr)runtime·lessstack)
runtime∕race·Read(racectx, addr, (void*)pc);
if(callpc)
runtime∕race·FuncExit(racectx);
+ m->locks--;
m->racecall = false;
}
}
if(!onstack((uintptr)addr)) {
m->racecall = true;
+ m->locks++;
racectx = g->racectx;
if(callpc) {
if(callpc == (uintptr)runtime·lessstack)
runtime∕race·ReadRange(racectx, addr, size, (void*)pc);
if(callpc)
runtime∕race·FuncExit(racectx);
+ m->locks--;
m->racecall = false;
}
}
if(g->raceignore)
return;
m->racecall = true;
+ m->locks++;
runtime∕race·Acquire(gp->racectx, addr);
+ m->locks--;
m->racecall = false;
}
if(g->raceignore)
return;
m->racecall = true;
+ m->locks++;
runtime∕race·Release(gp->racectx, addr);
+ m->locks--;
m->racecall = false;
}
if(g->raceignore)
return;
m->racecall = true;
+ m->locks++;
runtime∕race·ReleaseMerge(gp->racectx, addr);
+ m->locks--;
m->racecall = false;
}
runtime·racefingo(void)
{
m->racecall = true;
+ m->locks++;
runtime∕race·FinalizerGoroutine(g->racectx);
+ m->locks--;
m->racecall = false;
}