mirror of
https://github.com/golang/go
synced 2024-11-26 02:27:56 -07:00
runtime: introduce preemption function (not used for now)
This is part of preemptive scheduler. R=golang-dev, cshapiro, iant CC=golang-dev https://golang.org/cl/9843046
This commit is contained in:
parent
f5becf4233
commit
354ec51666
@ -110,6 +110,8 @@ static G* globrunqget(P*);
|
|||||||
static P* pidleget(void);
|
static P* pidleget(void);
|
||||||
static void pidleput(P*);
|
static void pidleput(P*);
|
||||||
static void injectglist(G*);
|
static void injectglist(G*);
|
||||||
|
static void preemptall(void);
|
||||||
|
static void preemptone(P*);
|
||||||
|
|
||||||
// The bootstrap sequence is:
|
// The bootstrap sequence is:
|
||||||
//
|
//
|
||||||
@ -2073,6 +2075,45 @@ retake(uint32 *ticks)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tell all goroutines that they have been preempted and they should stop.
|
||||||
|
// This function is purely best-effort. It can fail to inform a goroutine if a
|
||||||
|
// processor just started running it.
|
||||||
|
// No locks need to be held.
|
||||||
|
static void
|
||||||
|
preemptall(void)
|
||||||
|
{
|
||||||
|
P *p;
|
||||||
|
int32 i;
|
||||||
|
|
||||||
|
for(i = 0; i < runtime·gomaxprocs; i++) {
|
||||||
|
p = runtime·allp[i];
|
||||||
|
if(p == nil || p->status != Prunning)
|
||||||
|
continue;
|
||||||
|
preemptone(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell the goroutine running on processor P to stop.
|
||||||
|
// This function is purely best-effort. It can incorrectly fail to inform the
|
||||||
|
// goroutine. It can send inform the wrong goroutine. Even if it informs the
|
||||||
|
// correct goroutine, that goroutine might ignore the request if it is
|
||||||
|
// simultaneously executing runtime·newstack.
|
||||||
|
// No lock needs to be held.
|
||||||
|
static void
|
||||||
|
preemptone(P *p)
|
||||||
|
{
|
||||||
|
M *mp;
|
||||||
|
G *gp;
|
||||||
|
|
||||||
|
mp = p->m;
|
||||||
|
if(mp == nil || mp == m)
|
||||||
|
return;
|
||||||
|
gp = mp->curg;
|
||||||
|
if(gp == nil || gp == mp->g0)
|
||||||
|
return;
|
||||||
|
gp->stackguard0 = StackPreempt;
|
||||||
|
}
|
||||||
|
|
||||||
// Put mp on midle list.
|
// Put mp on midle list.
|
||||||
// Sched must be locked.
|
// Sched must be locked.
|
||||||
static void
|
static void
|
||||||
|
@ -105,4 +105,9 @@ enum {
|
|||||||
// The actual size can be smaller than this but cannot be larger.
|
// The actual size can be smaller than this but cannot be larger.
|
||||||
// Checked in proc.c's runtime.malg.
|
// Checked in proc.c's runtime.malg.
|
||||||
StackTop = 72,
|
StackTop = 72,
|
||||||
|
|
||||||
|
// Goroutine preemption request.
|
||||||
|
// Stored into g->stackguard0 to cause split stack check failure.
|
||||||
|
// Must be greater than any real sp.
|
||||||
|
StackPreempt = (uintptr)(intptr)0xfffffade,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user