summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorglenda <glenda@cirno>2022-09-18 14:55:48 +0000
committerglenda <glenda@cirno>2022-09-18 14:55:48 +0000
commit269c81f0217999367b4180e6a795142cbb2d02e7 (patch)
tree5b9299a3a7a2304ebc4259c1570c378e17f1e28f
parent6430127cc4503e2e7e40f86ccc68594ced055274 (diff)
Implement remote message passing via pipes!
-rw-r--r--apl9.h1
-rw-r--r--concurrency.c2
-rw-r--r--main.c2
-rw-r--r--mkfile1
-rw-r--r--quadnames.c18
-rw-r--r--runtime/remote.apl28
-rw-r--r--symbol.c12
7 files changed, 54 insertions, 10 deletions
diff --git a/apl9.h b/apl9.h
index 8fa539d..69d50b6 100644
--- a/apl9.h
+++ b/apl9.h
@@ -229,6 +229,7 @@ struct DfnFrame
ErrorGuard *errorguards; /* a linked list of error handlers */
DfnFrame *prev; /* prev in the call stack */
DfnFrame *chain; /* prev in the lexical scope */
+ int keep; /* prevents it from being freed */
};
struct ThreadData
diff --git a/concurrency.c b/concurrency.c
index 6719e6a..f4709e9 100644
--- a/concurrency.c
+++ b/concurrency.c
@@ -220,9 +220,9 @@ newprocfn(SpawnData *sp)
freearray(sp->name);
freearray(sp->left);
freearray(sp->right);
+ freefunction(sp->func);
if(sp->func.scope)
freedfnframe(sp->func.scope, 0);
- freefunction(sp->func);
free(sp);
free(td);
exits(nil);
diff --git a/main.c b/main.c
index 3da4841..d921810 100644
--- a/main.c
+++ b/main.c
@@ -9,6 +9,7 @@ Biobuf *stdin;
static int booted = 0;
static Rune *startfile = L"/sys/lib/apl/runtime/start.apl";
static Rune *stdlibfile = L"/sys/lib/apl/runtime/stdlib.apl";
+static Rune *remotefile = L"/sys/lib/apl/runtime/remote.apl";
void
main(int argc, char *argv[])
@@ -43,6 +44,7 @@ restart:
if(!booted){
booted = 1;
runfile(mkrunearray(stdlibfile));
+ runfile(mkrunearray(remotefile));
runfile(mkrunearray(startfile));
}
diff --git a/mkfile b/mkfile
index 1f262de..2f239c7 100644
--- a/mkfile
+++ b/mkfile
@@ -24,6 +24,7 @@ BIN=/$objtype/bin
DISTFILES=\
runtime/stdlib.apl\
+ runtime/remote.apl\
runtime/start.apl\
ACMEFILES=\
diff --git a/quadnames.c b/quadnames.c
index b7c04d0..29e973d 100644
--- a/quadnames.c
+++ b/quadnames.c
@@ -681,17 +681,19 @@ quadwrite(Array *fd, Array *data)
{
if(GetType(fd) != AtypeInt || GetSize(fd) != 1)
throwerror(L"Invalid fd", EDomain);
- if(GetType(data) != AtypeInt || GetRank(fd) > 1)
- throwerror(L"Data must be a scalar or vector of bytes", EDomain);
+
+ if((GetType(data) != AtypeInt && GetType(data) != AtypeFloat) || GetRank(data) > 1)
+ throwerror(L"Data must be a scalar or vector of bytes!", EDomain);
u8int *raw = emalloc(GetSize(data));
for(int i = 0; i < GetSize(data); i++){
- u64int v = data->intdata[i];
- if(v > 255){
- free(raw);
- throwerror(L"Data values must be bytes", EDomain);
- }else
- raw[i] = v;
+ u8int v;
+ switch(GetType(data)){
+ case AtypeInt: v = data->intdata[i]; break;
+ case AtypeFloat: v = data->floatdata[i]; break;
+ default: v = 0; break;
+ }
+ raw[i] = v;
}
long ret = write(fd->intdata[0], raw, GetSize(data));
free(raw);
diff --git a/runtime/remote.apl b/runtime/remote.apl
new file mode 100644
index 0000000..f696a15
--- /dev/null
+++ b/runtime/remote.apl
@@ -0,0 +1,28 @@
+REMOTE←{
+ fd←⎕PIPE ⍵
+ out←{
+ msg←{1(2⊃⍵)}⍇⍬
+ raw←0 ⎕SERIAL msg
+ len←(4⍴255)⊤≢raw
+ _←fd ⎕WRITE len,raw
+ ∇⍵
+ }
+ in←{
+ m←1 ⎕serial fd ⎕read (4⍴255)⊥fd ⎕read 4
+ _←m⍈⍵
+ ∇⍵
+ }
+ remote←{
+ 0≡≢⍵: ⍺∇out&'remote out'⊢⎕self ⍝ Spawn out thread
+ 1≡≢⍵: ⍺∇⍵,in&'remote in'⊢⎕self ⍝ Spawn in thread
+ (outid inid)←⍵
+ master←⍺
+ (from msg)←{1 ⍵}⍇⍬
+ _←{
+ from≡master: msg⍈outid
+ from≢master: msg⍈master
+ }⍬
+ ⍺∇⍵
+ }
+ ⎕self remote&'remote'⊢⍬
+}
diff --git a/symbol.c b/symbol.c
index 029ab0c..5d88f96 100644
--- a/symbol.c
+++ b/symbol.c
@@ -180,6 +180,9 @@ dupdfnframe(DfnFrame *f)
void
freedfnframe(DfnFrame *f, int keeperrorguards)
{
+ if(f->keep)
+ return;
+
freesymtab(f->symtab);
freedatum(f->lefto);
freedatum(f->righto);
@@ -337,12 +340,19 @@ dupscope(DfnFrame *dfn)
Symbol *sym = d->symtab->syms[i];
int found = 0;
for(int j = 0; j < new->symtab->nsyms && !found; j++)
- if(runestrcmp(new->symtab->syms[i]->name, d->symtab->syms[j]->name) == 0)
+ if(runestrcmp(new->symtab->syms[j]->name, d->symtab->syms[i]->name) == 0)
found = 1;
if(!found){
new->symtab->nsyms++;
new->symtab->syms = erealloc(new->symtab->syms, sizeof(Symbol *) * new->symtab->nsyms);
new->symtab->syms[new->symtab->nsyms-1] = dupsymbol(sym);
+ sym = new->symtab->syms[new->symtab->nsyms-1];
+ if(sym->value){
+ if(sym->value->tag == FunctionTag)
+ sym->value->func.scope->keep = 1;
+ if(sym->value->tag == MonadicOpTag || sym->value->tag == DyadicOpTag)
+ sym->value->operator.scope->keep = 1;
+ }
}
}
}