mirror of
https://github.com/golang/go
synced 2024-11-13 19:40:22 -07:00
runtime: introduce entersyscallblock()
In preparation for the new scheduler. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/7386044
This commit is contained in:
parent
e5b0bcebdb
commit
e25f19a638
@ -360,7 +360,7 @@ getprofile(Profile *p)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
// Wait for new log.
|
// Wait for new log.
|
||||||
runtime·entersyscall();
|
runtime·entersyscallblock();
|
||||||
runtime·notesleep(&p->wait);
|
runtime·notesleep(&p->wait);
|
||||||
runtime·exitsyscall();
|
runtime·exitsyscall();
|
||||||
runtime·noteclear(&p->wait);
|
runtime·noteclear(&p->wait);
|
||||||
|
@ -424,7 +424,7 @@ runtime·MHeap_Scavenger(void)
|
|||||||
h = runtime·mheap;
|
h = runtime·mheap;
|
||||||
for(k=0;; k++) {
|
for(k=0;; k++) {
|
||||||
runtime·noteclear(¬e);
|
runtime·noteclear(¬e);
|
||||||
runtime·entersyscall();
|
runtime·entersyscallblock();
|
||||||
runtime·notetsleep(¬e, tick);
|
runtime·notetsleep(¬e, tick);
|
||||||
runtime·exitsyscall();
|
runtime·exitsyscall();
|
||||||
|
|
||||||
@ -438,7 +438,7 @@ runtime·MHeap_Scavenger(void)
|
|||||||
runtime·noteclear(¬e);
|
runtime·noteclear(¬e);
|
||||||
notep = ¬e;
|
notep = ¬e;
|
||||||
runtime·newproc1((byte*)forcegchelper, (byte*)¬ep, sizeof(notep), 0, runtime·MHeap_Scavenger);
|
runtime·newproc1((byte*)forcegchelper, (byte*)¬ep, sizeof(notep), 0, runtime·MHeap_Scavenger);
|
||||||
runtime·entersyscall();
|
runtime·entersyscallblock();
|
||||||
runtime·notesleep(¬e);
|
runtime·notesleep(¬e);
|
||||||
runtime·exitsyscall();
|
runtime·exitsyscall();
|
||||||
if(trace)
|
if(trace)
|
||||||
|
@ -1049,6 +1049,59 @@ runtime·entersyscall(void)
|
|||||||
schedunlock();
|
schedunlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The same as runtime·entersyscall(), but with a hint that the syscall is blocking.
|
||||||
|
// The hint is ignored at the moment, and it's just a copy of runtime·entersyscall().
|
||||||
|
#pragma textflag 7
|
||||||
|
void
|
||||||
|
runtime·entersyscallblock(void)
|
||||||
|
{
|
||||||
|
uint32 v;
|
||||||
|
|
||||||
|
if(m->profilehz > 0)
|
||||||
|
runtime·setprof(false);
|
||||||
|
|
||||||
|
// Leave SP around for gc and traceback.
|
||||||
|
runtime·gosave(&g->sched);
|
||||||
|
g->gcsp = g->sched.sp;
|
||||||
|
g->gcstack = g->stackbase;
|
||||||
|
g->gcguard = g->stackguard;
|
||||||
|
g->status = Gsyscall;
|
||||||
|
if(g->gcsp < g->gcguard-StackGuard || g->gcstack < g->gcsp) {
|
||||||
|
// runtime·printf("entersyscall inconsistent %p [%p,%p]\n",
|
||||||
|
// g->gcsp, g->gcguard-StackGuard, g->gcstack);
|
||||||
|
runtime·throw("entersyscall");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fast path.
|
||||||
|
// The slow path inside the schedlock/schedunlock will get
|
||||||
|
// through without stopping if it does:
|
||||||
|
// mcpu--
|
||||||
|
// gwait not true
|
||||||
|
// waitstop && mcpu <= mcpumax not true
|
||||||
|
// If we can do the same with a single atomic add,
|
||||||
|
// then we can skip the locks.
|
||||||
|
v = runtime·xadd(&runtime·sched.atomic, -1<<mcpuShift);
|
||||||
|
if(!atomic_gwaiting(v) && (!atomic_waitstop(v) || atomic_mcpu(v) > atomic_mcpumax(v)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
schedlock();
|
||||||
|
v = runtime·atomicload(&runtime·sched.atomic);
|
||||||
|
if(atomic_gwaiting(v)) {
|
||||||
|
matchmg();
|
||||||
|
v = runtime·atomicload(&runtime·sched.atomic);
|
||||||
|
}
|
||||||
|
if(atomic_waitstop(v) && atomic_mcpu(v) <= atomic_mcpumax(v)) {
|
||||||
|
runtime·xadd(&runtime·sched.atomic, -1<<waitstopShift);
|
||||||
|
runtime·notewakeup(&runtime·sched.stopped);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-save sched in case one of the calls
|
||||||
|
// (notewakeup, matchmg) triggered something using it.
|
||||||
|
runtime·gosave(&g->sched);
|
||||||
|
|
||||||
|
schedunlock();
|
||||||
|
}
|
||||||
|
|
||||||
// The goroutine g exited its system call.
|
// The goroutine g exited its system call.
|
||||||
// Arrange for it to run on a cpu again.
|
// Arrange for it to run on a cpu again.
|
||||||
// This is called only from the go syscall library, not
|
// This is called only from the go syscall library, not
|
||||||
|
@ -692,6 +692,7 @@ M* runtime·newm(void);
|
|||||||
void runtime·goexit(void);
|
void runtime·goexit(void);
|
||||||
void runtime·asmcgocall(void (*fn)(void*), void*);
|
void runtime·asmcgocall(void (*fn)(void*), void*);
|
||||||
void runtime·entersyscall(void);
|
void runtime·entersyscall(void);
|
||||||
|
void runtime·entersyscallblock(void);
|
||||||
void runtime·exitsyscall(void);
|
void runtime·exitsyscall(void);
|
||||||
G* runtime·newproc1(byte*, byte*, int32, int32, void*);
|
G* runtime·newproc1(byte*, byte*, int32, int32, void*);
|
||||||
bool runtime·sigsend(int32 sig);
|
bool runtime·sigsend(int32 sig);
|
||||||
|
@ -105,7 +105,7 @@ func signal_recv() (m uint32) {
|
|||||||
new = HASWAITER;
|
new = HASWAITER;
|
||||||
if(runtime·cas(&sig.state, old, new)) {
|
if(runtime·cas(&sig.state, old, new)) {
|
||||||
if (new == HASWAITER) {
|
if (new == HASWAITER) {
|
||||||
runtime·entersyscall();
|
runtime·entersyscallblock();
|
||||||
runtime·notesleep(&sig);
|
runtime·notesleep(&sig);
|
||||||
runtime·exitsyscall();
|
runtime·exitsyscall();
|
||||||
runtime·noteclear(&sig);
|
runtime·noteclear(&sig);
|
||||||
|
@ -200,7 +200,7 @@ timerproc(void)
|
|||||||
timers.sleeping = true;
|
timers.sleeping = true;
|
||||||
runtime·noteclear(&timers.waitnote);
|
runtime·noteclear(&timers.waitnote);
|
||||||
runtime·unlock(&timers);
|
runtime·unlock(&timers);
|
||||||
runtime·entersyscall();
|
runtime·entersyscallblock();
|
||||||
runtime·notetsleep(&timers.waitnote, delta);
|
runtime·notetsleep(&timers.waitnote, delta);
|
||||||
runtime·exitsyscall();
|
runtime·exitsyscall();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user