]> Cypherpunks repositories - gostls13.git/commitdiff
segmented stacks AND goroutines
authorKen Thompson <ken@golang.org>
Sat, 12 Jul 2008 02:16:39 +0000 (19:16 -0700)
committerKen Thompson <ken@golang.org>
Sat, 12 Jul 2008 02:16:39 +0000 (19:16 -0700)
SVN=126929

src/cmd/6g/gen.c
src/cmd/6l/pass.c
src/cmd/gc/sys.go
src/cmd/gc/sysimport.c
src/runtime/rt0_amd64.s
src/runtime/rt2_amd64.c
src/runtime/runtime.c
src/runtime/runtime.h
src/runtime/sys_amd64_darwin.s
src/runtime/sys_amd64_linux.s

index a7a5dc020153d4dff12b72231f6d794f4d26ec56..9049cb4c630e4de6f5e713c47198e00f8b2d6ac0 100644 (file)
@@ -28,7 +28,7 @@ if(newproc == N) {
        newproc = nod(ONAME, N, N);
        memset(newproc, 0, sizeof(*newproc));
        newproc->op = ONAME;
-       newproc->sym = pkglookup("_newproc", "sys");
+       newproc->sym = pkglookup("newproc", "sys");
        newproc->class = PEXTERN;
        newproc->addable = 1;
        newproc->ullman = 0;
@@ -603,10 +603,12 @@ ginscall(Node *f, int proc)
        if(proc) {
                nodreg(&reg, types[TINT64], D_AX);
                gins(ALEAQ, f, &reg);
-               nodreg(&reg, types[TINT64], D_BX);
+               gins(APUSHQ, &reg, N);
                nodconst(&con, types[TINT32], argsize(f->type));
-               gins(AMOVL, &con, &reg);
+               gins(APUSHQ, &con, N);
                gins(ACALL, N, newproc);
+               gins(APOPQ, N, &reg);
+               gins(APOPQ, N, &reg);
                return;
        }
        gins(ACALL, N, f);
index d5939089694cc3960252b8760b63fc11e4f4aedf..808cef1dc0380ab31761301cd0a93174089c7be0 100644 (file)
@@ -572,19 +572,20 @@ dostkoff(void)
        Sym *symmorestack;
 
        pmorestack = P;
-       symmorestack = lookup("_morestack", 0);
+       symmorestack = lookup("sys·morestack", 0);
 
        if(symmorestack->type == STEXT)
        for(p = firstp; p != P; p = p->link) {
                if(p->as == ATEXT) {
                        if(p->from.sym == symmorestack) {
                                pmorestack = p;
+                               p->from.scale |= NOSPLIT;
                                break;
                        }
                }
        }
        if(pmorestack == P)
-               diag("_morestack not defined");
+               diag("sys·morestack not defined");
 
        curframe = 0;
        curbecome = 0;
@@ -693,7 +694,7 @@ dostkoff(void)
                                p = appendp(p);
                                p->as = AJHI;
                                p->to.type = D_BRANCH;
-                               p->to.offset = 3;
+                               p->to.offset = 4;
                                q = p;
 
                                p = appendp(p);
@@ -707,6 +708,12 @@ dostkoff(void)
                                        p->from.offset = (autoffset+160) & ~7LL;
                                p->from.offset |= textarg<<32;
 
+                               p = appendp(p);
+                               p->as = AMOVQ;
+                               p->from.type = D_AX;
+                               p->to.type = D_INDIR+D_R14;
+                               p->to.offset = 8;
+
                                p = appendp(p);
                                p->as = ACALL;
                                p->to.type = D_BRANCH;
index f58a16128a167e47673c8a822611baf5e5e64367..ebb9351ea0b9a07a6e0c8cb411de8f900867472f 100644 (file)
@@ -44,6 +44,9 @@ func  mapaccess2(hmap *map[any]any, key any) (val any, pres bool);
 func   mapassign1(hmap *map[any]any, key any, val any);
 func   mapassign2(hmap *map[any]any, key any, val any, pres bool);
 
+func   gosched();
+func   goexit();
+
 func   readfile(string) (string, bool);        // read file into string; boolean status
 func   bytestorune(*byte, int32, int32) (int32, int32);        // convert bytes to runes       
 func   stringtorune(string, int32, int32) (int32, int32);      // convert bytes to runes       
@@ -93,6 +96,10 @@ export
        mapassign1
        mapassign2
 
+       // go routines
+       gosched
+       goexit
+
        // files
        readfile
 
index 9a87a8100d44a8bf315917c52090456e1a3a2935..91dd561c3b042831c194ab73d18e4c289aa3e3b1 100644 (file)
@@ -183,25 +183,35 @@ char*     sysimport =
        "type sys._esys_089 (sys._esys_090 sys._esys_091 sys._isys_489)\n"
        "var !sys.mapassign2 sys._esys_089\n"
        "type sys._esys_095 {}\n"
-       "type sys._osys_499 {_esys_496 sys.string _esys_497 sys.bool}\n"
-       "type sys._isys_501 {_esys_498 sys.string}\n"
-       "type sys._esys_094 (sys._esys_095 sys._osys_499 sys._isys_501)\n"
-       "var !sys.readfile sys._esys_094\n"
+       "type sys._esys_096 {}\n"
        "type sys._esys_097 {}\n"
-       "type sys._osys_510 {_esys_505 sys.int32 _esys_506 sys.int32}\n"
-       "type sys._esys_098 *sys.uint8\n"
-       "type sys._isys_512 {_esys_507 sys._esys_098 _esys_508 sys.int32 _esys_509 sys.int32}\n"
-       "type sys._esys_096 (sys._esys_097 sys._osys_510 sys._isys_512)\n"
-       "var !sys.bytestorune sys._esys_096\n"
+       "type sys._esys_094 (sys._esys_095 sys._esys_096 sys._esys_097)\n"
+       "var !sys.gosched sys._esys_094\n"
+       "type sys._esys_099 {}\n"
        "type sys._esys_100 {}\n"
-       "type sys._osys_523 {_esys_518 sys.int32 _esys_519 sys.int32}\n"
-       "type sys._isys_525 {_esys_520 sys.string _esys_521 sys.int32 _esys_522 sys.int32}\n"
-       "type sys._esys_099 (sys._esys_100 sys._osys_523 sys._isys_525)\n"
-       "var !sys.stringtorune sys._esys_099\n"
-       "type sys._esys_102 {}\n"
+       "type sys._esys_101 {}\n"
+       "type sys._esys_098 (sys._esys_099 sys._esys_100 sys._esys_101)\n"
+       "var !sys.goexit sys._esys_098\n"
        "type sys._esys_103 {}\n"
-       "type sys._isys_532 {_esys_531 sys.int32}\n"
-       "type sys._esys_101 (sys._esys_102 sys._esys_103 sys._isys_532)\n"
-       "var !sys.exit sys._esys_101\n"
+       "type sys._osys_501 {_esys_498 sys.string _esys_499 sys.bool}\n"
+       "type sys._isys_503 {_esys_500 sys.string}\n"
+       "type sys._esys_102 (sys._esys_103 sys._osys_501 sys._isys_503)\n"
+       "var !sys.readfile sys._esys_102\n"
+       "type sys._esys_105 {}\n"
+       "type sys._osys_512 {_esys_507 sys.int32 _esys_508 sys.int32}\n"
+       "type sys._esys_106 *sys.uint8\n"
+       "type sys._isys_514 {_esys_509 sys._esys_106 _esys_510 sys.int32 _esys_511 sys.int32}\n"
+       "type sys._esys_104 (sys._esys_105 sys._osys_512 sys._isys_514)\n"
+       "var !sys.bytestorune sys._esys_104\n"
+       "type sys._esys_108 {}\n"
+       "type sys._osys_525 {_esys_520 sys.int32 _esys_521 sys.int32}\n"
+       "type sys._isys_527 {_esys_522 sys.string _esys_523 sys.int32 _esys_524 sys.int32}\n"
+       "type sys._esys_107 (sys._esys_108 sys._osys_525 sys._isys_527)\n"
+       "var !sys.stringtorune sys._esys_107\n"
+       "type sys._esys_110 {}\n"
+       "type sys._esys_111 {}\n"
+       "type sys._isys_534 {_esys_533 sys.int32}\n"
+       "type sys._esys_109 (sys._esys_110 sys._esys_111 sys._isys_534)\n"
+       "var !sys.exit sys._esys_109\n"
        "))\n"
 ;
index 13883ebff9c22ef2dcb62c8b83c29c44149afd5e..1a4e8d5a01f755865d14796b8aa4e62078f4a3d7 100644 (file)
@@ -16,206 +16,78 @@ TEXT       _rt0_amd64(SB),7,$-8
 
        // allocate the per-user and per-mach blocks
 
-       LEAQ    peruser<>(SB), R15      // dedicated u. register
-       LEAQ    permach<>(SB), R14      // dedicated m. register
+       LEAQ    m0<>(SB), R14           // dedicated m. register
+       LEAQ    g0(SB), R15             // dedicated g. register
+       MOVQ    R15, 0(R14)             // m has pointer to its g0
 
-       LEAQ    (-4096+104+4*8)(SP), AX
-       MOVQ    AX, 0(R15)              // 0(R15) is stack limit (w 104b guard)
-
-       MOVL    $1024, AX
-       MOVL    AX, 0(SP)
-       CALL    mal(SB)
-
-       LEAQ    104(AX), BX
-       MOVQ    BX, 0(R14)              // 0(R14) is limit of istack (w 104b guard)
+       // create istack out of the given (operating system) stack
 
-       ADDQ    0(SP), AX
-       LEAQ    (-4*8)(AX), BX
-       MOVQ    BX, 8(R14)              // 8(R14) is base of istack (w auto*4)
+       LEAQ    (-1024+104)(SP), AX
+       MOVQ    AX, 0(R15)              // 0(R15) is stack limit (w 104b guard)
+       MOVQ    SP, 8(R15)              // 8(R15) is base
 
        CALL    check(SB)
 
-       // process the arguments
-
        MOVL    16(SP), AX              // copy argc
        MOVL    AX, 0(SP)
        MOVQ    24(SP), AX              // copy argv
        MOVQ    AX, 8(SP)
        CALL    args(SB)
 
-       CALL    main·main(SB)
+       // create a new goroutine to start program
 
-       MOVQ    $0, AX
-       MOVQ    AX, 0(SP)               // exit status
-       CALL    sys·exit(SB)
+       PUSHQ   $main·main(SB)         // entry
+       PUSHQ   $16                     // arg size
+       CALL    sys·newproc(SB)
+       CALL    gom0init(SB)
+       POPQ    AX
+       POPQ    AX
 
-       CALL    notok(SB)               // fault
+       CALL    notok(SB)               // never returns
        RET
 
-//
-// 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     3(PC)
-//     MOVQ    $(N1<<0) | (A1<<32)), AX
-//     CALL    _morestack
-//
-// if N > 75
-//     LEAQ    (-N-75)(SP), AX
-//     CMPQ    AX, 0(R15)
-//     JHI     3(PC)
-//     MOVQ    $(N1<<0) | (A1<<32)), AX
-//     CALL    _morestack
-//
-
-TEXT   _morestack(SB), 7, $0
-       // save stuff on interrupt stack
-
-       MOVQ    8(R14), BX              // istack
-       MOVQ    SP, 8(BX)               // old SP
-       MOVQ    AX, 16(BX)              // magic number
-       MOVQ    0(R15), AX              // old limit
-       MOVQ    AX, 24(BX)
-
-       // switch and set up new limit
-
-       MOVQ    BX, SP
-       MOVQ    0(R14), AX              // istack limit
-       MOVQ    AX, 0(R15)
-
-       // allocate a new stack max of request and 4k
-
-       MOVL    16(SP), AX              // magic number
-       CMPL    AX, $4096
-       JHI     2(PC)
-       MOVL    $4096, AX
-       MOVL    AX, 0(SP)
-       CALL    mal(SB)
-
-       // switch to new stack
-
-       MOVQ    SP, BX                  // istack
-       ADDQ    $104, AX                // new stack limit
-       MOVQ    AX, 0(R15)
-       ADDQ    0(SP), AX
-       LEAQ    (-104-4*8)(AX), SP      // new SP
-       MOVQ    8(R15), AX
-       MOVQ    AX, 0(SP)               // old base
-       MOVQ    SP, 8(R15)              // new base
-
-       // copy needed stuff from istack to new stack
-
-       MOVQ    16(BX), AX              // magic number
-       MOVQ    AX, 16(SP)
-       MOVQ    24(BX), AX              // old limit
-       MOVQ    AX, 24(SP)
-       MOVQ    8(BX), AX               // old SP
-       MOVQ    AX, 8(SP)
-
-// are there parameters
-
-       MOVL    20(SP), CX              // copy count
-       CMPL    CX, $0
-       JEQ     easy
-
-// copy in
-
-       LEAQ    16(AX), SI
-       SUBQ    CX, SP
-       MOVQ    SP, DI
-       SHRL    $3, CX
-       CLD
-       REP
-       MOVSQ
-
-       // call the intended
-       CALL    0(AX)
-
-// copy out
-
-       MOVQ    SP, SI
-       MOVQ    8(R15), BX              // new base
-       MOVQ    8(BX), AX               // old SP
-       LEAQ    16(AX), DI
-       MOVL    20(BX), CX              // copy count
-       SHRL    $3, CX
-       CLD
-       REP
-       MOVSQ
-
-       // restore old SP and limit
-       MOVQ    8(R15), SP              // new base
-       MOVQ    24(SP), AX              // old limit
-       MOVQ    AX, 0(R15)
-       MOVQ    0(SP), AX
-       MOVQ    AX, 8(R15)              // old base
-       MOVQ    8(SP), AX               // old SP
-       MOVQ    AX, SP
-
-       // and return to the call behind mine
-       ADDQ    $8, SP
+TEXT   sys·breakpoint(SB),7,$-8
+       BYTE    $0xcc
        RET
 
-easy:
-       CALL    0(AX)
-
-       // restore old SP and limit
-       MOVQ    24(SP), AX              // old limit
-       MOVQ    AX, 0(R15)
-       MOVQ    0(SP), AX
-       MOVQ    AX, 8(R15)              // old base
-       MOVQ    8(SP), AX               // old SP
-       MOVQ    AX, SP
-
-       // and return to the call behind mine
-       ADDQ    $8, SP
+TEXT _morestack(SB), 7, $-8
+       BYTE    $0xcc
        RET
 
 // marker.  must be here; used by traceback() to discover calls to _morestack
 TEXT _endmorestack(SB), 7, $-8
        RET
 
-// call a subroutine in a new coroutine
-// argument list is on the stack
-// addr of fn is in AX
-TEXT   sys·_newproc(SB), 7, $0
-       // save stuff on interrupt stack
-
-       MOVQ    8(R14), CX              // istack
-       MOVQ    AX, 0(CX)               // fn pointer
-       MOVQ    BX, 8(CX)               // arg size
-       MOVQ    SP, 16(CX)              // old SP
-       MOVQ    0(R15), AX              // old limit
-       MOVQ    AX, 24(CX)
-
-       // switch and set up new limit
-
-       MOVQ    CX, SP
-       MOVQ    0(R14), AX              // istack limit
-       MOVQ    AX, 0(R15)
-
-       CALL    _newproc(SB)
-
-       // restore old SP and limit
-
-       MOVQ    24(SP), AX              // old limit
-       MOVQ    AX, 0(R15)
-       MOVQ    16(SP), AX              // old SP
-       MOVQ    AX, SP
+TEXT   FLUSH(SB),7,$-8
+       RET
 
+/*
+ *  go-routine
+ */
+TEXT gogo(SB), 7, $0
+       MOVQ    8(SP), AX               // gobuf
+       MOVQ    0(AX), SP               // restore SP
+       MOVQ    8(AX), AX
+       MOVQ    AX, 0(SP)               // put PC on the stack
+       MOVL    $1, AX                  // return 1
        RET
 
-TEXT   FLUSH(SB),7,$-8
+TEXT gosave(SB), 7, $0
+       MOVQ    8(SP), AX               // gobuf
+       MOVQ    SP, 0(AX)               // save SP
+       MOVQ    0(SP), BX
+       MOVQ    BX, 8(AX)               // save PC
+       MOVL    $0, AX                  // return 0
        RET
 
-TEXT   getu(SB),7,$-8
-       MOVQ    R15, AX
+TEXT setspgoto(SB), 7, $0
+       MOVQ    8(SP), AX               // SP
+       MOVQ    16(SP), BX              // fn to call
+       MOVQ    24(SP), CX              // fn to return
+       MOVQ    AX, SP
+       PUSHQ   CX
+       JMP     BX
+       POPQ    AX
        RET
 
-GLOBL  permach<>(SB),$64
-GLOBL  peruser<>(SB),$64
+GLOBL  m0<>(SB),$64
index 3ffbb1f99b3dd9b7e97ee523d2ed965e430981ec..81053b3dd3df0c4fc2812c9da8e754f4e90c86cf 100644 (file)
@@ -8,22 +8,6 @@ extern int32   debug;
 
 static int8 spmark[] = "\xa7\xf1\xd9\x2a\x82\xc8\xd8\xfe";
 
-//typedef struct U U;
-//struct U {
-//     uint8*  stackguard;
-//     uint8*  stackbase;
-//     uint8*  istackguard;
-//     uint8*  istackbase;
-//};
-
-typedef struct Stktop Stktop;
-struct Stktop {
-       uint8*  oldbase;
-       uint8*  oldsp;
-       uint8*  magic;
-       uint8*  oldguard;
-};
-
 extern void _morestack();
 extern void _endmorestack();
 
index 8a94f402c02057cadfc2166ef5a097ae0ef58e59..743e085e7a3cc3108953e1b2fb7f85768c0ddbe1 100644 (file)
@@ -4,9 +4,9 @@
 
 #include "runtime.h"
 
+G      g0;                     // idle goroutine
 int32  debug   = 0;
 
-/*BUG: move traceback code to architecture-dependent runtime */
 void
 sys·panicl(int32 lno)
 {
@@ -18,7 +18,7 @@ sys·panicl(int32 lno)
        sys·printpc(&lno);
        prints("\n");
        sp = (uint8*)&lno;
-       traceback(sys·getcallerpc(&lno), sp, getu());
+       traceback(sys·getcallerpc(&lno), sp, g);
        sys·breakpoint();
        sys·exit(2);
 }
@@ -571,20 +571,229 @@ check(void)
        initsig();
 }
 
