Skip to content

Commit 156e8b3

Browse files
committed
runtime: do not park sysmon thread if any goroutines are running
Sysmon thread parks if no goroutines are running (runtime.sched.npidle == runtime.gomaxprocs). Currently it's unparked when a goroutine enters syscall, it was enough to retake P's from blocking syscalls. But it's not enough for reliable goroutine preemption. We need to ensure that sysmon runs if any goroutines are running. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/12167043
1 parent e8018fb commit 156e8b3

File tree

1 file changed

+26
-4
lines changed

1 file changed

+26
-4
lines changed

src/pkg/runtime/proc.c

+26-4
Original file line numberDiff line numberDiff line change
@@ -1536,6 +1536,10 @@ exitsyscallfast(void)
15361536
if(runtime·sched.pidle) {
15371537
runtime·lock(&runtime·sched);
15381538
p = pidleget();
1539+
if(p && runtime·atomicload(&runtime·sched.sysmonwait)) {
1540+
runtime·atomicstore(&runtime·sched.sysmonwait, 0);
1541+
runtime·notewakeup(&runtime·sched.sysmonnote);
1542+
}
15391543
runtime·unlock(&runtime·sched);
15401544
if(p) {
15411545
acquirep(p);
@@ -1559,6 +1563,10 @@ exitsyscall0(G *gp)
15591563
p = pidleget();
15601564
if(p == nil)
15611565
globrunqput(gp);
1566+
else if(runtime·atomicload(&runtime·sched.sysmonwait)) {
1567+
runtime·atomicstore(&runtime·sched.sysmonwait, 0);
1568+
runtime·notewakeup(&runtime·sched.sysmonnote);
1569+
}
15621570
runtime·unlock(&runtime·sched);
15631571
if(p) {
15641572
acquirep(p);
@@ -1924,24 +1932,38 @@ static struct {
19241932
uintptr pcbuf[100];
19251933
} prof;
19261934

1935+
static void
1936+
System(void)
1937+
{
1938+
}
1939+
19271940
// Called if we receive a SIGPROF signal.
19281941
void
19291942
runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp)
19301943
{
19311944
int32 n;
1945+
bool traceback;
19321946

1933-
// Windows does profiling in a dedicated thread w/o m.
1934-
if(!Windows && (m == nil || m->mcache == nil))
1935-
return;
19361947
if(prof.fn == nil || prof.hz == 0)
19371948
return;
1949+
traceback = true;
1950+
// Windows does profiling in a dedicated thread w/o m.
1951+
if(!Windows && (m == nil || m->mcache == nil))
1952+
traceback = false;
1953+
if(gp == m->g0 || gp == m->gsignal)
1954+
traceback = false;
1955+
if(m != nil && m->racecall)
1956+
traceback = false;
19381957

19391958
runtime·lock(&prof);
19401959
if(prof.fn == nil) {
19411960
runtime·unlock(&prof);
19421961
return;
19431962
}
1944-
n = runtime·gentraceback((uintptr)pc, (uintptr)sp, (uintptr)lr, gp, 0, prof.pcbuf, nelem(prof.pcbuf), nil, nil, false);
1963+
n = 1;
1964+
prof.pcbuf[0] = (uintptr)pc;
1965+
if(traceback)
1966+
n = runtime·gentraceback((uintptr)pc, (uintptr)sp, (uintptr)lr, gp, 0, prof.pcbuf, nelem(prof.pcbuf), nil, nil, false);
19451967
if(n > 0)
19461968
prof.fn(prof.pcbuf, n);
19471969
runtime·unlock(&prof);

0 commit comments

Comments
 (0)