Skip to content

Commit a1695d2

Browse files
committed
runtime: use custom thunks for race calls instead of cgo
Implement custom assembly thunks for hot race calls (memory accesses and function entry/exit). The thunks extract caller pc, verify that the address is in heap or global and switch to g0 stack. Before: ok regexp 3.692s ok compress/bzip2 9.461s ok encoding/json 6.380s After: ok regexp 2.229s (-40%) ok compress/bzip2 4.703s (-50%) ok encoding/json 3.629s (-43%) For comparison, normal non-race build: ok regexp 0.348s ok compress/bzip2 0.304s ok encoding/json 0.661s Race build: ok regexp 2.229s (+540%) ok compress/bzip2 4.703s (+1447%) ok encoding/json 3.629s (+449%) Also removes some race-related special cases from cgocall and scheduler. In long-term it will allow to remove cyclic runtime/race dependency on cmd/cgo. Fixes #4249. Fixes #7460. Update #6508 Update #6688 R=iant, rsc, bradfitz CC=golang-codereviews https://golang.org/cl/55100044
1 parent 5db255f commit a1695d2

13 files changed

+355
-438
lines changed

src/pkg/runtime/cgocall.c

+5-22
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,6 @@ runtime·cgocall(void (*fn)(void*), void *arg)
100100
Defer d;
101101
SEHUnwind sehunwind;
102102

103-
if(m->racecall) {
104-
runtime·asmcgocall(fn, arg);
105-
return;
106-
}
107-
108103
if(!runtime·iscgo && !Solaris && !Windows)
109104
runtime·throw("cgocall unavailable");
110105

@@ -256,21 +251,9 @@ runtime·cgocallbackg(void)
256251
runtime·exit(2);
257252
}
258253

259-
if(m->racecall) {
260-
// We were not in syscall, so no need to call runtime·exitsyscall.
261-
// However we must set m->locks for the following reason.
262-
// Race detector runtime makes __tsan_symbolize cgo callback
263-
// holding internal mutexes. The mutexes are not cooperative with Go scheduler.
264-
// So if we deschedule a goroutine that holds race detector internal mutex
265-
// (e.g. preempt it), another goroutine will deadlock trying to acquire the same mutex.
266-
m->locks++;
267-
runtime·cgocallbackg1();
268-
m->locks--;
269-
} else {
270-
runtime·exitsyscall(); // coming out of cgo call
271-
runtime·cgocallbackg1();
272-
runtime·entersyscall(); // going back to cgo call
273-
}
254+
runtime·exitsyscall(); // coming out of cgo call
255+
runtime·cgocallbackg1();
256+
runtime·entersyscall(); // going back to cgo call
274257
}
275258

276259
void
@@ -292,14 +275,14 @@ runtime·cgocallbackg1(void)
292275
d.special = true;
293276
g->defer = &d;
294277

295-
if(raceenabled && !m->racecall)
278+
if(raceenabled)
296279
runtime·raceacquire(&cgosync);
297280

298281
// Invoke callback.
299282
cb = CBARGS;
300283
runtime·newstackcall(cb->fn, cb->arg, cb->argsize);
301284

302-
if(raceenabled && !m->racecall)
285+
if(raceenabled)
303286
runtime·racereleasemerge(&cgosync);
304287

305288
// Pop defer.

src/pkg/runtime/malloc.goc

-3
Original file line numberDiff line numberDiff line change
@@ -295,9 +295,6 @@ runtime·free(void *v)
295295
if(size < TinySize)
296296
runtime·throw("freeing too small block");
297297

298-
if(raceenabled)
299-
runtime·racefree(v);
300-
301298
// Ensure that the span is swept.
302299
// If we free into an unswept span, we will corrupt GC bitmaps.
303300
runtime·MSpan_EnsureSwept(s);

src/pkg/runtime/proc.c

-5
Original file line numberDiff line numberDiff line change
@@ -2235,11 +2235,6 @@ runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp, M *mp)
22352235
((uint8*)runtime·gogo <= pc && pc < (uint8*)runtime·gogo + RuntimeGogoBytes))
22362236
traceback = false;
22372237

2238-
// Race detector calls asmcgocall w/o entersyscall/exitsyscall,
2239-
// we can not currently unwind through asmcgocall.
2240-
if(mp != nil && mp->racecall)
2241-
traceback = false;
2242-
22432238
runtime·lock(&prof);
22442239
if(prof.fn == nil) {
22452240
runtime·unlock(&prof);

0 commit comments

Comments
 (0)