diff options
| author | Dmitriy Vyukov <dvyukov@google.com> | 2013-06-03 13:20:17 +0400 |
|---|---|---|
| committer | Dmitriy Vyukov <dvyukov@google.com> | 2013-06-03 13:20:17 +0400 |
| commit | 354ec5166668cae9be899c82e20c38b32ae3b867 (patch) | |
| tree | 7cc65028b2528aafbb1b3f60476a7c552a4f33a5 /src/pkg/runtime/proc.c | |
| parent | f5becf4233bd12506cbfcb9cbc04b5968ac11ae0 (diff) | |
| download | go-354ec5166668cae9be899c82e20c38b32ae3b867.tar.xz | |
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
Diffstat (limited to 'src/pkg/runtime/proc.c')
| -rw-r--r-- | src/pkg/runtime/proc.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c index 206a3cba19..5b5d9b8a0b 100644 --- a/src/pkg/runtime/proc.c +++ b/src/pkg/runtime/proc.c @@ -110,6 +110,8 @@ static G* globrunqget(P*); static P* pidleget(void); static void pidleput(P*); static void injectglist(G*); +static void preemptall(void); +static void preemptone(P*); // The bootstrap sequence is: // @@ -2073,6 +2075,45 @@ retake(uint32 *ticks) 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. // Sched must be locked. static void |