-extern register        u;
-uint32 a;
+void
+sys·goexit(void)
+{
+//prints("goexit goid=");
+//sys·printint(g->goid);
+//prints("\n");
+       g->status = Gdead;
+       sys·gosched();
+}
 
 void
-_newproc(byte* fn, int32 siz, byte* args)
+sys·newproc(int32 siz, byte* fn, byte* arg0)
 {
-       a = u;
+       byte *stk, *sp;
+       G *newg;
 
-       prints("_newproc fn=");
-       sys·printpointer(fn);
-       prints("; siz=");
-       sys·printint(siz);
-       prints("; args=");
-       sys·printpointer(args);
-       prints("\n");
-       dump(args, 32);
+//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->link = 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->link) {
+               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)
+//
+
+int32 debug = 0;
+
+void
+morestack2(void)
+{
+       Stktop *top;
+       uint32 siz2;
+       byte *sp;
+if(debug) prints("morestack2\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));
+if(debug) prints("morestack2 sp=");
+if(debug) sys·printpointer(m->morestack.SP);
+if(debug) prints(" pc=");
+if(debug) sys·printpointer(m->morestack.PC);
+if(debug) prints("\n");
+       gogo(&m->morestack);
+}
+
+void
+morestack1(void)
+{
+       int32 siz1, siz2;
+       Stktop *top;
+       byte *stk, *sp;
+       void (*fn)(void);
+
+       siz1 = m->morearg & 0xffffffffLL;
+       siz2 = (m->morearg>>32) & 0xffffLL;
+
+if(debug) prints("morestack1 siz1=");
+if(debug) sys·printint(siz1);
+if(debug) prints(" siz2=");
+if(debug) sys·printint(siz2);
+if(debug) prints(" moresp=");
+if(debug) sys·printpointer(m->moresp);
+if(debug) 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);
+if(debug) prints("fn=");
+if(debug) sys·printpointer(fn);
+if(debug) prints("\n");
+       setspgoto(sp, fn, morestack2);
+
+       *(int32*)345 = 123;
+}
+
+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, morestack1, nil);
+
+       *(int32*)234 = 123;
 }
