mirror of
https://github.com/golang/go
synced 2024-11-25 13:17:56 -07:00
segmented stacks AND goroutines
SVN=126929
This commit is contained in:
parent
ae905980e7
commit
751ce3a77a
@ -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(®, types[TINT64], D_AX);
|
||||
gins(ALEAQ, f, ®);
|
||||
nodreg(®, types[TINT64], D_BX);
|
||||
gins(APUSHQ, ®, N);
|
||||
nodconst(&con, types[TINT32], argsize(f->type));
|
||||
gins(AMOVL, &con, ®);
|
||||
gins(APUSHQ, &con, N);
|
||||
gins(ACALL, N, newproc);
|
||||
gins(APOPQ, N, ®);
|
||||
gins(APOPQ, N, ®);
|
||||
return;
|
||||
}
|
||||
gins(ACALL, N, f);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
;
|
||||
|
@ -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
|
||||
// create istack out of the given (operating system) stack
|
||||
|
||||
LEAQ (-1024+104)(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)
|
||||
|
||||
ADDQ 0(SP), AX
|
||||
LEAQ (-4*8)(AX), BX
|
||||
MOVQ BX, 8(R14) // 8(R14) is base of istack (w auto*4)
|
||||
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
|
||||
|
||||
RET
|
||||
|
||||
TEXT FLUSH(SB),7,$-8
|
||||
RET
|
||||
|
||||
TEXT getu(SB),7,$-8
|
||||
MOVQ R15, AX
|
||||
/*
|
||||
* 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
|
||||
|
||||
GLOBL permach<>(SB),$64
|
||||
GLOBL peruser<>(SB),$64
|
||||
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 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 m0<>(SB),$64
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user