ref: 853cdd446da5aa6c798f4109327c6dcf02ca2411
parent: d62c51c5ad190d2ce853a25feeb03ca511fcb01e
author: 9ferno <[email protected]>
date: Sat Jan 15 09:23:53 EST 2022
compiling version of devshm
--- a/os/pc64/forth.h
+++ b/os/pc64/forth.h
@@ -2139,7 +2139,7 @@
{.type FromH0, {.p C_cr}, .src = "dd C_cr"}, /* dd C_cr 17464 */
{.type FromH0, {.p C_abort}, .src = "dd C_abort"}, /* dd C_abort 17472 */
{.type FromH0, {.p M_exitcolon}, .src = "dd M_exitcolon"}, /* dd M_exitcolon 17480 */
- {.type Header, {.hdr { 9, "create-file", /* C_create_file = 17504 */ colon }}}, /* CENTRY "create-file" create_file 9 ; ( a n mode perm -- fd ioresult ) not part of the original ff. could move this to a forth file. h 17512 */
+ {.type Header, {.hdr { 11, "create-file", /* C_create_file = 17504 */ colon }}}, /* CENTRY "create-file" create_file 11 ; ( a n mode perm -- fd ioresult ) not part of the original ff. could move this to a forth file. h 17512 */
{.type FromH0, {.p M_rpush}, .src = "dd M_rpush ; ( a n mode ) (R perm)"}, /* dd M_rpush ; ( a n mode ) (R perm) 17520 */
{.type FromH0, {.p M_rpush}, .src = "dd M_rpush ; ( a n ) (R perm mode)"}, /* dd M_rpush ; ( a n ) (R perm mode) 17528 */
{.type FromH0, {.p C_pad}, .src = "dd C_pad ; ( a n padaddr)"}, /* dd C_pad ; ( a n padaddr) 17536 */
--- a/os/pc64/pc64
+++ b/os/pc64/pc64
@@ -11,9 +11,10 @@
prog
rtc
srv
- dup
ssl
+ dup
cap
+ shm
ether netif
bridge netif log
--- a/os/pc64/words-nasm.s
+++ b/os/pc64/words-nasm.s
@@ -1740,7 +1740,7 @@
dd C_abort
L246:
dd M_exitcolon
-CENTRY "create-file" C_create_file 9 ; ( a n mode perm -- fd ioresult ) not part of the original ff. could move this to a forth file.
+CENTRY "create-file" C_create_file 11 ; ( a n mode perm -- fd ioresult ) not part of the original ff. could move this to a forth file.
dd M_rpush ; ( a n mode ) (R perm)
dd M_rpush ; ( a n ) (R perm mode)
dd C_pad ; ( a n padaddr)
--- a/os/port/devforth.c
+++ b/os/port/devforth.c
@@ -19,7 +19,7 @@
For now, use the stdin, stdout and stderr mechanism.
If the performance is good enough, add more syscalls and then replace dis/init with forth
TODO
- add ref's to frq, fwq and ferrq
+ add initial memsize to Qnew
*/
enum
{
@@ -400,9 +400,9 @@
/*
shmem = 0, NOSHMEM no shared memory
shmem = 1, SHMEM share memory
-TODO shmem = 2, NEWSHMEM new shared memory
+ shmem = 2, NEWSHMEM new shared memory, leave it as nil, attach() will create it
*/
- if(params->shmem == 0){
+ if(params->shmem == 0 || params->shmem == 2){
p->shm = nil;
}else if(params->shmem == 1){
p->shm = up->shm;
--- a/os/port/devshm.c
+++ b/os/port/devshm.c
@@ -9,17 +9,26 @@
/*
1. Provides #h/shm for shared user memory
+ 2. similar to env(3)
+
How is this different from devenv?
O(1) for read and write
using array index as the path to keep lookups to O(1)
Keep c->aux = Svalue*
So, can read/write directly
+ attach() incref's Sgrp
+ open() incref's Svalue
+ close() decref's Svalue
If the length is greater than 1 read/write IO unit, then
this mechanism fails. Need an shmbig that puts rlock/wlock
at open() for that to work.
TODO
- needs some mechanism in devforth.c to create up->shm
+ needs some mechanism in devforth.c to create up->shm - attach() and up->shm == nil
+ kcreate() binding
+ forth: test
+ create write close
+ open read close
error if iounit(0 fd) > len
not doing
@@ -34,6 +43,7 @@
enum
{
DELTAENV = 32,
+ Maxshmsize = 1024,
};
/*
@@ -86,6 +96,7 @@
char *value;
s32 len;
s32 vers;
+ u8 dead; /* set by remove() */
};
typedef struct Sgrp Sgrp;
@@ -94,8 +105,8 @@
Ref;
RWlock;
union{ /* array of Svalue pointers */
- Svalue *entries;
- Svalue *ent;
+ Svalue **entries;
+ Svalue **ent;
};
int nent; /* number of entries used */
int ment; /* maximum number of entries */
@@ -102,18 +113,21 @@
u32 vers; /* of Sgrp */
};
+Sgrp* newshmgrp(void);
+static int shmwriteable(Chan *c);
+
static Svalue*
shmlookupname(Sgrp *g, char *name)
{
- Svalue *v, *ev;
+ Svalue **ent, **eent;
if(name == nil)
return nil;
- v = g->ent;
- for(ev = v + g->nent; v < ev; v++){
- if(name[0] == v->name[0] && strcmp(v->name, name) == 0))
- return v;
+ ent = g->ent;
+ for(eent = ent + g->nent; ent < eent; ent++){
+ if(name[0] == (*ent)->name[0] && strcmp((*ent)->name, name) == 0)
+ return *ent;
}
return nil;
}
@@ -121,8 +135,6 @@
static Svalue*
shmlookuppath(Sgrp *g, s64 qidpath)
{
- Svalue *v, *ev;
-
if(qidpath == -1)
return nil;
if(qidpath > g->nent)
@@ -132,14 +144,14 @@
}
/* same as envlookup */
-static Evalue*
+static Svalue*
shmlookup(Sgrp *g, char *name, s64 qidpath)
{
if(qidpath != -1)
- return shmlookuppath(sg, qidpath);
+ return shmlookuppath(g, qidpath);
if(name != nil)
- return shmlookupname(sg, name);
+ return shmlookupname(g, name);
return nil;
}
@@ -147,14 +159,14 @@
static s32
shmlookupidx(Sgrp *g, char *name)
{
- Svalue *v, *ev;
+ Svalue **ent;
s32 i;
if(name == nil)
return -1;
- for(i = 0, v = g->ent; i < g->nent; i++, v++){
- if(name[0] == v->name[0] && strcmp(v->name, name) == 0))
+ for(i = 0, ent = g->ent; i < g->nent; i++, ent++){
+ if(name[0] == (*ent)->name[0] && strcmp((*ent)->name, name) == 0)
return i;
}
return -1;
@@ -170,7 +182,7 @@
s32 i;
if(s == DEVDOTDOT){
- devdir(c, c->qid, "#s", 0, eve, 0775, dp);
+ devdir(c, c->qid, "#h", 0, eve, 0775, dp);
return 1;
}
@@ -178,15 +190,19 @@
return -1;
i = -1;
+ rlock(g);
if(name != nil)
i = shmlookupidx(g, name);
if((name == nil || i == -1) && s <= g->nent)
i = s;
- if(i == -1)
+ if(i == -1){
+ runlock(g);
return -1;
+ }
v = g->ent[i];
if(v == nil || name != nil && (strlen(v->name) >= sizeof(up->genbuf))) {
+ runlock(g);
return -1;
}
@@ -201,11 +217,11 @@
shmattach(char *spec)
{
Chan *c;
- Sgrp *g;
if(up->shm == nil)
- error(Enonexist);
+ up->shm = newshmgrp();
+print("devshm: attach up->shm 0x%p\n", up->shm);
c = devattach('h', spec);
mkqid(&c->qid, 0, 0, QTDIR);
c->aux = up->shm;
@@ -218,20 +234,8 @@
{
Walkqid *wq;
- rlock(up->shm);
+print("shmwalk nname %d name %s\n", nname, name);
wq = devwalk(c, nc, name, nname, 0, 0, shmgen);
- if(wq != nil && wq->clone != nil && wq->clone != c){
- wq->clone->aux = up->shm->ent[wq->clone->qid.path-1];
- DBG("shmwalk wq->clone->path %s mode 0x%ux\n"
- " wq->clone->qid.path 0x%zux wq->clone->qid.vers %d\n"
- " wq->clone->qid.type %d 0x%ux\n"
- " wq->clone->aux 0x%zx\n",
- chanpath(nc), wq->clone->mode,
- wq->clone->qid.path, wq->clone->qid.vers,
- wq->clone->qid.type, wq->clone->qid.type,
- wq->clone->aux);
- }
- runlock(up->shm);
return wq;
}
@@ -266,35 +270,39 @@
if(c->qid.type & QTDIR) {
if(omode != OREAD)
error(Eperm);
+ c->mode = openmode(omode);
+ c->offset = 0;
+ c->flag |= COPEN;
+ return c;
}
- else {
- trunc = omode & OTRUNC;
- if(omode != OREAD && shmwriteable(c) == 0)
- error(Eperm);
- if(trunc)
- wlock(g);
- else
- rlock(g);
- v = c->aux;
- if(v == nil) {
- if(trunc)
- wunlock(g);
- else
- runlock(g);
- error(Enonexist);
- }
- if(trunc && v->value != nil) {
- v->vers++;
- free(v->value);
- v->value = nil;
- v->len = 0;
- }
+ trunc = omode & OTRUNC;
+ if(omode != OREAD && shmwriteable(c) == 0)
+ error(Eperm);
+ if(trunc)
+ wlock(g);
+ else
+ rlock(g);
+
+ v = c->aux;
+ if(v == nil) {
if(trunc)
wunlock(g);
else
runlock(g);
+ error(Enonexist);
}
+ if(trunc && v->value != nil) {
+ v->vers++;
+ free(v->value);
+ v->value = nil;
+ v->len = 0;
+ }
+ if(trunc)
+ wunlock(g);
+ else
+ runlock(g);
+
c->mode = openmode(omode);
incref(v);
c->offset = 0;
@@ -303,12 +311,13 @@
}
static void
-shmcreate(Chan *c, char *name, u32 omode, u32)
+shmcreate(Chan *c, char *name, u32 omode, u32 perm)
{
Sgrp *g;
- Svalue *v, *ev;
+ Svalue *v;
s32 i;
+print("devshm: create name %s mode 0x%ux perm 0x%ux\n", name, omode, perm);
if(c->qid.type != QTDIR || shmwriteable(c) == 0)
error(Eperm);
@@ -330,7 +339,7 @@
error(Eexist);
if(g->nent == g->ment){
- Evalue *tmp;
+ Svalue **tmp;
g->ment += DELTAENV;
if((tmp = realloc(g->ent, sizeof(intptr)*g->ment)) == nil){
@@ -342,7 +351,7 @@
g->vers++;
/* find any remove'd entries to reuse */
for(i = 0; i < g->nent; i++){
- if(g->ent[i] == nil)
+ if(((Svalue*)g->ent[i]) == nil)
goto found;
}
i = g->nent;
@@ -363,6 +372,7 @@
c->offset = 0;
c->mode = omode;
c->flag |= COPEN;
+print("devshm: created chanpath(c) %s\n", chanpath(c));
return;
}
@@ -373,16 +383,15 @@
*/
shmread(Chan *c, void *a, s32 n, s64 off)
{
- Sgrp *g;
Svalue *v;
u64 offset = off;
+ if(up->shm == nil)
+ error(Enonexist);
+
if(c->qid.type & QTDIR)
return devdirread(c, a, n, 0, 0, shmgen);
- if((g = up->shm) == nil)
- error(Enonexist);
-
if((v = c->aux) == nil || v->dead == 1)
error(Enonexist);
@@ -395,7 +404,7 @@
n = 0;
else
memmove(a, v->value+offset, n);
- c->qid.vers = v->qid.vers;
+ c->qid.vers = v->vers;
runlock(v);
return n;
@@ -406,8 +415,7 @@
{
char *s;
ulong len;
- Sgrp *eg;
- Svalue *e;
+ Svalue *v;
u64 offset = off;
if(n <= 0)
@@ -415,7 +423,7 @@
if(offset > Maxshmsize || n > (Maxshmsize - offset))
error(Etoobig);
- if((g = up->shm) == nil)
+ if(up->shm == nil)
error(Enonexist);
if((v = c->aux) == nil || v->dead == 1)
@@ -423,13 +431,12 @@
wlock(v);
len = offset+n;
- if(len > e->len) {
- s = realloc(e->value, len);
+ if(len > v->len) {
+ s = realloc(v->value, len);
if(s == nil){
wunlock(v);
error(Enomem);
}
- memset(s+offset, 0, n);
v->value = s;
v->len = len;
}
@@ -442,11 +449,10 @@
}
static void
-shmclose(Chan *c)
+shmremove(Chan *c)
{
Sgrp *g;
Svalue *v;
- s32 d;
if(c->qid.type & QTDIR)
return;
@@ -457,6 +463,39 @@
if((v = c->aux) == nil)
error(Enonexist);
+ wlock(v);
+ v->dead = 1;
+ if(v->ref > 0){
+ wunlock(v);
+ return;
+ }
+ if(v->name != nil)
+ free(v->name);
+ if(v->value != nil)
+ free(v->value);
+ wunlock(v);
+
+ wlock(g);
+ g->ent[c->qid.path-1] = nil;
+ free(v);
+ wunlock(g);
+}
+
+static void
+shmclose(Chan *c)
+{
+ Svalue *v;
+ s32 d;
+
+ if(c->qid.type & QTDIR)
+ return;
+
+ if(up->shm == nil)
+ error(Enonexist);
+
+ if((v = c->aux) == nil)
+ error(Enonexist);
+
d = decref(v);
if(v->dead == 1 && d <= 0){
@@ -475,39 +514,6 @@
}
}
-static void
-shmremove(Chan *c)
-{
- Sgrp *eg;
- Svalue *e;
-
- if(c->qid.type & QTDIR)
- return;
-
- if((g = up->shm) == nil)
- error(Enonexist);
-
- if((v = c->aux) == nil)
- error(Enonexist);
-
- wlock(v);
- v->dead = 1;
- if(v->r.ref > 0){
- wunlock(v);
- return;
- }
- if(v->name != nil)
- free(v->name);
- if(v->value != nil)
- free(v->value);
- wunlock(v);
-
- wlock(g);
- g->ent[c->qid.path-1] = nil;
- free(v);
- wunlock(g);
-}
-
Dev shmdevtab = {
'h',
"shm",
@@ -545,18 +551,19 @@
void
closesgrp(Sgrp *g)
{
- Svalue *v, *ev;
+ Svalue **v, **ev;
+ s32 i;
if(g == nil)
return;
- if(decref(eg) == 0){
+ if(decref(g) <= 0){
v = g->ent;
for(i = 0, ev = v + g->nent; v < ev; v++, i++){
if(v == nil)
continue;
- wlock(v);
- free(v->name);
- free(v->value);
+ wlock(*v);
+ free((*v)->name);
+ free((*v)->value);
g->ent[i] = nil;
/* wunlock(v); */
free(v);
@@ -572,11 +579,11 @@
return c->aux == nil || c->aux == up->shm;
}
-/* same as shmcpy() of 9front */
-void
+/* same as shmcpy() of 9front, a simpler fork()(?) */
+/* TODO void
sgrpcpy(Sgrp *to, Sgrp *from)
{
- Svalue *e, *ee, *ne;
+ Svalue **e, **ee, **ne, *v, *nv;
rlock(from);
to->ment = ROUND(from->nent, DELTAENV);
@@ -584,12 +591,15 @@
ne = to->ent;
e = from->ent;
for(ee = e + from->nent; e < ee; e++, ne++){
- ne->name = smalloc(strlen(e->name)+1);
- strcpy(ne->name, e->name);
- if(e->value != nil){
- ne->value = smalloc(e->len);
- memmove(ne->value, e->value, e->len);
- ne->len = e->len;
+ v = *e;
+ nv = smalloc(sizeof(Svalue));
+ (*ne) = nv;
+ nv->name = smalloc(strlen(v->name)+1);
+ strcpy(nv->name, v->name);
+ if((v->len > 0){
+ nv->value = smalloc(v->len);
+ memmove(nv->value, v->value, v->len);
+ nv->len = v->len;
}
mkqid(&ne->qid, ++to->path, 0, QTFILE);
}
@@ -596,4 +606,4 @@
to->nent = from->nent;
runlock(from);
}
-
+*/