index 5fe1cb646de1a6500d5c611658254ace1abadeb8..f7d31a1dd8d5b97400aa2f69a99616f027a3df52 100644 (file)
@@ -60,31 +60,59 @@ struct      Map
        int32   unused;
        void    (*fun[])(void);
 };
+typedef        struct  Gobuf           Gobuf;
+struct Gobuf
+{
+       byte*   SP;
+       byte*   PC;
+};
 typedef        struct  G               G;
 struct G
 {
        byte*   stackguard;     // must not move
        byte*   stackbase;      // must not move
-       G*      ufor;           // dbl ll of all u
-       G*      ubak;
-       G*      runqfor;        // dbl ll of runnable
-       G*      runqbak;
+       Gobuf   sched;
+       G*      link;
+       int32   status;
+       int32   pri;
+       int32   goid;
 };
 typedef        struct  M               M;
 struct M
 {
-       byte*   istackguard;    // must not move
-       byte*   istackbase;     // must not move
+       G*      g0;             // g0 w interrupt stack - must not move
+       uint64  morearg;        // arg to morestack - must not move
+       G*      curg;           // current running goroutine
+       Gobuf   sched;
+       Gobuf   morestack;
+       byte*   moresp;
+       int32   siz1;
+       int32   siz2;
+};
+typedef struct Stktop Stktop;
+struct Stktop {
+       uint8*  oldbase;
+       uint8*  oldsp;
+       uint64  magic;
+       uint8*  oldguard;
 };
 extern register        G*      g;      // R15
 extern register        M*      m;      // R14
 
