diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/runtime/chan.c | 42 | ||||
-rw-r--r-- | src/runtime/hashmap.c | 11 | ||||
-rw-r--r-- | src/runtime/runtime.c | 3 | ||||
-rw-r--r-- | src/runtime/runtime.h | 2 |
4 files changed, 35 insertions, 23 deletions
diff --git a/src/runtime/chan.c b/src/runtime/chan.c index 45b32d3e9..14b5ce3a6 100644 --- a/src/runtime/chan.c +++ b/src/runtime/chan.c @@ -17,10 +17,10 @@ typedef struct Scase Scase; 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 Hchan 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 @@ struct Select 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 @@ sys·newchan(uint32 elemsize, uint32 elemalg, uint32 hint, 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 @@ sys·selectsend(Select *sel, Hchan *c, ...) 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 @@ sys·selectrecv(Select *sel, Hchan *c, ...) 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 @@ sys·selectdefault(Select *sel, ...) { 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 @@ sys·selectgo(Select *sel) // 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 @@ sys·selectgo(Select *sel) 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 @@ sys·selectgo(Select *sel) 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 @@ allocsg(Hchan *c) 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 83fe06c66..5b32fe588 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 @@ hash_lookup (struct hash *h, void *data, void **pres) 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 @@ hash_remove (struct hash *h, void *data, void *arg) 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 @@ hash_insert_internal (struct hash_subtable **pst, int32 flags, hash_hash_t hash, 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 @@ sys·newmap(uint32 keysize, uint32 valsize, { 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 baf6eb68b..3d0ee7f1e 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -644,11 +644,12 @@ pointercopy(uint32 s, void **a, void **b) } 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 dea47f72e..b2395e236 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -220,7 +220,7 @@ struct Func /* * external data */ -extern Alg algarray[3]; +extern Alg algarray[4]; extern string emptystring; G* allg; int32 goidgen; |