runtime·lock(c);
// TODO(dvyukov): add similar instrumentation to select.
if(raceenabled)
- runtime·racereadpc(c, pc);
+ runtime·racereadpc(c, pc, runtime·chansend);
if(c->closed)
goto closed;
}
if(raceenabled) {
- runtime·racewritepc(c, runtime·getcallerpc(&c));
+ runtime·racewritepc(c, runtime·getcallerpc(&c), runtime·closechan);
runtime·racerelease(c);
}
bool pres;
if(raceenabled && h != nil)
- runtime·racereadpc(h, runtime·getcallerpc(&t));
+ runtime·racereadpc(h, runtime·getcallerpc(&t), runtime·mapaccess1);
ak = (byte*)(&h + 1);
av = ak + ROUND(t->key->size, Structrnd);
byte *ak, *av, *ap;
if(raceenabled && h != nil)
- runtime·racereadpc(h, runtime·getcallerpc(&t));
+ runtime·racereadpc(h, runtime·getcallerpc(&t), runtime·mapaccess2);
ak = (byte*)(&h + 1);
av = ak + ROUND(t->key->size, Structrnd);
byte *ak, *av;
if(raceenabled && h != nil)
- runtime·racereadpc(h, runtime·getcallerpc(&t));
+ runtime·racereadpc(h, runtime·getcallerpc(&t), reflect·mapaccess);
if(t->key->size <= sizeof(key))
ak = (byte*)&key;
runtime·panicstring("assignment to entry in nil map");
if(raceenabled)
- runtime·racewritepc(h, runtime·getcallerpc(&t));
+ runtime·racewritepc(h, runtime·getcallerpc(&t), runtime·mapassign1);
ak = (byte*)(&h + 1);
av = ak + ROUND(t->key->size, t->elem->align);
runtime·panicstring("deletion of entry in nil map");
if(raceenabled)
- runtime·racewritepc(h, runtime·getcallerpc(&t));
+ runtime·racewritepc(h, runtime·getcallerpc(&t), runtime·mapdelete);
ak = (byte*)(&h + 1);
runtime·mapassign(t, h, ak, nil);
if(h == nil)
runtime·panicstring("assignment to entry in nil map");
if(raceenabled)
- runtime·racewritepc(h, runtime·getcallerpc(&t));
+ runtime·racewritepc(h, runtime·getcallerpc(&t), reflect·mapassign);
if(t->key->size <= sizeof(key))
ak = (byte*)&key;
else
return;
}
if(raceenabled)
- runtime·racereadpc(h, runtime·getcallerpc(&t));
+ runtime·racereadpc(h, runtime·getcallerpc(&t), runtime·mapiterinit);
hash_iter_init(t, h, it);
it->data = hash_next(it);
if(debug) {
runtime·mapiternext(struct hash_iter *it)
{
if(raceenabled)
- runtime·racereadpc(it->h, runtime·getcallerpc(&it));
+ runtime·racereadpc(it->h, runtime·getcallerpc(&it), runtime·mapiternext);
if(runtime·gcwaiting)
runtime·gosched();
else {
len = h->count;
if(raceenabled)
- runtime·racereadpc(h, runtime·getcallerpc(&h));
+ runtime·racereadpc(h, runtime·getcallerpc(&h), reflect·maplen);
}
FLUSH(&len);
}
m->racecall = false;
}
-void
-runtime·racewritepc(void *addr, void *pc)
+static void
+memoryaccess(void *addr, uintptr callpc, uintptr pc, bool write)
{
+ int64 goid;
+
if(!onstack((uintptr)addr)) {
m->racecall = true;
- runtime∕race·Write(g->goid-1, addr, pc);
+ goid = g->goid-1;
+ 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);
+ }
+ if(write)
+ runtime∕race·Write(goid, addr, (void*)pc);
+ else
+ runtime∕race·Read(goid, addr, (void*)pc);
+ if(callpc)
+ runtime∕race·FuncExit(goid);
m->racecall = false;
}
}
void
-runtime·racereadpc(void *addr, void *pc)
+runtime·racewritepc(void *addr, void *callpc, void *pc)
{
- if(!onstack((uintptr)addr)) {
- m->racecall = true;
- runtime∕race·Read(g->goid-1, addr, pc);
- m->racecall = false;
- }
+ memoryaccess(addr, (uintptr)callpc, (uintptr)pc, true);
+}
+
+void
+runtime·racereadpc(void *addr, void *callpc, void *pc)
+{
+ memoryaccess(addr, (uintptr)callpc, (uintptr)pc, false);
}
void
void
runtime·RaceRead(void *addr)
{
- runtime·racereadpc(addr, runtime·getcallerpc(&addr));
+ memoryaccess(addr, 0, (uintptr)runtime·getcallerpc(&addr), false);
}
// func RaceWrite(addr unsafe.Pointer)
void
runtime·RaceWrite(void *addr)
{
- runtime·racewritepc(addr, runtime·getcallerpc(&addr));
+ memoryaccess(addr, 0, (uintptr)runtime·getcallerpc(&addr), true);
}
// func RaceDisable()
void runtime·racefree(void *p);
void runtime·racegostart(int32 goid, void *pc);
void runtime·racegoend(int32 goid);
-void runtime·racewritepc(void *addr, void *pc);
-void runtime·racereadpc(void *addr, void *pc);
+void runtime·racewritepc(void *addr, void *callpc, void *pc);
+void runtime·racereadpc(void *addr, void *callpc, void *pc);
void runtime·racefingo(void);
void runtime·raceacquire(void *addr);
void runtime·raceacquireg(G *gp, void *addr);
}
void
-runtime·racewritepc(void *addr, void *pc)
+runtime·racewritepc(void *addr, void *callpc, void *pc)
{
USED(addr);
+ USED(callpc);
USED(pc);
}
void
-runtime·racereadpc(void *addr, void *pc)
+runtime·racereadpc(void *addr, void *callpc, void *pc)
{
USED(addr);
+ USED(callpc);
USED(pc);
}
if(raceenabled) {
pc = runtime·getcallerpc(&t);
for(i=0; i<x.len; i++)
- runtime·racereadpc(x.array + i*t->elem->size, pc);
+ runtime·racereadpc(x.array + i*t->elem->size, pc, runtime·appendslice);
for(i=x.len; i<x.cap; i++)
- runtime·racewritepc(x.array + i*t->elem->size, pc);
+ runtime·racewritepc(x.array + i*t->elem->size, pc, runtime·appendslice);
for(i=0; i<y.len; i++)
- runtime·racereadpc(y.array + i*t->elem->size, pc);
+ runtime·racereadpc(y.array + i*t->elem->size, pc, runtime·appendslice);
}
if(m > x.cap)
if(raceenabled) {
pc = runtime·getcallerpc(&t);
for(i=0; i<x.len; i++)
- runtime·racereadpc(x.array + i*t->elem->size, pc);
+ runtime·racereadpc(x.array + i*t->elem->size, pc, runtime·appendstr);
for(i=x.len; i<x.cap; i++)
- runtime·racewritepc(x.array + i*t->elem->size, pc);
+ runtime·racewritepc(x.array + i*t->elem->size, pc, runtime·appendstr);
}
if(m > x.cap)
if(raceenabled) {
pc = runtime·getcallerpc(&t);
for(i=0; i<old.len; i++)
- runtime·racewritepc(old.array + i*t->elem->size, pc);
+ runtime·racewritepc(old.array + i*t->elem->size, pc, runtime·growslice);
}
growslice1(t, old, cap, &ret);
if(raceenabled) {
pc = runtime·getcallerpc(&to);
for(i=0; i<ret; i++) {
- runtime·racewritepc(to.array + i*width, pc);
- runtime·racereadpc(fm.array + i*width, pc);
+ runtime·racewritepc(to.array + i*width, pc, runtime·copy);
+ runtime·racereadpc(fm.array + i*width, pc, runtime·copy);
}
}
if(raceenabled) {
pc = runtime·getcallerpc(&to);
for(i=0; i<ret; i++) {
- runtime·racewritepc(to.array + i, pc);
+ runtime·racewritepc(to.array + i, pc, runtime·slicestringcopy);
}
}