summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorglenda <glenda@cirno>2022-09-13 18:30:06 +0000
committerglenda <glenda@cirno>2022-09-13 18:30:06 +0000
commitb7e3d0927fe0821e919ccc4a66ef149bddcc20de (patch)
tree2c6e2e4fa7d31d3443dab3c0799bb6a44f60bcde
parent34adf252d179556df7d8277370e735c56c6ab3f5 (diff)
Switch to rfork instead of libthread
-rw-r--r--apl9.h12
-rw-r--r--array.c5
-rw-r--r--concurrency.c101
-rw-r--r--error.c4
-rw-r--r--functions.c3
-rw-r--r--lexer.c1
-rw-r--r--main.c5
-rw-r--r--memory.c21
-rw-r--r--quadnames.c5
-rw-r--r--symbol.c1
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 <u.h>
#include <libc.h>
-#include <thread.h>
#include <bio.h>
#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 <u.h>
#include <libc.h>
-#include <thread.h>
#include <bio.h>
+#include <tos.h>
#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 <u.h>
#include <libc.h>
-#include <thread.h>
#include <bio.h>
#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 <u.h>
#include <libc.h>
-#include <thread.h>
#include <bio.h>
#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 <u.h>
#include <libc.h>
-#include <thread.h>
#include <bio.h>
#include <pool.h>
@@ -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 <u.h>
#include <libc.h>
-#include <thread.h>
#include <bio.h>
#include <pool.h>
@@ -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 <u.h>
#include <libc.h>
-#include <thread.h>
#include <bio.h>
#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 <u.h>
#include <libc.h>
-#include <thread.h>
#include <bio.h>
#include "apl9.h"