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:
parent
963753d3f9
commit
b78676a49d
@ -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;
|
||||
|
@ -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))
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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,
|
||||
|
@ -659,6 +659,7 @@ opnames[] =
|
||||
[OI2I] = "I2I",
|
||||
[OSLICE] = "SLICE",
|
||||
[OSUB] = "SUB",
|
||||
[OSELECT] = "SELECT",
|
||||
[OSWITCH] = "SWITCH",
|
||||
[OTYPE] = "TYPE",
|
||||
[OVAR] = "VAR",
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user