aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/proc.c
diff options
context:
space:
mode:
authorDmitriy Vyukov <dvyukov@google.com>2013-06-03 13:20:17 +0400
committerDmitriy Vyukov <dvyukov@google.com>2013-06-03 13:20:17 +0400
commit354ec5166668cae9be899c82e20c38b32ae3b867 (patch)
tree7cc65028b2528aafbb1b3f60476a7c552a4f33a5 /src/pkg/runtime/proc.c
parentf5becf4233bd12506cbfcb9cbc04b5968ac11ae0 (diff)
downloadgo-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.c41
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