summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2022-02-08 16:03:10 +0000
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2022-02-08 16:03:10 +0000
commitc6e1c83f93f63a061f0804821ed29c656da38f28 (patch)
tree8f3b8863d9db2d79722a4ec104bb2eeb807f87e0
parent511ae2c1879676568b2f11312c38a66b2caa21c0 (diff)
Add work in progress concurrency. Might break stuff!
-rw-r--r--apl9.h33
-rw-r--r--array.c6
-rw-r--r--concurrency.c148
-rw-r--r--error.c1
-rw-r--r--eval.c12
-rw-r--r--functions.c45
-rw-r--r--hybrids.c4
-rw-r--r--lexer.c1
-rw-r--r--main.c5
-rw-r--r--memory.c4
-rw-r--r--mkfile1
-rw-r--r--operators.c29
-rw-r--r--quadnames.c42
-rw-r--r--symbol.c60
14 files changed, 330 insertions, 61 deletions
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 <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <bio.h>
+#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 <u.h>
#include <libc.h>
+#include <thread.h>
#include <bio.h>
#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 <u.h>
#include <libc.h>
+#include <thread.h>
#include <bio.h>
#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 <u.h>
#include <libc.h>
+#include <thread.h>
#include <bio.h>
#include <pool.h>
@@ -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)
@@ -91,6 +92,15 @@ opKey(Datum *lefto, Array *left, Array *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)
{
if(left == nil)
@@ -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 <u.h>
#include <libc.h>
+#include <thread.h>
#include <bio.h>
#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 <u.h>
#include <libc.h>
+#include <thread.h>
#include <bio.h>
#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;
}