code: 9ferno

Download patch

ref: 853cdd446da5aa6c798f4109327c6dcf02ca2411
parent: d62c51c5ad190d2ce853a25feeb03ca511fcb01e
author: 9ferno <gophone2015@gmail.com>
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);
 }
-
+*/