1
0
mirror of https://github.com/golang/go synced 2024-11-11 21:20:21 -07:00

start of select

random bugs fixed

SVN=128149
This commit is contained in:
Ken Thompson 2008-07-20 20:13:07 -07:00
parent 963753d3f9
commit b78676a49d
10 changed files with 194 additions and 91 deletions

View File

@ -902,6 +902,11 @@ cgen_as(Node *nl, Node *nr, int op)
case TPTR32:
case TPTR64:
if(isptrto(tl, TSTRING)) {
nr->val.sval = mal(8);
nr->val.ctype = CTSTR;
break;
}
nr->val.ctype = CTNIL;
nr->val.vval = 0;
break;

View File

@ -20,9 +20,13 @@ convlit(Node *n, Type *t)
goto bad1;
case Wlitnil:
if(isptr[et] || et == TINTER)
break;
goto bad1;
if(!isptr[et] && et != TINTER)
goto bad1;
if(isptrto(t, TSTRING)) {
n->val.sval = mal(8);
n->val.ctype = CTSTR;
}
break;
case Wlitstr:
if(isptrto(t, TSTRING))

View File

@ -219,7 +219,7 @@ enum
OLIST, OCMP,
OPTR, OARRAY,
ORETURN, OFOR, OIF, OSWITCH, OI2S, OS2I, OI2I,
OAS, OASOP, OCASE, OXCASE, OFALL, OXFALL,
OAS, OASOP, OCASE, OXCASE, OFALL, OXFALL, OSELECT,
OGOTO, OPROC, ONEW, OPANIC, OPRINT, OEMPTY,
OOROR,

View File

@ -18,7 +18,7 @@
%token LMAP LCHAN LINTERFACE LFUNC LSTRUCT
%token LCOLAS LFALL LRETURN
%token LNEW LLEN
%token LVAR LTYPE LCONST LCONVERT
%token LVAR LTYPE LCONST LCONVERT LSELECT
%token LFOR LIF LELSE LSWITCH LCASE LDEFAULT
%token LBREAK LCONTINUE LGO LGOTO LRANGE
%token LOROR LANDAND LEQ LNE LLE LLT LGE LGT
@ -37,7 +37,7 @@
%type <node> Astmt Bstmt Cstmt Dstmt
%type <node> for_stmt for_body for_header
%type <node> if_stmt if_body if_header
%type <node> range_header range_body range_stmt
%type <node> range_header range_body range_stmt select_stmt
%type <node> simple_stmt osimple_stmt semi_stmt
%type <node> expr uexpr pexpr expr_list oexpr oexpr_list expr_list_r
%type <node> name name_name new_name new_name_list_r conexpr
@ -360,6 +360,11 @@ complex_stmt:
//if($$->ninit != N && $$->ntest == N)
// yyerror("if conditional should not be missing");
}
| LSELECT select_stmt
{
popdcl();
$$ = $2;
}
| LRANGE range_stmt
{
popdcl();
@ -529,6 +534,15 @@ range_stmt:
$$ = $2;
}
select_stmt:
{
markdcl();
}
compound_stmt
{
$$ = nod(OSELECT, $2, N);
}
/*
* expressions
*/

View File

