summaryrefslogtreecommitdiff
path: root/concurrency.c
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 /concurrency.c
parent34adf252d179556df7d8277370e735c56c6ab3f5 (diff)
Switch to rfork instead of libthread
Diffstat (limited to 'concurrency.c')
-rw-r--r--concurrency.c101
1 files changed, 40 insertions, 61 deletions
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