+enum
+{
+       // G status
+       Gidle,
+       Grunnable,
+       Gdead,
+};
+
 /*
  * global variables
  */
 M*     allm;
-G*     allu;
-G*     runq;
+G*     allg;
+int32  goidgen;
 
 /*
  * defined constants
@@ -106,18 +134,21 @@ enum
 /*
  * common functions and data
  */
-int32 strcmp(byte*, byte*);
-int32 findnull(int8*);
+int32  strcmp(byte*, byte*);
+int32  findnull(int8*);
 void   dump(byte*, int32);
-int32 runetochar(byte*, int32);
-int32 chartorune(uint32*, byte*);
+int32  runetochar(byte*, int32);
+int32  chartorune(uint32*, byte*);
 
 extern string  emptystring;
-extern int32 debug;
+extern int32   debug;
 
 /*
  * very low level c-called
  */
+int32  gogo(Gobuf*);
+int32  gosave(Gobuf*);
+void   setspgoto(byte*, void(*)(void), void(*)(void));
 void   FLUSH(void*);
 void*  getu(void);
 void   throw(int8*);
@@ -126,7 +157,7 @@ void        mcpy(byte*, byte*, uint32);
 void*  mal(uint32);
 uint32 cmpstring(string, string);
 void   initsig(void);