@ -962,20 +962,20 @@ static struct
"string", LBASETYPE, TSTRING,
"any", LBASETYPE, TANY,
"sys", LPACK, Txxx,
/* keywords */
// "any", LANY, Txxx,
"break", LBREAK, Txxx,
"case", LCASE, Txxx,
"chan", LCHAN, Txxx,
"const", LCONST, Txxx,
"continue", LCONTINUE, Txxx,
"convert", LCONVERT, Txxx,
"convert", LCONVERT, Txxx, // should be a var
"default", LDEFAULT, Txxx,
"else", LELSE, Txxx,
"export", LEXPORT, Txxx,
"fallthrough", LFALL, Txxx,
"false", LFALSE, Txxx,
"false", LFALSE, Txxx, // should be a var
"for", LFOR, Txxx,
"func", LFUNC, Txxx,
"go", LGO, Txxx,
@ -985,20 +985,20 @@ static struct
"interface", LINTERFACE, Txxx,
"iota", LIOTA, Txxx,
"map", LMAP, Txxx,
"new", LNEW, Txxx,
"len", LLEN, Txxx,
"nil", LNIL, Txxx,
"new", LNEW, Txxx, // should be a var
"len", LLEN, Txxx, // should be a var
"nil", LNIL, Txxx, // should be a var
"package", LPACKAGE, Txxx,
"panic", LPANIC, Txxx,
"print", LPRINT, Txxx,
"panic", LPANIC, Txxx, // temp
"print", LPRINT, Txxx, // temp
"range", LRANGE, Txxx,
"return", LRETURN, Txxx,
"select", LSELECT, Txxx,
"struct", LSTRUCT, Txxx,
"switch", LSWITCH, Txxx,
"true", LTRUE, Txxx,
"true", LTRUE, Txxx, // should be a var
"type", LTYPE, Txxx,
"var", LVAR, Txxx,
"sys", LPACK, Txxx,
"notwithstanding", LIGNORE, Txxx,
"thetruthofthematter", LIGNORE, Txxx,

View File

@ -659,6 +659,7 @@ opnames[] =
[OI2I] = "I2I",
[OSLICE] = "SLICE",
[OSUB] = "SUB",
[OSELECT] = "SELECT",
[OSWITCH] = "SWITCH",
[OTYPE] = "TYPE",
[OVAR] = "VAR",

View File

