From c6e1c83f93f63a061f0804821ed29c656da38f28 Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Tue, 8 Feb 2022 16:03:10 +0000 Subject: Add work in progress concurrency. Might break stuff! --- apl9.h | 33 ++++++++++++- array.c | 6 +-- concurrency.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ error.c | 1 + eval.c | 12 ++--- functions.c | 45 +++++++++++------- hybrids.c | 4 +- lexer.c | 1 + main.c | 5 +- memory.c | 4 +- mkfile | 1 + operators.c | 29 ++++++++++-- quadnames.c | 42 +++++++++++++++++ symbol.c | 60 +++++++++++++----------- 14 files changed, 330 insertions(+), 61 deletions(-) create mode 100644 concurrency.c diff --git a/apl9.h b/apl9.h index 77966ed..4c28315 100644 --- a/apl9.h +++ b/apl9.h @@ -70,6 +70,8 @@ typedef struct Symtab Symtab; typedef struct QuadnameDef QuadnameDef; typedef struct ErrorHandler ErrorHandler; typedef struct DfnFrame DfnFrame; +typedef struct ThreadData ThreadData; +typedef struct Mail Mail; struct Mixed { @@ -204,6 +206,22 @@ struct DfnFrame DfnFrame *prev; }; +struct ThreadData +{ + int id; + DfnFrame *currentdfn; + Mail *mail; + Mail *lastmail; + QLock lock; + Rendez empty; +}; + +struct Mail +{ + Array *contents; + Mail *next; +}; + /* Function prototypes for the different source files */ /* main.c */ Datum *evalline(Rune *, Biobuf *, int); @@ -259,7 +277,7 @@ void checkmem(char *); Array *allocarray(int, int, int); void freearray(Array *); -void incref(Array *); +void incarrayref(Array *); /* functions.c */ Array *runfunc(Function, Array *,Array *); @@ -283,6 +301,13 @@ void throwerror(Rune *, int); /* inverse.c */ Function inverse(Function); +/* concurrency.c */ +void initthreads(void); +int spawnthread(Function, Array *, Array *); +ThreadData *getthreaddata(void); +void messagesend(Array *, int); +Array *messagerecv(Function, int); + /* Monadic functions from function.c */ Array *fnNegate(Array *); Array *fnSign(Array *); @@ -369,13 +394,16 @@ Array *fnReshape(Array *, Array *); Array *fnRotateLast(Array *, Array *); Array *fnRotateFirst(Array *, Array *); Array *fnSelfReference2(Array *, Array *); +Array *fnSend(Array *, Array *); /* Monadic operators from operators.c */ Array *opEach(Datum *, Array *, Array *); Array *opSwitch(Datum *, Array *, Array *); Array *opKey(Datum *, Array *, Array *); +Array *opSpawn(Datum *, Array *, Array *); Array *opOuterProduct(Datum *, Array *, Array *); Array *opSelfReference1(Datum *, Array *, Array *); +Array *opReceive(Datum *, Array *, Array *); /* Dyadic operators from operators.c */ Array *opPower(Datum *, Datum *, Array *, Array *); @@ -419,4 +447,5 @@ extern QuadnameDef quadnames[]; /* quadnames.c */ extern int printprecision; /* print.c */ extern ErrorHandler globalerror; /* error.c */ extern Rune *errorstrs[]; /* error.c */ -extern int needsnewline; /* quadnames.c */ \ No newline at end of file +extern int needsnewline; /* quadnames.c */ +extern int mainstacksize; /* concurrency.c */ \ No newline at end of file diff --git a/array.c b/array.c index c29c411..bc00a89 100644 --- a/array.c +++ b/array.c @@ -55,7 +55,7 @@ duparray(Array *a) memcpy(b->rawdata, a->rawdata, datasizes[a->type]*a->size); if(b->type == AtypeArray) for(int i = 0; i < b->size; i++) - incref(b->arraydata[i]); + incarrayref(b->arraydata[i]); return b; } @@ -197,7 +197,7 @@ arrayitem(Array *a, int index) break; case AtypeArray: res = a->arraydata[index]; - incref(res); + incarrayref(res); break; default: throwerror(L"Unhandled case in arrayitem", ENotImplemented); @@ -233,7 +233,7 @@ simplifyarray(Array *a) if(nested){ memcpy(b->rawdata + i * datasizes[type], a->arraydata[i]->rawdata, datasizes[type]); if(b->type == AtypeArray) - incref(b->arraydata[i]); + incarrayref(b->arraydata[i]); }else{ switch(b->type){ case AtypeInt: b->intdata[i] = a->mixeddata[i].i; break; diff --git a/concurrency.c b/concurrency.c new file mode 100644 index 0000000..4af563c --- /dev/null +++ b/concurrency.c @@ -0,0 +1,148 @@ +#include +#include +#include +#include +#include "apl9.h" + +#define STACKSIZE (8*1024*1024) /* 8 MB */ + +typedef struct SpawnData SpawnData; +struct SpawnData +{ + Function func; + Array *left; + Array *right; + Channel *setupdone; +}; + +static void newprocfn(void *); +static ThreadData *newthreaddata(void); + +/* global data */ +static Lock threadlock; +static int nthreads; +static ThreadData **threads; +int mainstacksize = STACKSIZE; + +void +initthreads(void) +{ + ThreadData *td = newthreaddata(); + void **tdptr = threaddata(); + *tdptr = td; +} + +int +spawnthread(Function f, Array *left, Array *right) +{ + /* lock the data structures */ + /* Spawn a new proc */ + /* Allocate a new mailbox */ + /* Send a message back to spawnthread that the setup is ready */ + /* In spawnthread: unlock datastructures, return thread id */ + /* in new proc: + run runfunc + lock datastructures + delete mailbox + unlock datastructures + exit proc + */ + Channel *setupdone = chancreate(sizeof(int), 0); + SpawnData *sp = malloc(sizeof(SpawnData)); + sp->func = f; + sp->left = left ? duparray(left) : nil; + sp->right = duparray(right); + sp->setupdone = setupdone; + int id = proccreate(newprocfn, sp, STACKSIZE); + recv(setupdone, nil); /* wait for new proc to signal that the setup is done */ + chanfree(setupdone); + return id; +} + +ThreadData * +getthreaddata(void) +{ + void **tdptr = threaddata(); + return (ThreadData *)*tdptr; +} + +void +messagesend(Array *a, int id) +{ + ThreadData *td = nil; + lock(&threadlock); + for(int i = 0; i < nthreads && td == nil; i++) + if(threads[i]->id == id) + td = threads[i]; + unlock(&threadlock); + if(td != nil){ + qlock(&td->lock); + Mail *newmail = malloc(sizeof(Mail)); + newmail->contents = fnSame(a); + newmail->next = 0; + if(td->lastmail != nil) + td->lastmail->next = newmail; + else + td->mail = newmail; + td->lastmail = newmail; + rwakeup(&td->empty); + qunlock(&td->lock); + } +} + +Array * +messagerecv(Function match, int timeout) +{ + USED(timeout); + USED(match); + ThreadData *td = getthreaddata(); + qlock(&td->lock); + while(td->mail == nil) + rsleep(&td->empty); + Mail *m = td->mail; + td->mail = m->next; + if(td->mail == nil) + td->lastmail = nil; + qunlock(&td->lock); + Array *a = m->contents; + free(m); + return a; +} + + +static void +newprocfn(void *data) +{ + SpawnData *sp = (SpawnData *)data; + ThreadData *td = newthreaddata(); + void **tdptr = threaddata(); + *tdptr = td; + int done = 1; + send(sp->setupdone, &done); + runfunc(sp->func, sp->left, sp->right); + lock(&threadlock); + /* TODO remove thread */ + unlock(&threadlock); + freearray(sp->left); + freearray(sp->right); + free(sp); + free(td); +} + +static ThreadData * +newthreaddata(void) +{ + ThreadData *td = mallocz(sizeof(ThreadData), 1); + td->id = threadid(); + td->currentdfn = nil; + td->mail = 0; + td->lastmail = 0; + td->empty.l = &td->lock; + + lock(&threadlock); + nthreads++; + threads = realloc(threads, sizeof(ThreadData *) * nthreads); + threads[nthreads-1] = td; + unlock(&threadlock); + return td; +} diff --git a/error.c b/error.c index 2d69457..47837a9 100644 --- a/error.c +++ b/error.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "apl9.h" diff --git a/eval.c b/eval.c index c6f6a8d..1d54e42 100644 --- a/eval.c +++ b/eval.c @@ -150,7 +150,7 @@ lookup(Datum var) else{ val = &symbol->value; if(val->tag == ArrayTag) - incref(val->array); /* since the value is now in the var AND in the code */ + incarrayref(val->array); /* since the value is now in the var AND in the code */ } val->shy = 0; traceprint("VAR %S = %S\n", var.name, ppdatum(*val)); @@ -200,7 +200,7 @@ dyadfun(Datum left, Datum right) result.func.code = right.hybrid; } result.func.left = left.array; - incref(left.array); + incarrayref(left.array); return result; } @@ -261,7 +261,7 @@ assign(Datum left, Datum right) symbol->undefined = 0; if(symbol->value.tag == ArrayTag){ symbol->value.array->stranded = 0; - incref(right.array); /* for the binding */ + incarrayref(right.array); /* for the binding */ } } }else{ @@ -307,7 +307,7 @@ assign(Datum left, Datum right) } right.shy = 1; if(right.tag == ArrayTag) - incref(right.array); /* for the returned array */ + incarrayref(right.array); /* for the returned array */ return right; } @@ -331,7 +331,7 @@ monadop(Datum left, Datum right) result.func.operator.left = arg; result.func.left = nil; if(arg->tag == ArrayTag) - incref(arg->array); + incarrayref(arg->array); return result; } @@ -348,7 +348,7 @@ dyadop(Datum left, Datum right) result.operator = left.operator; result.operator.right = arg; if(arg->tag == ArrayTag) - incref(arg->array); + incarrayref(arg->array); return result; } diff --git a/functions.c b/functions.c index b1003fa..46f9782 100644 --- a/functions.c +++ b/functions.c @@ -4,7 +4,7 @@ #include "apl9.h" -Rune primfuncnames[] = L"+-×÷*⍟⌹○!?|⌈⌊⊥⊤⊣⊢=≠≤<>≥≡≢∨∧⍲⍱↑↓⊂⊃⊆⌷⍋⍒⍳⍸∊⍷∪∩~,⍪⍴⌽⊖⍉⍎⍕∇"; +Rune primfuncnames[] = L"+-×÷*⍟⌹○!?|⌈⌊⊥⊤⊣⊢=≠≤<>≥≡≢∨∧⍲⍱↑↓⊂⊃⊆⌷⍋⍒⍳⍸∊⍷∪∩~,⍪⍴⌽⊖⍉⍎⍕∇⍈"; fnmonad monadfunctiondefs[] = { fnSame, /* + */ @@ -60,6 +60,7 @@ fnmonad monadfunctiondefs[] = { fnExecute, /* ⍎ */ fnFormat, /* ⍕ */ fnSelfReference1, /* ∇ */ + 0, /* ⍈ */ }; fndyad dyadfunctiondefs[] = { @@ -116,6 +117,7 @@ fndyad dyadfunctiondefs[] = { 0, /* ⍎ */ 0, /* ⍕ */ fnSelfReference2, /* ∇ */ + fnSend, /* ⍈ */ }; vlong gcd_int(vlong, vlong); @@ -445,7 +447,7 @@ fnFloor(Array *right) Array * fnSame(Array *right) { - incref(right); + incarrayref(right); return right; } @@ -533,10 +535,10 @@ fnMix(Array *right) result->arraydata[i*commonsize] = a->arraydata[0]; else result->arraydata[i*commonsize] = a; - incref(result->arraydata[i*commonsize]); + incarrayref(result->arraydata[i*commonsize]); for(j = 1; j < commonsize; j++){ result->arraydata[i*commonsize+j] = fill; - incref(fill); + incarrayref(fill); } }else{ for(j = 0; j < commonrank; j++) @@ -546,7 +548,7 @@ fnMix(Array *right) int nfill = commonshape->intdata[commonrank-1-k] - a->shape[a->rank-1-k]; while(nfill--){ result->arraydata[i*commonsize+offset] = fill; - incref(fill); + incarrayref(fill); offset++; } index[commonrank-1-k] = 0; @@ -558,7 +560,7 @@ fnMix(Array *right) index[commonrank-1]++; }else if(offset < commonsize){ result->arraydata[i*commonsize+offset] = fill; - incref(fill); + incarrayref(fill); offset++; } } @@ -580,7 +582,7 @@ fnSplit(Array *right) Array * fnEnclose(Array *right) { - incref(right); + incarrayref(right); if(simplescalar(right)) return right; else{ @@ -1148,7 +1150,7 @@ Array * fnLeft(Array *left, Array *right) { USED(right); - incref(left); + incarrayref(left); return left; } @@ -1156,7 +1158,7 @@ Array * fnRight(Array *left, Array *right) { USED(left); - incref(right); + incarrayref(right); return right; } @@ -1352,7 +1354,7 @@ fnTake(Array *left, Array *right) memcpy(result->rawdata + i*datasizes[result->type], fill->rawdata, datasizes[result->type]); if(result->type == AtypeArray) - incref(result->arraydata[i]); + incarrayref(result->arraydata[i]); index[left->size-1]++; } @@ -1530,7 +1532,7 @@ fnIndex(Array *left, Array *right) throwerror(nil, EIndex); } left->arraydata[i] = oldleft->arraydata[i]; - incref(left->arraydata[i]); + incarrayref(left->arraydata[i]); } } @@ -1575,7 +1577,7 @@ fnIndex(Array *left, Array *right) right->rawdata + from * datasizes[result->type], datasizes[result->type]); if(result->type == AtypeArray) - incref(result->arraydata[i]); + incarrayref(result->arraydata[i]); leftindex[left->size-1]++; } free(leftindex); @@ -1626,7 +1628,7 @@ fnFind(Array *left, Array *right) memcpy(newleft->rawdata, left->rawdata, datasizes[left->type] * left->size); if(left->type == AtypeArray) for(i = 0; i < left->size; i++) - incref(newleft->arraydata[i]); + incarrayref(newleft->arraydata[i]); left = newleft; }else left = fnSame(left); @@ -1746,7 +1748,7 @@ fnCatenateFirst(Array *left, Array *right) for(i = 0, j = 0; i < leftarr->size; i++, j++){ if(type == AtypeArray && leftarr->type == AtypeArray){ result->arraydata[j] = leftarr->arraydata[i]; - incref(result->arraydata[j]); + incarrayref(result->arraydata[j]); }else if(type == AtypeArray && leftarr->type != AtypeArray){ result->arraydata[j] = arrayitem(leftarr, i); }else{ @@ -1761,7 +1763,7 @@ fnCatenateFirst(Array *left, Array *right) for(i = 0; i < rightarr->size; i++, j++){ if(type == AtypeArray && rightarr->type == AtypeArray){ result->arraydata[j] = rightarr->arraydata[i]; - incref(result->arraydata[j]); + incarrayref(result->arraydata[j]); }else if(type == AtypeArray && rightarr->type != AtypeArray){ result->arraydata[j] = arrayitem(rightarr, i); }else{ @@ -1795,7 +1797,7 @@ fnReshape(Array *left, Array *right) memcpy(p, right->rawdata + (datasizes[res->type] * (i % right->size)), datasizes[res->type]); if(res->type == AtypeArray) for(i = 0; i < res->size; i++) - incref(res->arraydata[i]); + incarrayref(res->arraydata[i]); return res; } @@ -1862,6 +1864,17 @@ fnSelfReference2(Array *left, Array *right) } } +Array * +fnSend(Array *left, Array *right) +{ + if(right->size != 1) + throwerror(nil, ELength); + if(right->type != AtypeInt) + throwerror(nil, EType); + messagesend(left, right->intdata[0]); + return fnSame(left); +} + /* helper functions */ vlong gcd_int(vlong a, vlong b) diff --git a/hybrids.c b/hybrids.c index e7f7f4b..9dc0a43 100644 --- a/hybrids.c +++ b/hybrids.c @@ -95,7 +95,7 @@ fnReplicateFirst(Array *left, Array *right) } if(result->type == AtypeArray) for(int j = 0; j < npos*cellsize; j++) - incref(result->arraydata[to*cellsize+j]); + incarrayref(result->arraydata[to*cellsize+j]); } freearray(fill); freearray(left); @@ -153,7 +153,7 @@ fnExpandFirst(Array *left, Array *right) } if(result->type == AtypeArray) for(int j = 0; j < npos*cellsize; j++) - incref(result->arraydata[to*cellsize+j]); + incarrayref(result->arraydata[to*cellsize+j]); if(right->shape[0] != 1 && !neg) from++; } diff --git a/lexer.c b/lexer.c index 6abe33e..864bb3c 100644 --- a/lexer.c +++ b/lexer.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "apl9.h" diff --git a/main.c b/main.c index ea26c6c..0520592 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -8,10 +9,11 @@ Biobuf *stdin; void -main(int argc, char *argv[]) +threadmain(int argc, char *argv[]) { int off = 0; stdin = Bfdopen(0, OREAD); + initthreads(); initsymtab(); initquadnames(); traceeval = 0; @@ -101,6 +103,7 @@ evalline(Rune *line, Biobuf *bio, int toplevel) free(tmp->toks); free(tmp); } + return nil; } } \ No newline at end of file diff --git a/memory.c b/memory.c index 04c716d..4606ef2 100644 --- a/memory.c +++ b/memory.c @@ -68,11 +68,11 @@ allocarray(arrayDataType t, int rank, int size) } void -incref(Array *a) +incarrayref(Array *a) { /* print("INCREF %d->%d %S\n", a->refs, a->refs+1, pparray(a)); */ a->refs++; if(a->type == AtypeArray) for(int i = 0; i < a->size; i++) - incref(a->arraydata[i]); + incarrayref(a->arraydata[i]); } \ No newline at end of file diff --git a/mkfile b/mkfile index 017cc1a..0c05261 100644 --- a/mkfile +++ b/mkfile @@ -15,6 +15,7 @@ OFILES=\ error.$O\ hybrids.$O\ inverse.$O\ + concurrency.$O\ HFILES=\ apl9.h\ diff --git a/operators.c b/operators.c index f6066d9..a06b0d6 100644 --- a/operators.c +++ b/operators.c @@ -4,7 +4,7 @@ #include "apl9.h" -Rune primmonopnames[] = L"¨⍨⌸⌶&⌾∆"; +Rune primmonopnames[] = L"¨⍨⌸⌶&⌾∆⍇"; Rune primdyadopnames[] = L"⍣.∘⍤⍥@⍠⌺⍢⍫⍙"; opmonad monadoperatordefs[] = { @@ -12,9 +12,10 @@ opmonad monadoperatordefs[] = { opSwitch, /* ⍨ */ opKey, /* ⌸ */ 0, /* ⌶ */ - 0, /* & */ + opSpawn, /* & */ opOuterProduct, /* ⌾ */ opSelfReference1, /* ∆ */ + opReceive, /* ⍇ */ }; opdyad dyadoperatordefs[] = { @@ -68,7 +69,7 @@ Array * opSwitch(Datum *lefto, Array *left, Array *right) { if(lefto->tag == ArrayTag){ - incref(lefto->array); + incarrayref(lefto->array); return lefto->array; }else if(lefto->tag == FunctionTag){ if(left) @@ -90,6 +91,15 @@ opKey(Datum *lefto, Array *left, Array *right) return rundfn(L"⍵⍶⌸⍳≢⍵", lefto, nil, left, right); } +Array * +opSpawn(Datum *lefto, Array *left, Array *right) +{ + if(lefto->tag != FunctionTag) + throwerror(L"Can only spawn functions", EType); + int id = spawnthread(lefto->func, left, right); + return mkscalarint(id); +} + Array * opOuterProduct(Datum *lefto, Array *left, Array *right) { @@ -140,6 +150,19 @@ opSelfReference1(Datum *lefto, Array *left, Array *right) } } +Array * +opReceive(Datum *lefto, Array *left, Array *right) +{ + if(lefto->tag != FunctionTag) + throwerror(nil, EType); + if(right->type != AtypeInt) + throwerror(nil, EType); + if(right->size != 1) + throwerror(nil, ELength); + USED(left); + return messagerecv(lefto->func, right->intdata[0]); +} + /* Dyadic operators */ Array * opPower(Datum *lefto, Datum *righto, Array *left, Array *right) diff --git a/quadnames.c b/quadnames.c index 5632cd4..7d5884c 100644 --- a/quadnames.c +++ b/quadnames.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "apl9.h" @@ -16,6 +17,7 @@ Datum *getdiv(void); void setdiv(Datum); Datum *geta(void); Datum *getd(void); +Datum *getself(void); Array *runfile(Array *); Array *quadthrow1(Array *); @@ -23,9 +25,11 @@ Array *quadthrow2(Array *, Array *); Array *quadinfo(Array *); Array *quadproto(Array *); Array *quaducs(Array *); +Array *quaddl(Array *); int needsnewline = 0; static Rune *quadquotebuf = nil; +static Lock quadlock; QuadnameDef quadnames[] = { {L"⍞", NameTag, getquotequad, setquotequad, nil, nil}, @@ -35,11 +39,13 @@ QuadnameDef quadnames[] = { {L"⎕DIV", NameTag, getdiv, setdiv, nil, nil}, {L"⎕A", NameTag, geta, nil, nil, nil}, {L"⎕D", NameTag, getd, nil, nil, nil}, + {L"⎕SELF", NameTag, getself, nil, nil, nil}, {L"⎕RUN", FunctionTag, nil, nil, runfile, nil}, {L"⎕THROW", FunctionTag, nil, nil, quadthrow1, quadthrow2}, {L"⎕INFO", FunctionTag, nil, nil, quadinfo, nil}, {L"⎕PROTO", FunctionTag, nil, nil, quadproto, nil}, {L"⎕UCS", FunctionTag, nil, nil, quaducs, nil}, + {L"⎕DL", FunctionTag, nil, nil, quaddl, nil}, {nil, 0, nil, nil, nil, nil} /* MUST BE LAST */ }; @@ -88,6 +94,7 @@ quadnamedatum(QuadnameDef q) Datum * getquotequad(void) { + lock(&quadlock); int sizemax = 512; int size; Rune *input; @@ -114,12 +121,14 @@ getquotequad(void) result->tag = ArrayTag; result->array = mkrunearray(input); free(input); + unlock(&quadlock); return result; } void setquotequad(Datum new) { + lock(&quadlock); Rune *str = ppdatum(new); if(needsnewline && quadquotebuf != nil){ if(quadquotebuf){ @@ -135,6 +144,7 @@ setquotequad(Datum new) needsnewline = 1; print("%S", str); free(str); + unlock(&quadlock); } /* ⎕ */ @@ -150,8 +160,10 @@ getquad(void) void setquad(Datum new) { + lock(&quadlock); needsnewline = 0; print("%S\n", ppdatum(new)); + unlock(&quadlock); } /* ⎕IO */ @@ -231,6 +243,17 @@ getd(void) return d; } +/* ⎕SELF */ +Datum * +getself(void) +{ + Datum *d = mallocz(sizeof(Datum), 1); + d->tag = ArrayTag; + d->array = mkscalarint(threadid()); + return d; +} + + /* ⎕RUN */ Array * runfile(Array *a) @@ -337,4 +360,23 @@ quaducs(Array *a) }else throwerror(nil, EType); return res; +} + +/* ⎕DL */ +Array * +quaddl(Array *a) +{ + /* TODO: return amount of seconds slept */ + if(a->size != 1) + throwerror(nil, ELength); + if(a->type != AtypeInt && a->type != AtypeFloat) + throwerror(nil, EType); + + if(a->type == AtypeInt && a->intdata[0] >= 0) + sleep(a->intdata[0] * 1000); + else if(a->type == AtypeFloat && a->floatdata[0] >= 0) + sleep(a->floatdata[0] * 1000); + else + throwerror(nil, EDomain); + return fnSame(a); } \ No newline at end of file diff --git a/symbol.c b/symbol.c index ed6006d..4240ace 100644 --- a/symbol.c +++ b/symbol.c @@ -1,11 +1,11 @@ #include #include +#include #include #include "apl9.h" Symtab *globalsymtab; -DfnFrame *currentdfn; Symtab *newsymtab(void); void freesymtab(Symtab *); @@ -20,7 +20,8 @@ void setsyntaxerr(Datum); Symbol * getsym(Rune *name, int fresh) { - DfnFrame *dfn = currentdfn; + ThreadData *td = getthreaddata(); + DfnFrame *dfn = td->currentdfn; Symtab *tab; int done = 0; do{ @@ -28,10 +29,10 @@ getsym(Rune *name, int fresh) tab = dfn->symtab; else tab = globalsymtab; - - for(int i = 0; i < tab->nsyms; i++) + for(int i = 0; i < tab->nsyms; i++){ if(runestrcmp(tab->syms[i]->name, name) == 0) return tab->syms[i]; + } if(dfn) dfn = dfn->prev; else @@ -39,8 +40,8 @@ getsym(Rune *name, int fresh) }while(!done && !fresh); /* make sure to allocate in the most local scope if the symbol is not found */ - if(currentdfn) - tab = currentdfn->symtab; + if(td->currentdfn) + tab = td->currentdfn->symtab; tab->nsyms++; tab->syms = realloc(tab->syms, sizeof(Symbol *) * tab->nsyms); @@ -106,12 +107,14 @@ initsymtab(void) DfnFrame * getcurrentdfn(void) { - return currentdfn; + ThreadData *td = getthreaddata(); + return td->currentdfn; } DfnFrame * pushdfnframe(Rune *code, Datum *lefto, Datum *righto, Array *left, Array *right) { + ThreadData *td = getthreaddata(); DfnFrame *new = malloc(sizeof(DfnFrame)); new->code = code; new->symtab = newsymtab(); @@ -124,27 +127,29 @@ pushdfnframe(Rune *code, Datum *lefto, Datum *righto, Array *left, Array *right) }else new->left = nil; new->right = right; - new->prev = currentdfn; - currentdfn = new; + new->prev = td->currentdfn; + td->currentdfn = new; return new; } void popdfnframe(void) { - if(currentdfn != nil){ - DfnFrame *prev = currentdfn->prev; - freesymtab(currentdfn->symtab); - free(currentdfn); - currentdfn = prev; + ThreadData *td = getthreaddata(); + if(td->currentdfn != nil){ + DfnFrame *prev = td->currentdfn->prev; + freesymtab(td->currentdfn->symtab); + free(td->currentdfn); + td->currentdfn = prev; } } vlong globalIO(void) { - if(currentdfn) - return currentdfn->symtab->io; + ThreadData *td = getthreaddata(); + if(td->currentdfn) + return td->currentdfn->symtab->io; else if(globalsymtab) return globalsymtab->io; else @@ -154,8 +159,9 @@ globalIO(void) void globalIOset(vlong io) { - if(currentdfn) - currentdfn->symtab->io = io; + ThreadData *td = getthreaddata(); + if(td->currentdfn) + td->currentdfn->symtab->io = io; else globalsymtab->io = io; } @@ -163,8 +169,9 @@ globalIOset(vlong io) int globalDIV(void) { - if(currentdfn) - return currentdfn->symtab->div; + ThreadData *td = getthreaddata(); + if(td->currentdfn) + return td->currentdfn->symtab->div; else if(globalsymtab) return globalsymtab->div; else @@ -174,8 +181,9 @@ globalDIV(void) void globalDIVset(int div) { - if(currentdfn) - currentdfn->symtab->div = div; + ThreadData *td = getthreaddata(); + if(td->currentdfn) + td->currentdfn->symtab->div = div; else globalsymtab->div = div; } @@ -192,7 +200,7 @@ getalpha(void) res = malloc(sizeof(Datum)); *res = *dfn->left; if(res->tag == ArrayTag) - incref(res->array); + incarrayref(res->array); return res; } return res; @@ -209,7 +217,7 @@ getomega(void) res = mallocz(sizeof(Datum), 1); res->tag = ArrayTag; res->array = dfn->right; - incref(res->array); + incarrayref(res->array); } return res; } @@ -225,7 +233,7 @@ getalphao(void) res = malloc(sizeof(Datum)); *res = *dfn->lefto; if(res->tag == ArrayTag) - incref(res->array); + incarrayref(res->array); } return res; } @@ -241,7 +249,7 @@ getomegao(void) res = malloc(sizeof(Datum)); *res = *dfn->righto; if(res->tag == ArrayTag) - incref(res->array); + incarrayref(res->array); } return res; } -- cgit v1.2.3