#include "runtime.h"
static int32 debug = 0;
+static int32 xxx = 0;
static Lock chanlock;
typedef struct Hchan Hchan;
struct SudoG
{
G* g; // g and selgen constitute
- int16 offset; // offset of case number
int32 selgen; // a weak pointer to g
+ int16 offset; // offset of case number
+ int8 isfree; // offset of case number
SudoG* link;
byte elem[8]; // synch data element (+ more)
};
return;
asynch:
-//prints("\nasend\n");
while(c->qcount >= c->dataqsiz) {
if(pres != nil) {
unlock(&chanlock);
sg = dequeue(&c->recvq, c);
if(sg != nil) {
gp = sg->g;
- gp->param = sg;
freesg(c, sg);
unlock(&chanlock);
-//prints("wakeup\n");
ready(gp);
} else
unlock(&chanlock);
sg = dequeue(&c->sendq, c);
if(sg != nil) {
gp = sg->g;
- gp->param = sg;
freesg(c, sg);
unlock(&chanlock);
ready(gp);
if(debug) {
prints("newselect s=");
sys·printpointer(sel);
- prints("newselect size=");
+ prints(" size=");
sys·printint(size);
prints("\n");
}
c->elemalg->copy(c->elemsize, cas->u.elem, ae);
if(debug) {
- prints("newselect s=");
+ prints("selectsend s=");
sys·printpointer(sel);
prints(" pc=");
sys·printpointer(cas->pc);
cas->u.elemp = *(byte**)((byte*)&sel + eo);
if(debug) {
- prints("newselect s=");
+ prints("selectrecv s=");
sys·printpointer(sel);
prints(" pc=");
sys·printpointer(cas->pc);
}
-// selectrecv(sel *byte) (selected bool);
+// selectdefaul(sel *byte) (selected bool);
void
sys·selectdefault(Select *sel, ...)
{
cas->u.elemp = nil;
if(debug) {
- prints("newselect s=");
+ prints("selectdefault s=");
sys·printpointer(sel);
prints(" pc=");
sys·printpointer(cas->pc);
}
}
-uint32 xxx = 0;
// selectgo(sel *byte);
void
lock(&chanlock);
+loop:
// pass 1 - look for something already waiting
dfl = nil;
for(i=0; i<sel->ncase; i++) {
o -= sel->ncase;
}
+ g->param = nil;
g->status = Gwaiting;
unlock(&chanlock);
sys·Gosched();
lock(&chanlock);
sg = g->param;
+ if(sg == nil)
+ goto loop;
+
o = sg->offset;
cas = sel->scase[o];
c = cas->chan;
+ if(c->dataqsiz > 0) {
+// prints("shouldnt happen\n");
+ goto loop;
+ }
+
if(xxx) {
prints("wait-return: sel=");
sys·printpointer(sel);
prints("\n");
}
- if(c->dataqsiz > 0) {
- if(cas->send)
- goto asyns;
- goto asynr;
- }
-
if(!cas->send) {
if(cas->u.elemp != nil)
c->elemalg->copy(c->elemsize, cas->u.elemp, sg->elem);
sg = dequeue(&c->sendq, c);
if(sg != nil) {
gp = sg->g;
- gp->param = sg;
freesg(c, sg);
ready(gp);
}
sg = dequeue(&c->recvq, c);
if(sg != nil) {
gp = sg->g;
- gp->param = sg;
freesg(c, sg);
ready(gp);
}
sg->selgen = g->selgen;
sg->g = g;
sg->offset = 0;
+ sg->isfree = 0;
return sg;
}
static void
freesg(Hchan *c, SudoG *sg)
{
+ if(sg->isfree)
+ throw("chan.freesg: already free");
+ sg->isfree = 1;
sg->link = c->free;
c->free = sg;
}