From b7e3d0927fe0821e919ccc4a66ef149bddcc20de Mon Sep 17 00:00:00 2001 From: glenda Date: Tue, 13 Sep 2022 18:30:06 +0000 Subject: Switch to rfork instead of libthread --- apl9.h | 12 ++----- array.c | 5 ++- concurrency.c | 101 +++++++++++++++++++++++----------------------------------- error.c | 4 --- functions.c | 3 +- lexer.c | 1 - main.c | 5 ++- memory.c | 21 ++++++------ quadnames.c | 5 ++- symbol.c | 1 - 10 files changed, 61 insertions(+), 97 deletions(-) diff --git a/apl9.h b/apl9.h index 6709dcb..8fa539d 100644 --- a/apl9.h +++ b/apl9.h @@ -2,9 +2,6 @@ #define MAX_LINE_LENGTH 1024 #define MAX_LINE_TOKENS 1024 -#define STACKSIZE (1024*1024) /* 1 MB */ -#define REQUIREDSTACK (16*1024) /* 16 KB */ - typedef enum { ArrayTag, @@ -237,7 +234,7 @@ struct DfnFrame struct ThreadData { int id; - int requiredstack; + int stackused; DfnFrame *currentdfn; Mail *mail; Mail *lastmail; @@ -355,9 +352,7 @@ void messagesend(Array *, int); Array *messagerecv(Function, int); Array *runningthreads(void); Array *threadproperty(vlong, vlong); -int stackused(void); -int hasstack(int); -void checkstack(void); +void stackusage(void); /* Monadic functions from function.c */ Array *fnNegate(Array *); @@ -497,5 +492,4 @@ extern opmonad hybridoperatordefs[]; /* hybrids.c */ extern int arrayalloccounts; /* memory.c */ extern int datumalloccounts; /* memory.c */ extern QuadnameDef quadnames[]; /* quadnames.c */ -extern int printprecision; /* print.c */ -extern int mainstacksize; /* concurrency.c */ \ No newline at end of file +extern int printprecision; /* print.c */ \ No newline at end of file diff --git a/array.c b/array.c index a46668b..554c60b 100644 --- a/array.c +++ b/array.c @@ -1,6 +1,5 @@ #include #include -#include #include #include "apl9.h" @@ -323,7 +322,7 @@ comparearray(Array *a, Array *b, int checkshapes) break; default: print("Missing comparison code for type %d\n", GetType(a)); - threadexitsall(nil); + exits(nil); } if(sub != 0) return sub; @@ -365,7 +364,7 @@ fillelement(Array *a) } default: print("Can't make fill element of array type %d\n", GetType(a)); - threadexitsall(nil); + exits(nil); return 0; } } diff --git a/concurrency.c b/concurrency.c index 28cea35..9670866 100644 --- a/concurrency.c +++ b/concurrency.c @@ -1,13 +1,10 @@ #include #include -#include #include +#include #include "apl9.h" -/* Nasty stuff to get stack size used */ -#include "/sys/src/libthread/threadimpl.h" - typedef struct SpawnData SpawnData; struct SpawnData { @@ -15,37 +12,40 @@ struct SpawnData Array *name; Array *left; Array *right; - Channel *setupdone; }; -static void newprocfn(void *); +static void newprocfn(SpawnData *); static ThreadData *newthreaddata(Array *); +extern void **_privates; + /* global data */ static Lock threadlock; static int nthreads; static ThreadData **threads; -int mainstacksize = STACKSIZE; -void -recvtimeout(void *raw) +int +recvtimeout(void *, char *note) { - ThreadData *td = (ThreadData *)raw; - if(0 == sleep(td->timeout)){ + if(strcmp(note, "alarm") != 0) + return 0; + + ThreadData *td = getthreaddata(); + if(rfork(RFPROC|RFMEM) == 0){ qlock(&td->lock); td->timedout = 1; rwakeup(&td->newmail); qunlock(&td->lock); + exits(nil); } + return 1; } void initthreads(void) { Array *name = mkrunearray(L"main"); - ThreadData *td = newthreaddata(name); - void **tdptr = procdata(); - *tdptr = td; + _privates[0] = newthreaddata(name); freearray(name); } @@ -64,25 +64,25 @@ spawnthread(Function f, Array *name, Array *left, Array *right) unlock datastructures exit proc */ - Channel *setupdone = chancreate(sizeof(int), 0); SpawnData *sp = emalloc(sizeof(SpawnData)); sp->func = dupfunction(f); sp->func.scope = dupscope(f.scope); sp->name = duparray(name); 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); + + int id = rfork(RFPROC|RFMEM); + if(id == 0){ /* in new process*/ + newprocfn(sp); + exits(nil); + } return id; } ThreadData * getthreaddata(void) { - void **tdptr = procdata(); - return (ThreadData *)*tdptr; + return (ThreadData *)_privates[0]; } void @@ -122,11 +122,10 @@ messagerecv(Function match, int timeout) qlock(&td->lock); /* Start a "timeout thread" if needed */ - int timeoutid = 0; td->timedout = 0; /* clear the timeout bit */ if(timeout > 0){ - td->timeout = timeout; - timeoutid = proccreate(recvtimeout, td, STACKSIZE); + atnotify(recvtimeout, 1); + alarm(timeout); } /* Wait for a message, or timeout */ @@ -166,8 +165,10 @@ Retry: } /* We found a match, remove the mail from the mailbox, and kill the timeout */ - if(timeout > 0) - threadkill(timeoutid); + if(timeout > 0){ + atnotify(recvtimeout, 0); + alarm(0); + } if(td->mail == m) td->mail = m->next; else{ @@ -186,20 +187,15 @@ Retry: } static void -newprocfn(void *data) +newprocfn(SpawnData *sp) { - SpawnData *sp = (SpawnData *)data; ThreadData *td = newthreaddata(sp->name); - void **tdptr = procdata(); - *tdptr = td; + _privates[0] = td; ErrorGuard *eg = newerrorguard(mkscalarint(0), nil); /* make a catch-all error guard */ if(setjmp(eg->jmp)) displayerror(); - else{ - int done = 1; - send(sp->setupdone, &done); + else runfunc(sp->func, sp->left, sp->right); - } lock(&threadlock); for(int i = 0; i < nthreads; i++){ if(threads[i] != td) @@ -219,14 +215,15 @@ newprocfn(void *data) freefunction(sp->func); free(sp); free(td); + exits(nil); } static ThreadData * newthreaddata(Array *name) { ThreadData *td = emallocz(sizeof(ThreadData), 1); - td->id = threadid(); - td->requiredstack = REQUIREDSTACK; + td->id = getpid(); + td->stackused = 0; td->currentdfn = nil; td->mail = 0; td->lastmail = 0; @@ -240,6 +237,7 @@ newthreaddata(Array *name) threads = erealloc(threads, sizeof(ThreadData *) * nthreads); threads[nthreads-1] = td; unlock(&threadlock); + return td; } @@ -275,19 +273,16 @@ threadproperty(vlong t, vlong p) case 1: /* thread name */ res = fnSame(td->name); break; - case 2: /* stacksize max */ - res = mkscalarint(STACKSIZE); - break; - case 3: /* used stacksize */ - res = mkscalarint(stackused()); - break; - case 4: /* messages in mailbox */ + case 2: /* messages in mailbox */ qlock(&td->lock); for(Mail *tmp = td->mail; tmp != nil; tmp = tmp->next) mailcount++; qunlock(&td->lock); res = mkscalarint(mailcount); break; + case 3: /* used stacksize */ + res = mkscalarint(td->stackused); + break; default: unlock(&threadlock); throwerror(L"Invalid thread property", EDomain); @@ -298,25 +293,9 @@ threadproperty(vlong t, vlong p) return res; } -int -stackused(void) -{ - int x; - Proc *p = _threadgetproc(); - Thread *t = p->thread; - return STACKSIZE - ((uchar*)&x - (uchar*)t->stk); -} - -int -hasstack(int n) -{ - return (n+stackused()) < STACKSIZE; -} - void -checkstack(void) +stackusage(void) { ThreadData *td = getthreaddata(); - if(!hasstack(td->requiredstack)) - throwerror(L"Not enough C stack. Stuff will go bad from now on.", EStack); + td->stackused = ((uchar*)_tos - (uchar *)&td); } \ No newline at end of file diff --git a/error.c b/error.c index 5b7f386..4d04696 100644 --- a/error.c +++ b/error.c @@ -1,6 +1,5 @@ #include #include -#include #include #include "apl9.h" @@ -78,14 +77,11 @@ void displayerror(void) { ThreadData *td = getthreaddata(); - int tmp = td->requiredstack; - td->requiredstack = 0; Array *error = allocarray(AtypeArray, 1, 3); error->shape[0] = 3; error->arraydata[0] = mkrunearray(errorstr(td->lasterror)); error->arraydata[1] = mkrunearray(td->lasterrormsg ? td->lasterrormsg : L""); error->arraydata[2] = fnSame(td->name); rundfn(L"0::⎕RAWIO←⍵ ⋄ ('!' ⍵) ⍈ ⎕SESSION", nil, nil, nil, error); - td->requiredstack = tmp; freearray(error); } \ No newline at end of file diff --git a/functions.c b/functions.c index 3559050..30a7dd1 100644 --- a/functions.c +++ b/functions.c @@ -128,7 +128,8 @@ Array *indexOfHelper(Array *, Array *, int); Array * runfunc(Function f, Array *left, Array *right) { - checkstack(); + stackusage(); /* update it */ + Array *result; if(f.type == FunctypeDfn || (f.type == FunctypeOp && f.operator.type == OperatortypeDop)){ Rune *code; diff --git a/lexer.c b/lexer.c index 68e1fa0..9971ecd 100644 --- a/lexer.c +++ b/lexer.c @@ -1,6 +1,5 @@ #include #include -#include #include #include "apl9.h" diff --git a/main.c b/main.c index 4931920..3da4841 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,5 @@ #include #include -#include #include #include @@ -12,7 +11,7 @@ static Rune *startfile = L"/sys/lib/apl/runtime/start.apl"; static Rune *stdlibfile = L"/sys/lib/apl/runtime/stdlib.apl"; void -threadmain(int argc, char *argv[]) +main(int argc, char *argv[]) { int off = 0; stdin = Bfdopen(0, OREAD); @@ -61,7 +60,7 @@ restart: print("Unfreed datums: %d\n", datumalloccounts); */ } - threadexitsall(nil); + exits(nil); } Datum * diff --git a/memory.c b/memory.c index bdec236..e55485a 100644 --- a/memory.c +++ b/memory.c @@ -1,6 +1,5 @@ #include #include -#include #include #include @@ -16,7 +15,7 @@ emalloc(ulong size) void *res = malloc(size); if(res == nil && size > 0){ print("Out of memory! :(\n"); - threadexitsall("emalloc"); + exits("emalloc"); } return res; } @@ -27,7 +26,7 @@ emallocz(ulong size, int clr) void *res = mallocz(size, clr); if(res == nil && size > 0){ print("Out of memory! :(\n"); - threadexitsall("emallocz"); + exits("emallocz"); } return res; } @@ -38,7 +37,7 @@ erealloc(void *ptr, ulong size) void *res = realloc(ptr, size); if(res == nil && size > 0){ print("Out of memory! :(\n"); - threadexitsall("erealloc"); + exits("erealloc"); } return res; } @@ -59,7 +58,7 @@ freearray(Array *a) return; if(GetRefs(a) == 0){ print("NEGATIVE REF COUNT (array)! %p\n", a); - threadexitsall(nil); + exits(nil); } SetRefs(a, GetRefs(a)-1); @@ -148,13 +147,13 @@ freedatum(Datum *d) break; default: print("Don't know how to free datum with tag: %d\n", d->tag); - threadexitsall("freedatum"); + exits("freedatum"); } free(d); datumalloccounts--; }else if(d->refs < 0){ print("NEGATIVE REF COUNT (datum)! %p\n", d); - threadexitsall(nil); + exits(nil); } } @@ -189,7 +188,7 @@ freefunction(Function f) break; default: print("Missing case in freefunction: %d\n", f.type); - threadexitsall("freefunction"); + exits("freefunction"); } } @@ -207,7 +206,7 @@ freeoperator(Operator o) break; default: print("Missing case in freeoperator: %d\n", o.type); - threadexitsall("freeoperator"); + exits("freeoperator"); } } @@ -250,7 +249,7 @@ dupfunction(Function f) break; default: print("Missing case in dupfunction: %d\n", f.type); - threadexitsall("dupfunction"); + exits("dupfunction"); } return g; @@ -273,7 +272,7 @@ dupoperator(Operator o) break; default: print("Missing case in dupoperator: %d\n", o.type); - threadexitsall("dupoperator"); + exits("dupoperator"); } return p; } diff --git a/quadnames.c b/quadnames.c index 3340ac6..8c7490c 100644 --- a/quadnames.c +++ b/quadnames.c @@ -1,6 +1,5 @@ #include #include -#include #include #include "apl9.h" @@ -95,7 +94,7 @@ quadnamedatum(QuadnameDef q) case DyadicOpTag: default: print("Can't use quad names with type=%d\n", q.tag); - threadexitsall(nil); + exits(nil); } return d; } @@ -291,7 +290,7 @@ Datum * getself(void) { Datum *d = allocdatum(ArrayTag, 0); - d->array = mkscalarint(threadid()); + d->array = mkscalarint(getpid()); return d; } diff --git a/symbol.c b/symbol.c index 626a2db..2f5165b 100644 --- a/symbol.c +++ b/symbol.c @@ -1,6 +1,5 @@ #include #include -#include #include #include "apl9.h" -- cgit v1.2.3