m->nomemprof--;
if(raceenabled)
- runtime·raceinit();
+ g->racectx = runtime·raceinit();
}
extern void main·init(void);
void
runtime·goexit(void)
{
+ if(raceenabled)
+ runtime·racegoend();
g->status = Gmoribund;
runtime·gosched();
}
gput(gp);
break;
case Gmoribund:
- if(raceenabled)
- runtime·racegoend(gp->goid);
gp->status = Gdead;
if(gp->lockedm) {
gp->lockedm = nil;
byte *sp;
G *newg;
int32 siz;
- int64 goid;
+ uintptr racectx;
//printf("newproc1 %p %p narg=%d nret=%d\n", fn, argp, narg, nret);
siz = narg + nret;
if(siz > StackMin - 1024)
runtime·throw("runtime.newproc: function arguments too large for new goroutine");
- goid = runtime·xadd64((uint64*)&runtime·sched.goidgen, 1);
if(raceenabled)
- runtime·racegostart(goid, callerpc);
+ racectx = runtime·racegostart(callerpc);
schedlock();
newg->sched.g = newg;
newg->entry = fn;
newg->gopc = (uintptr)callerpc;
+ if(raceenabled)
+ newg->racectx = racectx;
runtime·sched.gcount++;
- newg->goid = goid;
+ newg->goid = ++runtime·sched.goidgen;
newprocreadylocked(newg);
schedunlock();
#include "malloc.h"
#include "race.h"
-void runtime∕race·Initialize(void);
+void runtime∕race·Initialize(uintptr *racectx);
void runtime∕race·MapShadow(void *addr, uintptr size);
void runtime∕race·Finalize(void);
-void runtime∕race·FinalizerGoroutine(int32);
-void runtime∕race·Read(int32 goid, void *addr, void *pc);
-void runtime∕race·Write(int32 goid, void *addr, void *pc);
-void runtime∕race·ReadRange(int32 goid, void *addr, uintptr sz, uintptr step, void *pc);
-void runtime∕race·WriteRange(int32 goid, void *addr, uintptr sz, uintptr step, void *pc);
-void runtime∕race·FuncEnter(int32 goid, void *pc);
-void runtime∕race·FuncExit(int32 goid);
-void runtime∕race·Malloc(int32 goid, void *p, uintptr sz, void *pc);
+void runtime∕race·FinalizerGoroutine(uintptr racectx);
+void runtime∕race·Read(uintptr racectx, void *addr, void *pc);
+void runtime∕race·Write(uintptr racectx, void *addr, void *pc);
+void runtime∕race·ReadRange(uintptr racectx, void *addr, uintptr sz, uintptr step, void *pc);
+void runtime∕race·WriteRange(uintptr racectx, void *addr, uintptr sz, uintptr step, void *pc);
+void runtime∕race·FuncEnter(uintptr racectx, void *pc);
+void runtime∕race·FuncExit(uintptr racectx);
+void runtime∕race·Malloc(uintptr racectx, void *p, uintptr sz, void *pc);
void runtime∕race·Free(void *p);
-void runtime∕race·GoStart(int32 pgoid, int32 chgoid, void *pc);
-void runtime∕race·GoEnd(int32 goid);
-void runtime∕race·Acquire(int32 goid, void *addr);
-void runtime∕race·Release(int32 goid, void *addr);
-void runtime∕race·ReleaseMerge(int32 goid, void *addr);
+void runtime∕race·GoStart(uintptr racectx, uintptr *chracectx, void *pc);
+void runtime∕race·GoEnd(uintptr racectx);
+void runtime∕race·Acquire(uintptr racectx, void *addr);
+void runtime∕race·Release(uintptr racectx, void *addr);
+void runtime∕race·ReleaseMerge(uintptr racectx, void *addr);
extern byte noptrdata[];
extern byte enoptrbss[];
static bool onstack(uintptr argp);
-void
+uintptr
runtime·raceinit(void)
{
- uintptr sz;
+ uintptr sz, racectx;
m->racecall = true;
- runtime∕race·Initialize();
+ runtime∕race·Initialize(&racectx);
sz = (byte*)&runtime·mheap - noptrdata;
if(sz)
runtime∕race·MapShadow(noptrdata, sz);
if(sz)
runtime∕race·MapShadow(&runtime·mheap+1, sz);
m->racecall = false;
+ return racectx;
}
void
{
if(!onstack(addr)) {
m->racecall = true;
- runtime∕race·Write(g->goid-1, (void*)addr, runtime·getcallerpc(&addr));
+ runtime∕race·Write(g->racectx, (void*)addr, runtime·getcallerpc(&addr));
m->racecall = false;
}
}
{
if(!onstack(addr)) {
m->racecall = true;
- runtime∕race·Read(g->goid-1, (void*)addr, runtime·getcallerpc(&addr));
+ runtime∕race·Read(g->racectx, (void*)addr, runtime·getcallerpc(&addr));
m->racecall = false;
}
}
runtime·callers(2, &pc, 1);
m->racecall = true;
- runtime∕race·FuncEnter(g->goid-1, (void*)pc);
+ runtime∕race·FuncEnter(g->racectx, (void*)pc);
m->racecall = false;
}
runtime·racefuncexit(void)
{
m->racecall = true;
- runtime∕race·FuncExit(g->goid-1);
+ runtime∕race·FuncExit(g->racectx);
m->racecall = false;
}
if(m->curg == nil)
return;
m->racecall = true;
- runtime∕race·Malloc(m->curg->goid-1, p, sz, pc);
+ runtime∕race·Malloc(m->curg->racectx, p, sz, pc);
m->racecall = false;
}
m->racecall = false;
}
-void
-runtime·racegostart(int32 goid, void *pc)
+uintptr
+runtime·racegostart(void *pc)
{
+ uintptr racectx;
+
m->racecall = true;
- runtime∕race·GoStart(g->goid-1, goid-1, pc);
+ runtime∕race·GoStart(g->racectx, &racectx, pc);
m->racecall = false;
+ return racectx;
}
void
-runtime·racegoend(int32 goid)
+runtime·racegoend(void)
{
m->racecall = true;
- runtime∕race·GoEnd(goid-1);
+ runtime∕race·GoEnd(g->racectx);
m->racecall = false;
}
static void
memoryaccess(void *addr, uintptr callpc, uintptr pc, bool write)
{
- int64 goid;
+ uintptr racectx;
if(!onstack((uintptr)addr)) {
m->racecall = true;
- goid = g->goid-1;
+ racectx = g->racectx;
if(callpc) {
if(callpc == (uintptr)runtime·lessstack ||
(callpc >= (uintptr)runtime·mheap.arena_start && callpc < (uintptr)runtime·mheap.arena_used))
runtime·callers(3, &callpc, 1);
- runtime∕race·FuncEnter(goid, (void*)callpc);
+ runtime∕race·FuncEnter(racectx, (void*)callpc);
}
if(write)
- runtime∕race·Write(goid, addr, (void*)pc);
+ runtime∕race·Write(racectx, addr, (void*)pc);
else
- runtime∕race·Read(goid, addr, (void*)pc);
+ runtime∕race·Read(racectx, addr, (void*)pc);
if(callpc)
- runtime∕race·FuncExit(goid);
+ runtime∕race·FuncExit(racectx);
m->racecall = false;
}
}
static void
rangeaccess(void *addr, uintptr size, uintptr step, uintptr callpc, uintptr pc, bool write)
{
- int64 goid;
+ uintptr racectx;
if(!onstack((uintptr)addr)) {
m->racecall = true;
- goid = g->goid-1;
+ racectx = g->racectx;
if(callpc) {
if(callpc == (uintptr)runtime·lessstack ||
(callpc >= (uintptr)runtime·mheap.arena_start && callpc < (uintptr)runtime·mheap.arena_used))
runtime·callers(3, &callpc, 1);
- runtime∕race·FuncEnter(goid, (void*)callpc);
+ runtime∕race·FuncEnter(racectx, (void*)callpc);
}
if(write)
- runtime∕race·WriteRange(goid, addr, size, step, (void*)pc);
+ runtime∕race·WriteRange(racectx, addr, size, step, (void*)pc);
else
- runtime∕race·ReadRange(goid, addr, size, step, (void*)pc);
+ runtime∕race·ReadRange(racectx, addr, size, step, (void*)pc);
if(callpc)
- runtime∕race·FuncExit(goid);
+ runtime∕race·FuncExit(racectx);
m->racecall = false;
}
}
if(g->raceignore)
return;
m->racecall = true;
- runtime∕race·Acquire(gp->goid-1, addr);
+ runtime∕race·Acquire(gp->racectx, addr);
m->racecall = false;
}
if(g->raceignore)
return;
m->racecall = true;
- runtime∕race·Release(gp->goid-1, addr);
+ runtime∕race·Release(gp->racectx, addr);
m->racecall = false;
}
if(g->raceignore)
return;
m->racecall = true;
- runtime∕race·ReleaseMerge(gp->goid-1, addr);
+ runtime∕race·ReleaseMerge(gp->racectx, addr);
m->racecall = false;
}
runtime·racefingo(void)
{
m->racecall = true;
- runtime∕race·FinalizerGoroutine(g->goid - 1);
+ runtime∕race·FinalizerGoroutine(g->racectx);
m->racecall = false;
}
#endif
// Initialize race detection subsystem.
-void runtime·raceinit(void);
+uintptr runtime·raceinit(void);
// Finalize race detection subsystem, does not return.
void runtime·racefini(void);
void runtime·racemapshadow(void *addr, uintptr size);
void runtime·racemalloc(void *p, uintptr sz, void *pc);
void runtime·racefree(void *p);
-void runtime·racegostart(int32 goid, void *pc);
-void runtime·racegoend(int32 goid);
+uintptr runtime·racegostart(void *pc);
+void runtime·racegoend(void);
void runtime·racewritepc(void *addr, void *callpc, void *pc);
void runtime·racereadpc(void *addr, void *callpc, void *pc);
void runtime·racewriterangepc(void *addr, uintptr sz, uintptr step, void *callpc, void *pc);
package race
/*
-void __tsan_init(void);
+void __tsan_init(void **racectx);
void __tsan_fini(void);
void __tsan_map_shadow(void *addr, void *size);
-void __tsan_go_start(int pgoid, int chgoid, void *pc);
-void __tsan_go_end(int goid);
-void __tsan_read(int goid, void *addr, void *pc);
-void __tsan_write(int goid, void *addr, void *pc);
-void __tsan_read_range(int goid, void *addr, long sz, long step, void *pc);
-void __tsan_write_range(int goid, void *addr, long sz, long step, void *pc);
-void __tsan_func_enter(int goid, void *pc);
-void __tsan_func_exit(int goid);
-void __tsan_malloc(int goid, void *p, long sz, void *pc);
+void __tsan_go_start(void *racectx, void **chracectx, void *pc);
+void __tsan_go_end(void *racectx);
+void __tsan_read(void *racectx, void *addr, void *pc);
+void __tsan_write(void *racectx, void *addr, void *pc);
+void __tsan_read_range(void *racectx, void *addr, long sz, long step, void *pc);
+void __tsan_write_range(void *racectx, void *addr, long sz, long step, void *pc);
+void __tsan_func_enter(void *racectx, void *pc);
+void __tsan_func_exit(void *racectx);
+void __tsan_malloc(void *racectx, void *p, long sz, void *pc);
void __tsan_free(void *p);
-void __tsan_acquire(int goid, void *addr);
-void __tsan_release(int goid, void *addr);
-void __tsan_release_merge(int goid, void *addr);
-void __tsan_finalizer_goroutine(int tid);
+void __tsan_acquire(void *racectx, void *addr);
+void __tsan_release(void *racectx, void *addr);
+void __tsan_release_merge(void *racectx, void *addr);
+void __tsan_finalizer_goroutine(void *racectx);
*/
import "C"
"unsafe"
)
-func Initialize() {
- C.__tsan_init()
+func Initialize(racectx *uintptr) {
+ C.__tsan_init((*unsafe.Pointer)(unsafe.Pointer(racectx)))
}
func Finalize() {
C.__tsan_map_shadow(unsafe.Pointer(addr), unsafe.Pointer(size))
}
-func FinalizerGoroutine(goid int32) {
- C.__tsan_finalizer_goroutine(C.int(goid))
+func FinalizerGoroutine(racectx uintptr) {
+ C.__tsan_finalizer_goroutine(unsafe.Pointer(racectx))
}
-func Read(goid int32, addr, pc uintptr) {
- C.__tsan_read(C.int(goid), unsafe.Pointer(addr), unsafe.Pointer(pc))
+func Read(racectx uintptr, addr, pc uintptr) {
+ C.__tsan_read(unsafe.Pointer(racectx), unsafe.Pointer(addr), unsafe.Pointer(pc))
}
-func Write(goid int32, addr, pc uintptr) {
- C.__tsan_write(C.int(goid), unsafe.Pointer(addr), unsafe.Pointer(pc))
+func Write(racectx uintptr, addr, pc uintptr) {
+ C.__tsan_write(unsafe.Pointer(racectx), unsafe.Pointer(addr), unsafe.Pointer(pc))
}
-func ReadRange(goid int32, addr, sz, step, pc uintptr) {
- C.__tsan_read_range(C.int(goid), unsafe.Pointer(addr),
+func ReadRange(racectx uintptr, addr, sz, step, pc uintptr) {
+ C.__tsan_read_range(unsafe.Pointer(racectx), unsafe.Pointer(addr),
C.long(sz), C.long(step), unsafe.Pointer(pc))
}
-func WriteRange(goid int32, addr, sz, step, pc uintptr) {
- C.__tsan_write_range(C.int(goid), unsafe.Pointer(addr),
+func WriteRange(racectx uintptr, addr, sz, step, pc uintptr) {
+ C.__tsan_write_range(unsafe.Pointer(racectx), unsafe.Pointer(addr),
C.long(sz), C.long(step), unsafe.Pointer(pc))
}
-func FuncEnter(goid int32, pc uintptr) {
- C.__tsan_func_enter(C.int(goid), unsafe.Pointer(pc))
+func FuncEnter(racectx uintptr, pc uintptr) {
+ C.__tsan_func_enter(unsafe.Pointer(racectx), unsafe.Pointer(pc))
}
-func FuncExit(goid int32) {
- C.__tsan_func_exit(C.int(goid))
+func FuncExit(racectx uintptr) {
+ C.__tsan_func_exit(unsafe.Pointer(racectx))
}
-func Malloc(goid int32, p, sz, pc uintptr) {
- C.__tsan_malloc(C.int(goid), unsafe.Pointer(p), C.long(sz), unsafe.Pointer(pc))
+func Malloc(racectx uintptr, p, sz, pc uintptr) {
+ C.__tsan_malloc(unsafe.Pointer(racectx), unsafe.Pointer(p), C.long(sz), unsafe.Pointer(pc))
}
func Free(p uintptr) {
C.__tsan_free(unsafe.Pointer(p))
}
-func GoStart(pgoid, chgoid int32, pc uintptr) {
- C.__tsan_go_start(C.int(pgoid), C.int(chgoid), unsafe.Pointer(pc))
+func GoStart(racectx uintptr, chracectx *uintptr, pc uintptr) {
+ C.__tsan_go_start(unsafe.Pointer(racectx), (*unsafe.Pointer)(unsafe.Pointer(chracectx)), unsafe.Pointer(pc))
}
-func GoEnd(goid int32) {
- C.__tsan_go_end(C.int(goid))
+func GoEnd(racectx uintptr) {
+ C.__tsan_go_end(unsafe.Pointer(racectx))
}
-func Acquire(goid int32, addr uintptr) {
- C.__tsan_acquire(C.int(goid), unsafe.Pointer(addr))
+func Acquire(racectx uintptr, addr uintptr) {
+ C.__tsan_acquire(unsafe.Pointer(racectx), unsafe.Pointer(addr))
}
-func Release(goid int32, addr uintptr) {
- C.__tsan_release(C.int(goid), unsafe.Pointer(addr))
+func Release(racectx uintptr, addr uintptr) {
+ C.__tsan_release(unsafe.Pointer(racectx), unsafe.Pointer(addr))
}
-func ReleaseMerge(goid int32, addr uintptr) {
- C.__tsan_release_merge(C.int(goid), unsafe.Pointer(addr))
+func ReleaseMerge(racectx uintptr, addr uintptr) {
+ C.__tsan_release_merge(unsafe.Pointer(racectx), unsafe.Pointer(addr))
}
//export __tsan_symbolize
#include "runtime.h"
-void
+uintptr
runtime·raceinit(void)
{
+ return 0;
}
void
USED(p);
}
-void
-runtime·racegostart(int32 goid, void *pc)
+uintptr
+runtime·racegostart(void *pc)
{
- USED(goid);
USED(pc);
+ return 0;
}
void
-runtime·racegoend(int32 goid)
+runtime·racegoend()
{
- USED(goid);
}
uintptr sigcode1;
uintptr sigpc;
uintptr gopc; // pc of go statement that created this goroutine
+ uintptr racectx;
uintptr end[];
};
struct M