]> Cypherpunks repositories - gostls13.git/commitdiff
synch chan
authorKen Thompson <ken@golang.org>
Mon, 14 Jul 2008 21:34:27 +0000 (14:34 -0700)
committerKen Thompson <ken@golang.org>
Mon, 14 Jul 2008 21:34:27 +0000 (14:34 -0700)
SVN=127057

src/runtime/proc.c [new file with mode: 0644]

diff --git a/src/runtime/proc.c b/src/runtime/proc.c
new file mode 100644 (file)
index 0000000..fee6255
--- /dev/null
@@ -0,0 +1,264 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+
+static int32   debug   = 0;
+
+void
+sys·goexit(void)
+{
+//prints("goexit goid=");
+//sys·printint(g->goid);
+//prints("\n");
+       g->status = Gdead;
+       sys·gosched();
+}
+
+void
+sys·newproc(int32 siz, byte* fn, byte* arg0)
+{
+       byte *stk, *sp;
+       G *newg;
+
+//prints("newproc siz=");
+//sys·printint(siz);
+//prints(" fn=");
+//sys·printpointer(fn);
+
+       siz = (siz+7) & ~7;
+       if(siz > 1024) {
+               prints("sys·newproc: too many args: ");
+               sys·printint(siz);
+               prints("\n");
+               sys·panicl(123);
+       }
+
+       newg = mal(sizeof(G));
+       stk = mal(4096);
+       newg->stackguard = stk+160;
+
+       sp = stk + 4096 - 4*8;
+       newg->stackbase = sp;
+
+       sp -= siz;
+       mcpy(sp, (byte*)&arg0, siz);
+
+       sp -= 8;
+       *(byte**)sp = (byte*)sys·goexit;
+
+       sp -= 8;        // retpc used by gogo
+       newg->sched.SP = sp;
+       newg->sched.PC = fn;
+
+       goidgen++;
+       newg->goid = goidgen;
+
+       newg->status = Grunnable;
+       newg->alllink = allg;
+       allg = newg;
+
+//prints(" goid=");
+//sys·printint(newg->goid);
+//prints("\n");
+}
+
+G*
+select(void)
+{
+       G *gp, *bestg;
+
+       bestg = nil;
+       for(gp=allg; gp!=nil; gp=gp->alllink) {
+               if(gp->status != Grunnable)
+                       continue;
+               if(bestg == nil || gp->pri < bestg->pri)
+                       bestg = gp;
+       }
+       if(bestg != nil)
+               bestg->pri++;
+       return bestg;
+}
+
+void
+gom0init(void)
+{
+       gosave(&m->sched);
+       sys·gosched();
+}
+
+void
+sys·gosched(void)
+{
+       G* gp;
+
+       if(g != m->g0) {
+               if(gosave(&g->sched))
+                       return;
+               g = m->g0;
+               gogo(&m->sched);
+       }
+       gp = select();
+       if(gp == nil) {
+//             prints("sched: no more work\n");
+               sys·exit(0);
+       }
+
+       m->curg = gp;
+       g = gp;
+       gogo(&gp->sched);
+}
+
+//
+// the calling sequence for a routine that
+// needs N bytes stack, A args.
+//
+//     N1 = (N+160 > 4096)? N+160: 0
+//     A1 = A
+//
+// if N <= 75
+//     CMPQ    SP, 0(R15)
+//     JHI     4(PC)
+//     MOVQ    $(N1<<0) | (A1<<32)), AX
+//     MOVQ    AX, 0(R14)
+//     CALL    sys·morestack(SB)
+//
+// if N > 75
+//     LEAQ    (-N-75)(SP), AX
+//     CMPQ    AX, 0(R15)
+//     JHI     4(PC)
+//     MOVQ    $(N1<<0) | (A1<<32)), AX
+//     MOVQ    AX, 0(R14)
+//     CALL    sys·morestack(SB)
+//
+
+void
+oldstack(void)
+{
+       Stktop *top;
+       uint32 siz2;
+       byte *sp;
+
+// prints("oldstack m->cret = ");
+// sys·printpointer((void*)m->cret);
+// prints("\n");
+
+       top = (Stktop*)m->curg->stackbase;
+
+       m->curg->stackbase = top->oldbase;
+       m->curg->stackguard = top->oldguard;
+       siz2 = (top->magic>>32) & 0xffffLL;
+
+       sp = (byte*)top;
+       if(siz2 > 0) {
+               siz2 = (siz2+7) & ~7;
+               sp -= siz2;
+               mcpy(top->oldsp+16, sp, siz2);
+       }
+
+       m->morestack.SP = top->oldsp+8;
+       m->morestack.PC = (byte*)(*(uint64*)(top->oldsp+8));
+
+// prints("oldstack sp=");
+// sys·printpointer(m->morestack.SP);
+// prints(" pc=");
+// sys·printpointer(m->morestack.PC);
+// prints("\n");
+
+       gogoret(&m->morestack, m->cret);
+}
+
+void
+newstack(void)
+{
+       int32 siz1, siz2;
+       Stktop *top;
+       byte *stk, *sp;
+       void (*fn)(void);
+
+       siz1 = m->morearg & 0xffffffffLL;
+       siz2 = (m->morearg>>32) & 0xffffLL;
+
+// prints("newstack siz1=");
+// sys·printint(siz1);
+// prints(" siz2=");
+// sys·printint(siz2);
+// prints(" moresp=");
+// sys·printpointer(m->moresp);
+// prints("\n");
+
+       if(siz1 < 4096)
+               siz1 = 4096;
+       stk = mal(siz1 + 1024);
+       stk += 512;
+
+       top = (Stktop*)(stk+siz1-sizeof(*top));
+
+       top->oldbase = m->curg->stackbase;
+       top->oldguard = m->curg->stackguard;
+       top->oldsp = m->moresp;
+       top->magic = m->morearg;
+
+       m->curg->stackbase = (byte*)top;
+       m->curg->stackguard = stk + 160;
+
+       sp = (byte*)top;
+       
+       if(siz2 > 0) {
+               siz2 = (siz2+7) & ~7;
+               sp -= siz2;
+               mcpy(sp, m->moresp+16, siz2);
+       }
+
+       g = m->curg;
+       fn = (void(*)(void))(*(uint64*)m->moresp);
+
+// prints("fn=");
+// sys·printpointer(fn);
+// prints("\n");
+
+       setspgoto(sp, fn, retfromnewstack);
+
+       *(int32*)345 = 123;     // never return
+}
+
+void
+sys·morestack(uint64 u)
+{
+       while(g == m->g0) {
+               // very bad news
+               *(int32*)123 = 123;
+       }
+
+       g = m->g0;
+       m->moresp = (byte*)(&u-1);
+       setspgoto(m->sched.SP, newstack, nil);
+
+       *(int32*)234 = 123;     // never return
+}
+
+G*
+dequeue(WaitQ *q)
+{
+       G *gp;
+
+       gp = q->first;
+       if(gp == nil)
+               return nil;
+       q->first = gp->qlink;
+       return gp;
+}
+
+void
+enqueue(WaitQ *q, G *gp)
+{
+       gp->qlink = nil;
+       if(q->first == nil) {
+               q->first = gp;
+               q->last = gp;
+               return;
+       }
+       q->last->qlink = gp;
+       q->last = gp;
+}