shithub: riscv

Download patch

ref: 37e4ce0ea75ae0e9a71d773d7fc7f16fd3d64fe7
parent: 29a53a52fdc3f8fc9af3d19d0253ba33b1efccba
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Aug 2 17:39:33 EDT 2015

devenv: avoid indirection, keep Evalue's allocated in an array

avoid the indirection for envlookup() by allocating Evalue structs
together in an array. remove unused link field in Evalue.

--- a/sys/src/9/port/devenv.c
+++ b/sys/src/9/port/devenv.c
@@ -7,6 +7,7 @@
 
 enum
 {
+	DELTAENV = 32,
 	Maxenvsize = 16300,
 };
 
@@ -18,12 +19,12 @@
 static Evalue*
 envlookup(Egrp *eg, char *name, ulong qidpath)
 {
-	Evalue *e;
-	int i;
+	Evalue *e, *ee;
 
-	for(i=0; i<eg->nent; i++){
-		e = eg->ent[i];
-		if(e->qid.path == qidpath || (name != nil && name[0] == e->name[0] && strcmp(e->name, name) == 0))
+	e = eg->ent;
+	for(ee = e + eg->nent; e < ee; e++){
+		if(e->qid.path == qidpath
+		|| (name != nil && name[0] == e->name[0] && strcmp(e->name, name) == 0))
 			return e;
 	}
 	return nil;
@@ -42,12 +43,12 @@
 
 	eg = envgrp(c);
 	rlock(eg);
-	e = nil;
 	if(name != nil)
 		e = envlookup(eg, name, -1);
 	else if(s < eg->nent)
-		e = eg->ent[s];
-
+		e = &eg->ent[s];
+	else
+		e = nil;
 	if(e == nil || name != nil && (strlen(e->name) >= sizeof(up->genbuf))) {
 		runlock(eg);
 		return -1;
@@ -141,7 +142,6 @@
 {
 	Egrp *eg;
 	Evalue *e;
-	Evalue **ent;
 
 	if(c->qid.type != QTDIR || !envwriteable(c))
 		error(Eperm);
@@ -151,7 +151,6 @@
 
 	omode = openmode(omode);
 	eg = envgrp(c);
-
 	wlock(eg);
 	if(waserror()) {
 		wunlock(eg);
@@ -161,22 +160,23 @@
 	if(envlookup(eg, name, -1) != nil)
 		error(Eexist);
 
-	e = smalloc(sizeof(Evalue));
-	e->name = smalloc(strlen(name)+1);
-	strcpy(e->name, name);
-
 	if(eg->nent == eg->ment){
-		eg->ment += 32;
-		ent = smalloc(sizeof(eg->ent[0])*eg->ment);
-		if(eg->nent)
-			memmove(ent, eg->ent, sizeof(eg->ent[0])*eg->nent);
-		free(eg->ent);
-		eg->ent = ent;
+		Evalue *tmp;
+
+		eg->ment += DELTAENV;
+		if((tmp = realloc(eg->ent, sizeof(eg->ent[0])*eg->ment)) == nil){
+			eg->ment -= DELTAENV;
+			error(Enomem);
+		}
+		eg->ent = tmp;
 	}
-	e->qid.path = ++eg->path;
-	e->qid.vers = 0;
 	eg->vers++;
-	eg->ent[eg->nent++] = e;
+	e = &eg->ent[eg->nent++];
+	e->value = nil;
+	e->len = 0;
+	e->name = smalloc(strlen(name)+1);
+	strcpy(e->name, name);
+	mkqid(&e->qid, ++eg->path, 0, QTFILE);
 	c->qid = e->qid;
 
 	wunlock(eg);
@@ -191,9 +191,8 @@
 static void
 envremove(Chan *c)
 {
-	int i;
 	Egrp *eg;
-	Evalue *e;
+	Evalue *e, *ee;
 
 	if(c->qid.type & QTDIR || !envwriteable(c))
 		error(Eperm);
@@ -200,22 +199,20 @@
 
 	eg = envgrp(c);
 	wlock(eg);
-	e = nil;
-	for(i=0; i<eg->nent; i++){
-		if(eg->ent[i]->qid.path == c->qid.path){
-			e = eg->ent[i];
+	e = eg->ent;
+	for(ee = e + eg->nent; e < ee; e++){
+		if(e->qid.path == c->qid.path){
+			free(e->name);
+			free(e->value);
+			*e = ee[-1];
 			eg->nent--;
-			eg->ent[i] = eg->ent[eg->nent];
 			eg->vers++;
-			break;
+			wunlock(eg);
+			return;
 		}
 	}
 	wunlock(eg);
-	if(e == nil)
-		error(Enonexist);
-	free(e->name);
-	free(e->value);
-	free(e);
+	error(Enonexist);
 }
 
 static void
@@ -242,12 +239,14 @@
 
 	eg = envgrp(c);
 	rlock(eg);
-	e = envlookup(eg, nil, c->qid.path);
-	if(e == nil) {
+	if(waserror()){
 		runlock(eg);
-		error(Enonexist);
+		nexterror();
 	}
 
+	e = envlookup(eg, nil, c->qid.path);
+	if(e == nil)
+		error(Enonexist);
 	if(offset >= e->len || e->value == nil)
 		n = 0;
 	else if(offset + n > e->len)
@@ -256,7 +255,9 @@
 		n = 0;
 	else
 		memmove(a, e->value+offset, n);
+
 	runlock(eg);
+	poperror();
 	return n;
 }
 
@@ -276,23 +277,21 @@
 
 	eg = envgrp(c);
 	wlock(eg);
-	e = envlookup(eg, nil, c->qid.path);
-	if(e == nil) {
+	if(waserror()){
 		wunlock(eg);
-		error(Enonexist);
+		nexterror();
 	}
 
+	e = envlookup(eg, nil, c->qid.path);
+	if(e == nil)
+		error(Enonexist);
+
 	len = offset+n;
 	if(len > e->len) {
-		s = malloc(len);
-		if(s == nil){
-			wunlock(eg);
+		s = realloc(e->value, len);
+		if(s == nil)
 			error(Enomem);
-		}
-		if(e->value != nil){
-			memmove(s, e->value, e->len);
-			free(e->value);
-		}
+		memset(s+offset, 0, n);
 		e->value = s;
 		e->len = len;
 	}
@@ -299,7 +298,9 @@
 	memmove(e->value+offset, a, n);
 	e->qid.vers++;
 	eg->vers++;
+
 	wunlock(eg);
+	poperror();
 	return n;
 }
 
@@ -327,15 +328,14 @@
 void
 envcpy(Egrp *to, Egrp *from)
 {
-	int i;
-	Evalue *ne, *e;
+	Evalue *e, *ee, *ne;
 
 	rlock(from);
-	to->ment = (from->nent+31)&~31;
+	to->ment = ROUND(from->nent, DELTAENV);
 	to->ent = smalloc(to->ment*sizeof(to->ent[0]));
-	for(i=0; i<from->nent; i++){
-		e = from->ent[i];
-		ne = smalloc(sizeof(Evalue));
+	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){
@@ -343,8 +343,7 @@
 			memmove(ne->value, e->value, e->len);
 			ne->len = e->len;
 		}
-		ne->qid.path = ++to->path;
-		to->ent[i] = ne;
+		mkqid(&ne->qid, ++to->path, 0, QTFILE);
 	}
 	to->nent = from->nent;
 	runlock(from);
@@ -353,15 +352,13 @@
 void
 closeegrp(Egrp *eg)
 {
-	int i;
-	Evalue *e;
+	Evalue *e, *ee;
 
 	if(decref(eg) == 0){
-		for(i=0; i<eg->nent; i++){
-			e = eg->ent[i];
+		e = eg->ent;
+		for(ee = e + eg->nent; e < ee; e++){
 			free(e->name);
 			free(e->value);
-			free(e);
 		}
 		free(eg->ent);
 		free(eg);
@@ -406,9 +403,9 @@
 getconfenv(void)
 {
 	Egrp *eg = &confegrp;
-	Evalue *e;
+	Evalue *e, *ee;
 	char *p, *q;
-	int i, n;
+	int n;
 
 	rlock(eg);
 	if(waserror()) {
@@ -418,16 +415,16 @@
 	
 	/* determine size */
 	n = 0;
-	for(i=0; i<eg->nent; i++){
-		e = eg->ent[i];
+	e = eg->ent;
+	for(ee = e+eg->nent; e<ee; e++)
 		n += strlen(e->name) + e->len + 2;
-	}
+
 	p = malloc(n + 1);
 	if(p == nil)
 		error(Enomem);
 	q = p;
-	for(i=0; i<eg->nent; i++){
-		e = eg->ent[i];
+	e = eg->ent;
+	for(ee = e + eg->nent; e < ee; e++){
 		strcpy(q, e->name);
 		q += strlen(q) + 1;
 		memmove(q, e->value, e->len);
@@ -437,7 +434,7 @@
 	}
 	*q = '\0';
 	
-	poperror();
 	runlock(eg);
+	poperror();
 	return p;
 }
--- a/sys/src/9/port/portdat.h
+++ b/sys/src/9/port/portdat.h
@@ -495,7 +495,7 @@
 {
 	Ref;
 	RWlock;
-	Evalue	**ent;
+	Evalue	*ent;
 	int	nent;
 	int	ment;
 	ulong	path;	/* qid.path of next Evalue to be allocated */
@@ -507,7 +507,6 @@
 	char	*name;
 	char	*value;
 	int	len;
-	Evalue	*link;
 	Qid	qid;
 };