From af58f17af936f8d88ccfed96b7a0e9953b4e6010 Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Mon, 14 Jul 2008 14:34:27 -0700 Subject: [PATCH] synch chan SVN=127057 --- src/runtime/proc.c | 264 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 264 insertions(+) create mode 100644 src/runtime/proc.c diff --git a/src/runtime/proc.c b/src/runtime/proc.c new file mode 100644 index 0000000000..fee6255a1b --- /dev/null +++ b/src/runtime/proc.c @@ -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; +} -- 2.48.1