-void   traceback(uint8 *pc, uint8 *sp, void* up);
+void   traceback(uint8 *pc, uint8 *sp, G* gp);
 int32  open(byte*, int32);
 int32  read(int32, void*, int32);
 void   close(int32);
@@ -140,6 +171,8 @@ struct      SigTab
 /*
  * low level go -called
  */
+void   sys·goexit(void);
+void   sys·gosched(void);
 void   sys·exit(int32);
 void   sys·write(int32, void*, int32);
 void   sys·breakpoint(void);
index 16b999b4ed1130e830d623afce2ae43868bdb8ce..56e97690ae0a2d9bf1a8f6779009929668eaaeac 100644 (file)
@@ -71,10 +71,6 @@ TEXT sigtramp(SB),1,$24
        CALL    sighandler(SB)
        RET
 
-TEXT   sys·breakpoint(SB),1,$-8
-       BYTE    $0xcc
-       RET
-
 TEXT   sys·mmap(SB),1,$-8
        MOVQ    8(SP), DI               // arg 1 addr
        MOVL    16(SP), SI              // arg 2 len
index 993193b8cdd7509e00c3ba4b1a47db064dfc2338..c49ae2ffb74017ab8bdda98d338f237ec4bd6818 100644 (file)
@@ -65,10 +65,6 @@ TEXT sigtramp(SB),1,$24
        CALL    sighandler(SB)
        RET
 
-TEXT   sys·breakpoint(SB),1,$-8
-       BYTE    $0xcc
-       RET
-
 TEXT   sys·mmap(SB),1,$-8
        MOVQ    8(SP), DI
        MOVL    16(SP), SI