tventi: reduce locking contention in buildindex - plan9port - [fork] Plan 9 fro… | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit ac5a97e6b3b136c1ab669ae19a813a81cce673eb | |
parent cd87898f5db211b3485d8cad2c00ea356ca96361 | |
Author: Russ Cox <[email protected]> | |
Date: Thu, 3 Jul 2008 22:44:24 -0400 | |
venti: reduce locking contention in buildindex | |
Diffstat: | |
M src/cmd/venti/srv/bloom.c | 16 ++++++++++++++++ | |
M src/cmd/venti/srv/buildindex.c | 70 +++++++++++++++++++++++++----… | |
M src/cmd/venti/srv/fns.h | 1 + | |
3 files changed, 74 insertions(+), 13 deletions(-) | |
--- | |
diff --git a/src/cmd/venti/srv/bloom.c b/src/cmd/venti/srv/bloom.c | |
t@@ -229,6 +229,22 @@ markbloomfilter(Bloom *b, u8int *score) | |
runlock(&b->lk); | |
} | |
+void | |
+markbloomfiltern(Bloom *b, u8int score[][20], int n) | |
+{ | |
+ int i; | |
+ | |
+ if(b == nil || b->data == nil) | |
+ return; | |
+ | |
+ rlock(&b->lk); | |
+ qlock(&b->mod); | |
+ for(i=0; i<n; i++) | |
+ _markbloomfilter(b, score[i]); | |
+ qunlock(&b->mod); | |
+ runlock(&b->lk); | |
+} | |
+ | |
static void | |
bloomwriteproc(void *v) | |
{ | |
diff --git a/src/cmd/venti/srv/buildindex.c b/src/cmd/venti/srv/buildindex.c | |
t@@ -11,6 +11,20 @@ enum | |
MaxBufSize = 4*1024*1024, | |
}; | |
+typedef struct IEntryBuf IEntryBuf; | |
+struct IEntryBuf | |
+{ | |
+ IEntry ie[100]; | |
+ int nie; | |
+}; | |
+ | |
+typedef struct ScoreBuf ScoreBuf; | |
+struct ScoreBuf | |
+{ | |
+ uchar score[100][VtScoreSize]; | |
+ int nscore; | |
+}; | |
+ | |
int dumb; | |
int errors; | |
char **isect; | |
t@@ -117,10 +131,10 @@ threadmain(int argc, char *argv[]) | |
/* start index procs */ | |
fprint(2, "%T read index\n"); | |
- isectdonechan = chancreate(sizeof(void*), 0); | |
+ isectdonechan = chancreate(sizeof(void*), 1); | |
for(i=0; i<ix->nsects; i++){ | |
if(shouldprocess(ix->sects[i])){ | |
- ix->sects[i]->writechan = chancreate(sizeof(IEntry), 0… | |
+ ix->sects[i]->writechan = chancreate(sizeof(IEntryBuf)… | |
vtproc(isectproc, ix->sects[i]); | |
} | |
} | |
t@@ -208,12 +222,17 @@ arenapartproc(void *v) | |
ClumpInfo *ci, *cis; | |
IEntry ie; | |
Part *p; | |
+ IEntryBuf *buf, *b; | |
+ uchar *score; | |
+ ScoreBuf sb; | |
p = v; | |
threadsetname("arenaproc %s", p->name); | |
+ buf = MKNZ(IEntryBuf, ix->nsects); | |
nskip = 0; | |
tot = 0; | |
+ sb.nscore = 0; | |
cis = MKN(ClumpInfo, ClumpChunks); | |
for(i=0; i<ix->narenas; i++){ | |
a = ix->arenas[i]; | |
t@@ -252,10 +271,23 @@ arenapartproc(void *v) | |
tot++; | |
x = indexsect(ix, ie.score); | |
assert(0 <= x && x < ix->nsects); | |
- if(ix->sects[x]->writechan) | |
- send(ix->sects[x]->writechan, … | |
- if(ix->bloom) | |
- markbloomfilter(ix->bloom, ie.… | |
+ if(ix->sects[x]->writechan) { | |
+ b = &buf[x]; | |
+ b->ie[b->nie] = ie; | |
+ b->nie++; | |
+ if(b->nie == nelem(b->ie)) { | |
+ send(ix->sects[x]->wri… | |
+ b->nie = 0; | |
+ } | |
+ } | |
+ if(ix->bloom) { | |
+ score = sb.score[sb.nscore++]; | |
+ scorecp(score, ie.score); | |
+ if(sb.nscore == nelem(sb.score… | |
+ markbloomfiltern(ix->b… | |
+ sb.nscore = 0; | |
+ } | |
+ } | |
} | |
} | |
} | |
t@@ -264,6 +296,14 @@ arenapartproc(void *v) | |
} | |
add(&arenaentries, tot); | |
add(&skipentries, nskip); | |
+ | |
+ for(i=0; i<ix->nsects; i++) | |
+ if(ix->sects[i]->writechan && buf[i].nie > 0) | |
+ send(ix->sects[i]->writechan, &buf[i]); | |
+ free(buf); | |
+ free(cis); | |
+ if(ix->bloom && sb.nscore > 0) | |
+ markbloomfiltern(ix->bloom, sb.score, sb.nscore); | |
sendp(arenadonechan, p); | |
} | |
t@@ -743,6 +783,7 @@ isectproc(void *v) | |
uchar *data, *p; | |
Buf *buf; | |
IEntry ie; | |
+ IEntryBuf ieb; | |
IPool *ipool; | |
ISect *is; | |
Minibuf *mbuf, *mb; | |
t@@ -837,14 +878,17 @@ isectproc(void *v) | |
assert(p == data+nbuf*bufsize); | |
n = 0; | |
- while(recv(is->writechan, &ie) == 1){ | |
- if(ie.ia.addr == 0) | |
+ while(recv(is->writechan, &ieb) == 1){ | |
+ if(ieb.nie == 0) | |
break; | |
- buck = score2bucket(is, ie.score); | |
- i = buck/bufbuckets; | |
- assert(i < nbuf); | |
- bwrite(&buf[i], &ie); | |
- n++; | |
+ for(j=0; j<ieb.nie; j++){ | |
+ ie = ieb.ie[j]; | |
+ buck = score2bucket(is, ie.score); | |
+ i = buck/bufbuckets; | |
+ assert(i < nbuf); | |
+ bwrite(&buf[i], &ie); | |
+ n++; | |
+ } | |
} | |
add(&indexentries, n); | |
diff --git a/src/cmd/venti/srv/fns.h b/src/cmd/venti/srv/fns.h | |
t@@ -105,6 +105,7 @@ Lump *lookuplump(u8int *score, int type); | |
int lookupscore(u8int *score, int type, IAddr *ia); | |
int maparenas(AMap *am, Arena **arenas, int n, char *what); | |
void markbloomfilter(Bloom*, u8int*); | |
+void markbloomfiltern(Bloom*, u8int[][20], int); | |
uint msec(void); | |
int namecmp(char *s, char *t); | |
void namecp(char *dst, char *src); |