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.
This commit is contained in:
parent
29a53a52fd
commit
37e4ce0ea7
2 changed files with 70 additions and 74 deletions
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
DELTAENV = 32,
|
||||||
Maxenvsize = 16300,
|
Maxenvsize = 16300,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,12 +19,12 @@ static Egrp confegrp; /* global environment group containing the kernel configur
|
||||||
static Evalue*
|
static Evalue*
|
||||||
envlookup(Egrp *eg, char *name, ulong qidpath)
|
envlookup(Egrp *eg, char *name, ulong qidpath)
|
||||||
{
|
{
|
||||||
Evalue *e;
|
Evalue *e, *ee;
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i=0; i<eg->nent; i++){
|
e = eg->ent;
|
||||||
e = eg->ent[i];
|
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))
|
if(e->qid.path == qidpath
|
||||||
|
|| (name != nil && name[0] == e->name[0] && strcmp(e->name, name) == 0))
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
|
@ -42,12 +43,12 @@ envgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp)
|
||||||
|
|
||||||
eg = envgrp(c);
|
eg = envgrp(c);
|
||||||
rlock(eg);
|
rlock(eg);
|
||||||
e = nil;
|
|
||||||
if(name != nil)
|
if(name != nil)
|
||||||
e = envlookup(eg, name, -1);
|
e = envlookup(eg, name, -1);
|
||||||
else if(s < eg->nent)
|
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))) {
|
if(e == nil || name != nil && (strlen(e->name) >= sizeof(up->genbuf))) {
|
||||||
runlock(eg);
|
runlock(eg);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -141,7 +142,6 @@ envcreate(Chan *c, char *name, int omode, ulong)
|
||||||
{
|
{
|
||||||
Egrp *eg;
|
Egrp *eg;
|
||||||
Evalue *e;
|
Evalue *e;
|
||||||
Evalue **ent;
|
|
||||||
|
|
||||||
if(c->qid.type != QTDIR || !envwriteable(c))
|
if(c->qid.type != QTDIR || !envwriteable(c))
|
||||||
error(Eperm);
|
error(Eperm);
|
||||||
|
@ -151,7 +151,6 @@ envcreate(Chan *c, char *name, int omode, ulong)
|
||||||
|
|
||||||
omode = openmode(omode);
|
omode = openmode(omode);
|
||||||
eg = envgrp(c);
|
eg = envgrp(c);
|
||||||
|
|
||||||
wlock(eg);
|
wlock(eg);
|
||||||
if(waserror()) {
|
if(waserror()) {
|
||||||
wunlock(eg);
|
wunlock(eg);
|
||||||
|
@ -161,22 +160,23 @@ envcreate(Chan *c, char *name, int omode, ulong)
|
||||||
if(envlookup(eg, name, -1) != nil)
|
if(envlookup(eg, name, -1) != nil)
|
||||||
error(Eexist);
|
error(Eexist);
|
||||||
|
|
||||||
e = smalloc(sizeof(Evalue));
|
if(eg->nent == eg->ment){
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
eg->vers++;
|
||||||
|
e = &eg->ent[eg->nent++];
|
||||||
|
e->value = nil;
|
||||||
|
e->len = 0;
|
||||||
e->name = smalloc(strlen(name)+1);
|
e->name = smalloc(strlen(name)+1);
|
||||||
strcpy(e->name, name);
|
strcpy(e->name, name);
|
||||||
|
mkqid(&e->qid, ++eg->path, 0, QTFILE);
|
||||||
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;
|
|
||||||
}
|
|
||||||
e->qid.path = ++eg->path;
|
|
||||||
e->qid.vers = 0;
|
|
||||||
eg->vers++;
|
|
||||||
eg->ent[eg->nent++] = e;
|
|
||||||
c->qid = e->qid;
|
c->qid = e->qid;
|
||||||
|
|
||||||
wunlock(eg);
|
wunlock(eg);
|
||||||
|
@ -191,31 +191,28 @@ envcreate(Chan *c, char *name, int omode, ulong)
|
||||||
static void
|
static void
|
||||||
envremove(Chan *c)
|
envremove(Chan *c)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
Egrp *eg;
|
Egrp *eg;
|
||||||
Evalue *e;
|
Evalue *e, *ee;
|
||||||
|
|
||||||
if(c->qid.type & QTDIR || !envwriteable(c))
|
if(c->qid.type & QTDIR || !envwriteable(c))
|
||||||
error(Eperm);
|
error(Eperm);
|
||||||
|
|
||||||
eg = envgrp(c);
|
eg = envgrp(c);
|
||||||
wlock(eg);
|
wlock(eg);
|
||||||
e = nil;
|
e = eg->ent;
|
||||||
for(i=0; i<eg->nent; i++){
|
for(ee = e + eg->nent; e < ee; e++){
|
||||||
if(eg->ent[i]->qid.path == c->qid.path){
|
if(e->qid.path == c->qid.path){
|
||||||
e = eg->ent[i];
|
free(e->name);
|
||||||
|
free(e->value);
|
||||||
|
*e = ee[-1];
|
||||||
eg->nent--;
|
eg->nent--;
|
||||||
eg->ent[i] = eg->ent[eg->nent];
|
|
||||||
eg->vers++;
|
eg->vers++;
|
||||||
break;
|
wunlock(eg);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wunlock(eg);
|
wunlock(eg);
|
||||||
if(e == nil)
|
error(Enonexist);
|
||||||
error(Enonexist);
|
|
||||||
free(e->name);
|
|
||||||
free(e->value);
|
|
||||||
free(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -242,12 +239,14 @@ envread(Chan *c, void *a, long n, vlong off)
|
||||||
|
|
||||||
eg = envgrp(c);
|
eg = envgrp(c);
|
||||||
rlock(eg);
|
rlock(eg);
|
||||||
e = envlookup(eg, nil, c->qid.path);
|
if(waserror()){
|
||||||
if(e == nil) {
|
|
||||||
runlock(eg);
|
runlock(eg);
|
||||||
error(Enonexist);
|
nexterror();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e = envlookup(eg, nil, c->qid.path);
|
||||||
|
if(e == nil)
|
||||||
|
error(Enonexist);
|
||||||
if(offset >= e->len || e->value == nil)
|
if(offset >= e->len || e->value == nil)
|
||||||
n = 0;
|
n = 0;
|
||||||
else if(offset + n > e->len)
|
else if(offset + n > e->len)
|
||||||
|
@ -256,7 +255,9 @@ envread(Chan *c, void *a, long n, vlong off)
|
||||||
n = 0;
|
n = 0;
|
||||||
else
|
else
|
||||||
memmove(a, e->value+offset, n);
|
memmove(a, e->value+offset, n);
|
||||||
|
|
||||||
runlock(eg);
|
runlock(eg);
|
||||||
|
poperror();
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,30 +277,30 @@ envwrite(Chan *c, void *a, long n, vlong off)
|
||||||
|
|
||||||
eg = envgrp(c);
|
eg = envgrp(c);
|
||||||
wlock(eg);
|
wlock(eg);
|
||||||
e = envlookup(eg, nil, c->qid.path);
|
if(waserror()){
|
||||||
if(e == nil) {
|
|
||||||
wunlock(eg);
|
wunlock(eg);
|
||||||
error(Enonexist);
|
nexterror();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e = envlookup(eg, nil, c->qid.path);
|
||||||
|
if(e == nil)
|
||||||
|
error(Enonexist);
|
||||||
|
|
||||||
len = offset+n;
|
len = offset+n;
|
||||||
if(len > e->len) {
|
if(len > e->len) {
|
||||||
s = malloc(len);
|
s = realloc(e->value, len);
|
||||||
if(s == nil){
|
if(s == nil)
|
||||||
wunlock(eg);
|
|
||||||
error(Enomem);
|
error(Enomem);
|
||||||
}
|
memset(s+offset, 0, n);
|
||||||
if(e->value != nil){
|
|
||||||
memmove(s, e->value, e->len);
|
|
||||||
free(e->value);
|
|
||||||
}
|
|
||||||
e->value = s;
|
e->value = s;
|
||||||
e->len = len;
|
e->len = len;
|
||||||
}
|
}
|
||||||
memmove(e->value+offset, a, n);
|
memmove(e->value+offset, a, n);
|
||||||
e->qid.vers++;
|
e->qid.vers++;
|
||||||
eg->vers++;
|
eg->vers++;
|
||||||
|
|
||||||
wunlock(eg);
|
wunlock(eg);
|
||||||
|
poperror();
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,15 +328,14 @@ Dev envdevtab = {
|
||||||
void
|
void
|
||||||
envcpy(Egrp *to, Egrp *from)
|
envcpy(Egrp *to, Egrp *from)
|
||||||
{
|
{
|
||||||
int i;
|
Evalue *e, *ee, *ne;
|
||||||
Evalue *ne, *e;
|
|
||||||
|
|
||||||
rlock(from);
|
rlock(from);
|
||||||
to->ment = (from->nent+31)&~31;
|
to->ment = ROUND(from->nent, DELTAENV);
|
||||||
to->ent = smalloc(to->ment*sizeof(to->ent[0]));
|
to->ent = smalloc(to->ment*sizeof(to->ent[0]));
|
||||||
for(i=0; i<from->nent; i++){
|
ne = to->ent;
|
||||||
e = from->ent[i];
|
e = from->ent;
|
||||||
ne = smalloc(sizeof(Evalue));
|
for(ee = e + from->nent; e < ee; e++, ne++){
|
||||||
ne->name = smalloc(strlen(e->name)+1);
|
ne->name = smalloc(strlen(e->name)+1);
|
||||||
strcpy(ne->name, e->name);
|
strcpy(ne->name, e->name);
|
||||||
if(e->value != nil){
|
if(e->value != nil){
|
||||||
|
@ -343,8 +343,7 @@ envcpy(Egrp *to, Egrp *from)
|
||||||
memmove(ne->value, e->value, e->len);
|
memmove(ne->value, e->value, e->len);
|
||||||
ne->len = e->len;
|
ne->len = e->len;
|
||||||
}
|
}
|
||||||
ne->qid.path = ++to->path;
|
mkqid(&ne->qid, ++to->path, 0, QTFILE);
|
||||||
to->ent[i] = ne;
|
|
||||||
}
|
}
|
||||||
to->nent = from->nent;
|
to->nent = from->nent;
|
||||||
runlock(from);
|
runlock(from);
|
||||||
|
@ -353,15 +352,13 @@ envcpy(Egrp *to, Egrp *from)
|
||||||
void
|
void
|
||||||
closeegrp(Egrp *eg)
|
closeegrp(Egrp *eg)
|
||||||
{
|
{
|
||||||
int i;
|
Evalue *e, *ee;
|
||||||
Evalue *e;
|
|
||||||
|
|
||||||
if(decref(eg) == 0){
|
if(decref(eg) == 0){
|
||||||
for(i=0; i<eg->nent; i++){
|
e = eg->ent;
|
||||||
e = eg->ent[i];
|
for(ee = e + eg->nent; e < ee; e++){
|
||||||
free(e->name);
|
free(e->name);
|
||||||
free(e->value);
|
free(e->value);
|
||||||
free(e);
|
|
||||||
}
|
}
|
||||||
free(eg->ent);
|
free(eg->ent);
|
||||||
free(eg);
|
free(eg);
|
||||||
|
@ -406,9 +403,9 @@ char *
|
||||||
getconfenv(void)
|
getconfenv(void)
|
||||||
{
|
{
|
||||||
Egrp *eg = &confegrp;
|
Egrp *eg = &confegrp;
|
||||||
Evalue *e;
|
Evalue *e, *ee;
|
||||||
char *p, *q;
|
char *p, *q;
|
||||||
int i, n;
|
int n;
|
||||||
|
|
||||||
rlock(eg);
|
rlock(eg);
|
||||||
if(waserror()) {
|
if(waserror()) {
|
||||||
|
@ -418,16 +415,16 @@ getconfenv(void)
|
||||||
|
|
||||||
/* determine size */
|
/* determine size */
|
||||||
n = 0;
|
n = 0;
|
||||||
for(i=0; i<eg->nent; i++){
|
e = eg->ent;
|
||||||
e = eg->ent[i];
|
for(ee = e+eg->nent; e<ee; e++)
|
||||||
n += strlen(e->name) + e->len + 2;
|
n += strlen(e->name) + e->len + 2;
|
||||||
}
|
|
||||||
p = malloc(n + 1);
|
p = malloc(n + 1);
|
||||||
if(p == nil)
|
if(p == nil)
|
||||||
error(Enomem);
|
error(Enomem);
|
||||||
q = p;
|
q = p;
|
||||||
for(i=0; i<eg->nent; i++){
|
e = eg->ent;
|
||||||
e = eg->ent[i];
|
for(ee = e + eg->nent; e < ee; e++){
|
||||||
strcpy(q, e->name);
|
strcpy(q, e->name);
|
||||||
q += strlen(q) + 1;
|
q += strlen(q) + 1;
|
||||||
memmove(q, e->value, e->len);
|
memmove(q, e->value, e->len);
|
||||||
|
@ -437,7 +434,7 @@ getconfenv(void)
|
||||||
}
|
}
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
|
|
||||||
poperror();
|
|
||||||
runlock(eg);
|
runlock(eg);
|
||||||
|
poperror();
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
|
@ -495,7 +495,7 @@ struct Egrp
|
||||||
{
|
{
|
||||||
Ref;
|
Ref;
|
||||||
RWlock;
|
RWlock;
|
||||||
Evalue **ent;
|
Evalue *ent;
|
||||||
int nent;
|
int nent;
|
||||||
int ment;
|
int ment;
|
||||||
ulong path; /* qid.path of next Evalue to be allocated */
|
ulong path; /* qid.path of next Evalue to be allocated */
|
||||||
|
@ -507,7 +507,6 @@ struct Evalue
|
||||||
char *name;
|
char *name;
|
||||||
char *value;
|
char *value;
|
||||||
int len;
|
int len;
|
||||||
Evalue *link;
|
|
||||||
Qid qid;
|
Qid qid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue