chans and maps of interfaces
R=r
DELTA=746 (729 added, 1 deleted, 16 changed)
OCL=20858
CL=20858
diff --git a/src/runtime/chan.c b/src/runtime/chan.c
index 45b32d3..14b5ce3 100644
--- a/src/runtime/chan.c
+++ b/src/runtime/chan.c
@@ -17,10 +17,10 @@
struct SudoG
{
G* g; // g and selgen constitute
- byte elem[8]; // synch data element
int16 offset; // offset of case number
int32 selgen; // a weak pointer to g
SudoG* link;
+ byte elem[8]; // synch data element (+ more)
};
struct WaitQ
@@ -45,7 +45,7 @@
struct Link
{
Link* link; // asynch queue circular linked list
- byte elem[8]; // asynch queue data element
+ byte elem[8]; // asynch queue data element (+ more)
};
struct Scase
@@ -65,7 +65,7 @@
uint16 tcase; // total count of scase[]
uint16 ncase; // currently filled scase[]
Select* link; // for freelist
- Scase scase[1]; // one per case
+ Scase* scase[1]; // one per case
};
static Select* selfree[20];
@@ -108,7 +108,7 @@
b = nil;
e = nil;
for(i=0; i<hint; i++) {
- d = mal(sizeof(*d));
+ d = mal(sizeof(*d) + c->elemsize - sizeof(d->elem));
if(e == nil)
e = d;
d->link = b;
@@ -430,7 +430,11 @@
if(i >= sel->tcase)
throw("selectsend: too many cases");
sel->ncase = i+1;
- cas = &sel->scase[i];
+ cas = sel->scase[i];
+ if(cas == nil) {
+ cas = mal(sizeof *cas + c->elemsize - sizeof(cas->u.elem));
+ sel->scase[i] = cas;
+ }
cas->pc = sys·getcallerpc(&sel);
cas->chan = c;
@@ -473,8 +477,11 @@
if(i >= sel->tcase)
throw("selectrecv: too many cases");
sel->ncase = i+1;
- cas = &sel->scase[i];
-
+ cas = sel->scase[i];
+ if(cas == nil) {
+ cas = mal(sizeof *cas);
+ sel->scase[i] = cas;
+ }
cas->pc = sys·getcallerpc(&sel);
cas->chan = c;
@@ -506,13 +513,16 @@
{
int32 i;
Scase *cas;
-
+
i = sel->ncase;
if(i >= sel->tcase)
throw("selectdefault: too many cases");
sel->ncase = i+1;
- cas = &sel->scase[i];
-
+ cas = sel->scase[i];
+ if(cas == nil) {
+ cas = mal(sizeof *cas);
+ sel->scase[i] = cas;
+ }
cas->pc = sys·getcallerpc(&sel);
cas->chan = nil;
@@ -579,7 +589,7 @@
// pass 1 - look for something already waiting
dfl = nil;
for(i=0; i<sel->ncase; i++) {
- cas = &sel->scase[o];
+ cas = sel->scase[o];
if(cas->send == 2) { // default
dfl = cas;
@@ -613,16 +623,16 @@
if(o >= sel->ncase)
o -= sel->ncase;
}
-
+
if(dfl != nil) {
cas = dfl;
goto retc;
}
-
+
// pass 2 - enqueue on all chans
for(i=0; i<sel->ncase; i++) {
- cas = &sel->scase[o];
+ cas = sel->scase[o];
c = cas->chan;
if(c->dataqsiz > 0) {
@@ -682,7 +692,7 @@
lock(&chanlock);
sg = g->param;
o = sg->offset;
- cas = &sel->scase[o];
+ cas = sel->scase[o];
c = cas->chan;
if(xxx) {
@@ -832,7 +842,7 @@
if(sg != nil) {
c->free = sg->link;
} else
- sg = mal(sizeof(*sg));
+ sg = mal(sizeof(*sg) + c->elemsize - sizeof(sg->elem));
sg->selgen = g->selgen;
sg->g = g;
sg->offset = 0;
diff --git a/src/runtime/hashmap.c b/src/runtime/hashmap.c
index 83fe06c..5b32fe5 100644
--- a/src/runtime/hashmap.c
+++ b/src/runtime/hashmap.c
@@ -8,6 +8,7 @@
/* Return a pointer to the struct/union of type "type"
whose "field" field is addressed by pointer "p". */
+
struct hash { /* a hash table; initialize with hash_init() */
uint32 count; /* elements in table - must be first */
@@ -291,7 +292,7 @@
int32 shift = HASH_BITS - (st->power + used);
int32 index_mask = (1 << st->power) - 1;
int32 i = (hash >> shift) & index_mask; /* i is the natural position of hash */
-
+
e = HASH_OFFSET (st->entry, i * elemsize); /* e points to element i */
e_hash = e->hash;
if ((e_hash & HASH_MASK) != HASH_SUBHASH) { /* a subtable */
@@ -332,7 +333,7 @@
int32 shift = HASH_BITS - (st->power + used);
int32 index_mask = (1 << st->power) - 1;
int32 i = (hash >> shift) & index_mask; /* i is the natural position of hash */
-
+
e = HASH_OFFSET (st->entry, i * elemsize); /* e points to element i */
e_hash = e->hash;
if ((e_hash & HASH_MASK) != HASH_SUBHASH) { /* a subtable */
@@ -378,7 +379,7 @@
struct hash_entry *e = start_e; /* e is going to range over [start_e, end_e) */
struct hash_entry *end_e;
hash_hash_t e_hash = e->hash;
-
+
if ((e_hash & HASH_MASK) == HASH_SUBHASH) { /* a subtable */
pst = (struct hash_subtable **) e->data;
flags += HASH_MAKE_USED (st->power);
@@ -662,8 +663,8 @@
{
Hmap *h;
- if(keyalg >= 3 ||
- valalg >= 3) {
+ if(keyalg >= 4 ||
+ valalg >= 4) {
prints("0<=");
sys·printint(keyalg);
prints("<");
diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c
index baf6eb6..3d0ee7f 100644
--- a/src/runtime/runtime.c
+++ b/src/runtime/runtime.c
@@ -644,11 +644,12 @@
}
Alg
-algarray[3] =
+algarray[4] =
{
{ memhash, memequal, memprint, memcopy }, // 0
{ stringhash, stringequal, stringprint, stringcopy }, // 1
// { pointerhash, pointerequal, pointerprint, pointercopy }, // 2
{ memhash, memequal, memprint, memcopy }, // 2 - treat pointers as ints
+ { memhash, memequal, memprint, memcopy }, // 3 - treat interfaces as memory
};
diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h
index dea47f7..b2395e2 100644
--- a/src/runtime/runtime.h
+++ b/src/runtime/runtime.h
@@ -220,7 +220,7 @@
/*
* external data
*/
-extern Alg algarray[3];
+extern Alg algarray[4];
extern string emptystring;
G* allg;
int32 goidgen;