@ -8,6 +8,21 @@ static int32 debug = 0;
typedef struct Hchan Hchan;
typedef struct Link Link;
typedef struct WaitQ WaitQ;
typedef struct SudoG SudoG;
struct SudoG
{
G* g; // g and selgen constitute
int64 selgen; // a weak pointer to g
SudoG* link;
};
struct WaitQ
{
SudoG* first;
SudoG* last;
};
struct Hchan
{
@ -21,6 +36,7 @@ struct Hchan
Link* recvdataq; // pointer for receiver
WaitQ recvq; // list of recv waiters
WaitQ sendq; // list of send waiters
SudoG* free; // freelist
};
struct Link
@ -29,6 +45,11 @@ struct Link
byte elem[8];
};
static SudoG* dequeue(WaitQ*, Hchan*);
static void enqueue(WaitQ*, SudoG*);
static SudoG* allocsg(Hchan*);
static void freesg(Hchan*, SudoG*);
// newchan(elemsize uint32, elemalg uint32, hint uint32) (hchan *chan any);
void
sys·newchan(uint32 elemsize, uint32 elemalg, uint32 hint,
@ -97,7 +118,8 @@ void
sys·chansend1(Hchan* c, ...)
{
byte *ae;
G *gr;
SudoG *sgr;
G* gr;
ae = (byte*)&c + c->eo;
if(debug) {
@ -110,30 +132,39 @@ sys·chansend1(Hchan* c, ...)
if(c->dataqsiz > 0)
goto asynch;
gr = dequeue(&c->recvq);
if(gr != nil) {
sgr = dequeue(&c->recvq, c);
if(sgr != nil) {
gr = sgr->g;
freesg(c, sgr);
c->elemalg->copy(c->elemsize, gr->elem, ae);
gr->status = Grunnable;
return;
}
c->elemalg->copy(c->elemsize, g->elem, ae);
sgr = allocsg(c);
g->status = Gwaiting;
enqueue(&c->sendq, g);
enqueue(&c->sendq, sgr);
sys·gosched();
return;
asynch:
while(c->qcount >= c->dataqsiz) {
sgr = allocsg(c);
g->status = Gwaiting;
enqueue(&c->sendq, g);
enqueue(&c->sendq, sgr);
sys·gosched();
}
c->elemalg->copy(c->elemsize, c->senddataq->elem, ae);
c->senddataq = c->senddataq->link;
c->qcount++;
gr = dequeue(&c->recvq);
if(gr != nil)
sgr = dequeue(&c->recvq, c);
if(sgr != nil) {
gr = sgr->g;
freesg(c, sgr);
gr->status = Grunnable;
}
}
// chansend2(hchan *chan any, elem any) (pres bool);
@ -141,6 +172,7 @@ void
sys·chansend2(Hchan* c, ...)
{
byte *ae, *ap;
SudoG *sgr;
G *gr;
ae = (byte*)&c + c->eo;
@ -156,8 +188,11 @@ sys·chansend2(Hchan* c, ...)
if(c->dataqsiz > 0)
goto asynch;
gr = dequeue(&c->recvq);
if(gr != nil) {
sgr = dequeue(&c->recvq, c);
if(sgr != nil) {
gr = sgr->g;
freesg(c, sgr);
c->elemalg->copy(c->elemsize, gr->elem, ae);
gr->status = Grunnable;
*ap = true;
@ -174,9 +209,12 @@ asynch:
c->elemalg->copy(c->elemsize, c->senddataq->elem, ae);
c->senddataq = c->senddataq->link;
c->qcount++;
gr = dequeue(&c->recvq);
if(gr != nil)
sgr = dequeue(&c->recvq, c);
if(gr != nil) {
gr = sgr->g;
freesg(c, sgr);
gr->status = Grunnable;
}
*ap = true;
}
@ -185,6 +223,7 @@ void
sys·chanrecv1(Hchan* c, ...)
{
byte *ae;
SudoG *sgs;
G *gs;
ae = (byte*)&c + c->eo;
@ -196,30 +235,39 @@ sys·chanrecv1(Hchan* c, ...)
if(c->dataqsiz > 0)
goto asynch;
gs = dequeue(&c->sendq);
if(gs != nil) {
sgs = dequeue(&c->sendq, c);
if(sgs != nil) {
gs = sgs->g;
freesg(c, sgs);
c->elemalg->copy(c->elemsize, ae, gs->elem);
gs->status = Grunnable;
return;
}
sgs = allocsg(c);
g->status = Gwaiting;
enqueue(&c->recvq, g);
enqueue(&c->recvq, sgs);
sys·gosched();
c->elemalg->copy(c->elemsize, ae, g->elem);
return;
asynch:
while(c->qcount <= 0) {
sgs = allocsg(c);
g->status = Gwaiting;
enqueue(&c->recvq, g);
enqueue(&c->recvq, sgs);
sys·gosched();
}
c->elemalg->copy(c->elemsize, ae, c->recvdataq->elem);
c->recvdataq = c->recvdataq->link;
c->qcount--;
gs = dequeue(&c->sendq);
if(gs != nil)
sgs = dequeue(&c->sendq, c);
if(gs != nil) {
gs = sgs->g;
freesg(c, sgs);
gs->status = Grunnable;
}
}
// chanrecv2(hchan *chan any) (elem any, pres bool);
@ -227,6 +275,7 @@ void
sys·chanrecv2(Hchan* c, ...)
{
byte *ae, *ap;
SudoG *sgs;
G *gs;
ae = (byte*)&c + c->eo;
@ -240,8 +289,11 @@ sys·chanrecv2(Hchan* c, ...)
if(c->dataqsiz > 0)
goto asynch;
gs = dequeue(&c->sendq);
if(gs != nil) {
sgs = dequeue(&c->sendq, c);
if(sgs != nil) {
gs = sgs->g;
freesg(c, sgs);
c->elemalg->copy(c->elemsize, ae, gs->elem);
gs->status = Grunnable;
*ap = true;
@ -258,8 +310,70 @@ asynch:
c->elemalg->copy(c->elemsize, ae, c->recvdataq->elem);
c->recvdataq = c->recvdataq->link;
c->qcount--;
gs = dequeue(&c->sendq);
if(gs != nil)
sgs = dequeue(&c->sendq, c);
if(sgs != nil) {
gs = sgs->g;
freesg(c, sgs);
gs->status = Grunnable;
}
*ap = true;
}
static SudoG*
dequeue(WaitQ *q, Hchan *c)
{
SudoG *sgp;
loop:
sgp = q->first;
if(sgp == nil)
return nil;
q->first = sgp->link;
// if sgp is stale, ignore it
if(sgp->selgen != sgp->g->selgen) {
prints("INVALID PSEUDOG POINTER\n");
freesg(c, sgp);
goto loop;
}
// invalidate any others
sgp->g->selgen++;
return sgp;
}
static void
enqueue(WaitQ *q, SudoG *sgp)
{
sgp->link = nil;
if(q->first == nil) {
q->first = sgp;
q->last = sgp;
return;
}
q->last->link = sgp;
q->last = sgp;
}
static SudoG*
allocsg(Hchan *c)
{
SudoG* sg;
sg = c->free;
if(sg != nil) {
c->free = sg->link;
} else
sg = mal(sizeof(*sg));
sg->selgen = g->selgen;
sg->g = g;
return sg;
}
static void
freesg(Hchan *c, SudoG *sg)
{
sg->link = c->free;
c->free = sg;
}

View File

@ -254,28 +254,3 @@ sys·morestack(uint64 u)
*(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;
}

View File

@ -42,7 +42,6 @@ typedef struct G G;
typedef struct M M;
typedef struct Stktop Stktop;
typedef struct Alg Alg;
typedef struct WaitQ WaitQ;
/*
* per cpu declaration
@ -108,9 +107,9 @@ struct G
byte* stack0; // first stack segment
Gobuf sched;
G* alllink; // on allq
G* qlink; // on wait q
int32 status;
int32 goid;
int64 selgen; // valid sudog pointer
byte elem[8]; // transfer element for chan
};
struct M
@ -126,11 +125,6 @@ struct M
int32 siz1;
int32 siz2;
};
struct WaitQ
{
G* first;
G* last;
};
struct Stktop
{
uint8* oldbase;
@ -176,8 +170,6 @@ int32 findnull(int8*);
void dump(byte*, int32);
int32 runetochar(byte*, int32);
int32 chartorune(uint32*, byte*);
G* dequeue(WaitQ*);
void enqueue(WaitQ*, G*);
/*
* very low level c-called

View File

@ -233,24 +233,6 @@ type PS2 *[2] PS; // pair of power series
var Ones PS
var Twos PS
// print eval in floating point of PS at x=c to n terms
func
Evaln(c *rat, U PS, n int)
{
xn := float64(1);
x := float64(c.num)/float64(c.den);
val := float64(0);
for i:=0; i<n; i++ {
u := get(U);
if end(u) != 0 {
break;
}
val = val + x * float64(u.num)/float64(u.den);
xn = xn*x;
}
print val, "\n";
}
func mkPS() *dch {
return mkdch()
}
@ -335,8 +317,25 @@ func inv(u *rat) *rat{ // invert a rat
return i2tor(u.den, u.num);
}
// Print n terms of a power series
// print eval in floating point of PS at x=c to n terms
func
Evaln(c *rat, U PS, n int)
{
xn := float64(1);
x := float64(c.num)/float64(c.den);
val := float64(0);
for i:=0; i<n; i++ {
u := get(U);
if end(u) != 0 {
break;
}
val = val + x * float64(u.num)/float64(u.den);
xn = xn*x;
}
print val, "\n";
}
// Print n terms of a power series
func Printn(U PS, n int){
done := false;
for ; !done && n>0; n-- {
@ -352,7 +351,6 @@ func Print(U PS){
}
// Evaluate n terms of power series U at x=c
func eval(c *rat, U PS, n int) *rat{
if n==0 { return zero }
y := get(U);