#include "runtime.h"
#include "arch.h"
#include "go-type.h"
-#include "race.h"
#include "malloc.h"
#include "chan.h"
static void dequeueg(WaitQ*);
static SudoG* dequeue(WaitQ*);
static void enqueue(WaitQ*, SudoG*);
-static void racesync(Hchan*, SudoG*);
static Hchan*
makechan(ChanType *t, int64 hint)
static bool
chansend(ChanType *t, Hchan *c, byte *ep, bool block, void *pc)
{
+ USED(pc);
SudoG *sg;
SudoG mysg;
G* gp;
g = runtime_g();
- if(raceenabled)
- runtime_racereadobjectpc(ep, t->__element_type, runtime_getcallerpc(&t), chansend);
-
if(c == nil) {
USED(t);
if(!block)
}
runtime_lock(c);
- if(raceenabled)
- runtime_racereadpc(c, pc, chansend);
if(c->closed)
goto closed;
sg = dequeue(&c->recvq);
if(sg != nil) {
- if(raceenabled)
- racesync(c, sg);
runtime_unlock(c);
gp = sg->g;
goto asynch;
}
- if(raceenabled) {
- runtime_raceacquire(chanbuf(c, c->sendx));
- runtime_racerelease(chanbuf(c, c->sendx));
- }
-
runtime_memmove(chanbuf(c, c->sendx), ep, c->elemsize);
if(++c->sendx == c->dataqsiz)
c->sendx = 0;
if(runtime_gcwaiting())
runtime_gosched();
- // raceenabled: don't need to check ep, as it is always on the stack.
-
if(debug)
runtime_printf("chanrecv: chan=%p\n", c);
sg = dequeue(&c->sendq);
if(sg != nil) {
- if(raceenabled)
- racesync(c, sg);
runtime_unlock(c);
if(ep != nil)
goto asynch;
}
- if(raceenabled) {
- runtime_raceacquire(chanbuf(c, c->recvx));
- runtime_racerelease(chanbuf(c, c->recvx));
- }
-
if(ep != nil)
runtime_memmove(ep, chanbuf(c, c->recvx), c->elemsize);
runtime_memclr(chanbuf(c, c->recvx), c->elemsize);
runtime_memclr(ep, c->elemsize);
if(received != nil)
*received = false;
- if(raceenabled)
- runtime_raceacquire(c);
runtime_unlock(c);
if(mysg.releasetime > 0)
runtime_blockevent(mysg.releasetime - t0, 2);
break;
case CaseSend:
- if(raceenabled)
- runtime_racereadpc(c, runtime_selectgo, chansend);
if(c->closed)
goto sclose;
if(c->dataqsiz > 0) {
*cas->receivedp = true;
}
- if(raceenabled) {
- if(cas->kind == CaseRecv && cas->sg.elem != nil)
- runtime_racewriteobjectpc(cas->sg.elem, c->elemtype, selectgo, chanrecv);
- else if(cas->kind == CaseSend)
- runtime_racereadobjectpc(cas->sg.elem, c->elemtype, selectgo, chansend);
- }
-
selunlock(sel);
goto retc;
asyncrecv:
// can receive from buffer
- if(raceenabled) {
- if(cas->sg.elem != nil)
- runtime_racewriteobjectpc(cas->sg.elem, c->elemtype, selectgo, chanrecv);
- runtime_raceacquire(chanbuf(c, c->recvx));
- runtime_racerelease(chanbuf(c, c->recvx));
- }
if(cas->receivedp != nil)
*cas->receivedp = true;
if(cas->sg.elem != nil)
asyncsend:
// can send to buffer
- if(raceenabled) {
- runtime_raceacquire(chanbuf(c, c->sendx));
- runtime_racerelease(chanbuf(c, c->sendx));
- runtime_racereadobjectpc(cas->sg.elem, c->elemtype, selectgo, chansend);
- }
runtime_memmove(chanbuf(c, c->sendx), cas->sg.elem, c->elemsize);
if(++c->sendx == c->dataqsiz)
c->sendx = 0;
syncrecv:
// can receive from sleeping sender (sg)
- if(raceenabled) {
- if(cas->sg.elem != nil)
- runtime_racewriteobjectpc(cas->sg.elem, c->elemtype, selectgo, chanrecv);
- racesync(c, sg);
- }
selunlock(sel);
if(debug)
runtime_printf("syncrecv: sel=%p c=%p o=%d\n", sel, c, o);
*cas->receivedp = false;
if(cas->sg.elem != nil)
runtime_memclr(cas->sg.elem, c->elemsize);
- if(raceenabled)
- runtime_raceacquire(c);
goto retc;
syncsend:
// can send to sleeping receiver (sg)
- if(raceenabled) {
- runtime_racereadobjectpc(cas->sg.elem, c->elemtype, selectgo, chansend);
- racesync(c, sg);
- }
selunlock(sel);
if(debug)
runtime_printf("syncsend: sel=%p c=%p o=%d\n", sel, c, o);
static void
closechan(Hchan *c, void *pc)
{
+ USED(pc);
SudoG *sg;
G* gp;
runtime_unlock(c);
runtime_panicstring("close of closed channel");
}
-
- if(raceenabled) {
- runtime_racewritepc(c, pc, runtime_closechan);
- runtime_racerelease(c);
- }
-
c->closed = true;
// release all readers
q->last->link = sgp;
q->last = sgp;
}
-
-static void
-racesync(Hchan *c, SudoG *sg)
-{
- runtime_racerelease(chanbuf(c, 0));
- runtime_raceacquireg(sg->g, chanbuf(c, 0));
- runtime_racereleaseg(sg->g, chanbuf(c, 0));
- runtime_raceacquire(chanbuf(c, 0));
-}
#include "malloc.h"
#include "interface.h"
#include "go-type.h"
-#include "race.h"
// Map gccgo field names to gc field names.
// Eface aka __go_empty_interface.
if(UseSpanType && !(flag & FlagNoScan) && typ != 0)
settype(s, v, typ);
- if(raceenabled)
- runtime_racemalloc(v, size);
-
if(runtime_debug.allocfreetrace)
runtime_tracealloc(v, size, typ);
h->arena_used += n;
runtime_MHeap_MapBits(h);
runtime_MHeap_MapSpans(h);
- if(raceenabled)
- runtime_racemapshadow(p, n);
if(((uintptr)p & (PageSize-1)) != 0)
runtime_throw("misrounded allocation in MHeap_SysAlloc");
h->arena_end = p_end;
runtime_MHeap_MapBits(h);
runtime_MHeap_MapSpans(h);
- if(raceenabled)
- runtime_racemapshadow(p, n);
}
if(((uintptr)p & (PageSize-1)) != 0)
+++ /dev/null
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Definitions related to data race detection.
-
-#ifdef RACE
-enum { raceenabled = 1 };
-#else
-enum { raceenabled = 0 };
-#endif
-
-// Initialize race detection subsystem.
-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);
-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, void *callpc, void *pc);
-void runtime_racereadrangepc(void *addr, uintptr sz, void *callpc, void *pc);
-void runtime_racereadobjectpc(void *addr, const Type *t, void *callpc, void *pc);
-void runtime_racewriteobjectpc(void *addr, const Type *t, void *callpc, void *pc);
-void runtime_racefingo(void);
-void runtime_raceacquire(void *addr);
-void runtime_raceacquireg(G *gp, void *addr);
-void runtime_racerelease(void *addr);
-void runtime_racereleaseg(G *gp, void *addr);
-void runtime_racereleasemerge(void *addr);
-void runtime_racereleasemergeg(G *gp, void *addr);