diff options
author | rsc <devnull@localhost> | 2005-02-13 19:26:14 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2005-02-13 19:26:14 +0000 |
commit | 0faf0f0baa92349a203a419f8e1db76104e42313 (patch) | |
tree | 1fd281fb6bec5526f62f5298bf6f85f13b2816c9 /src/libventi | |
parent | 06f4d9201a6552b3c832fccc72ff0627986977e5 (diff) | |
download | plan9port-0faf0f0baa92349a203a419f8e1db76104e42313.tar.gz plan9port-0faf0f0baa92349a203a419f8e1db76104e42313.tar.bz2 plan9port-0faf0f0baa92349a203a419f8e1db76104e42313.zip |
add log
Diffstat (limited to 'src/libventi')
-rw-r--r-- | src/libventi/log.c | 188 | ||||
-rw-r--r-- | src/libventi/mkfile | 1 |
2 files changed, 189 insertions, 0 deletions
diff --git a/src/libventi/log.c b/src/libventi/log.c new file mode 100644 index 00000000..fdf6ceee --- /dev/null +++ b/src/libventi/log.c @@ -0,0 +1,188 @@ +#include <u.h> +#include <libc.h> +#include <venti.h> + +#define log not_the_log_library_call + +enum +{ /* defaults */ + LogChunkSize = 8192, + LogSize = 65536, +}; + +static struct { + QLock lk; + VtLog *hash[1024]; +} vl; + +static uint +hash(char *s) +{ + uint h; + uchar *p; + + h = 0; + for(p=(uchar*)s; *p; p++) + h = h*37 + *p; + return h; +} + +VtLog* +vtlogopen(char *name, uint size) +{ + uint h; + int i, nc; + char *p; + VtLog *l, *last; + + h = hash(name)%nelem(vl.hash); + qlock(&vl.lk); + last = nil; + for(l=vl.hash[h]; l; last=l, l=l->next) + if(strcmp(l->name, name) == 0){ + if(last){ /* move to front */ + last->next = l->next; + l->next = vl.hash[h]; + vl.hash[h] = l; + } + l->ref++; + qunlock(&vl.lk); + return l; + } + + if(size == 0){ + qunlock(&vl.lk); + return nil; + } + + /* allocate */ + nc = (size+LogChunkSize-1)/LogChunkSize; + l = vtmalloc(sizeof *l + nc*(sizeof(*l->chunk)+LogChunkSize) + strlen(name)+1); + memset(l, 0, sizeof *l); + l->chunk = (VtLogChunk*)(l+1); + l->nchunk = nc; + l->w = l->chunk; + p = (char*)(l->chunk+nc); + for(i=0; i<nc; i++){ + l->chunk[i].p = p; + p += LogChunkSize; + l->chunk[i].ep = p; + } + strcpy(p, name); + l->name = p; + + /* insert */ + l->next = vl.hash[h]; + vl.hash[h] = l; + + l->ref++; + qunlock(&vl.lk); + return l; +} + +void +vtlogclose(VtLog *l) +{ + if(l == nil) + return; + + qlock(&vl.lk); + if(--l->ref == 0) + free(l); + else + assert(l->ref > 0); + qunlock(&vl.lk); +} + +void +vtlogremove(char *name) +{ + uint h; + VtLog *last, *l; + + h = hash(name)%nelem(vl.hash); + qlock(&vl.lk); + last = nil; + for(l=vl.hash[h]; l; last=l, l=l->next) + if(strcmp(l->name, name) == 0){ + if(last) + last->next = l->next; + else + vl.hash[h] = l->next; + qunlock(&vl.lk); + vtlogclose(l); + return; + } + qunlock(&vl.lk); +} + +void +vtlogvprint(VtLog *l, char *fmt, va_list arg) +{ + int n; + char *p; + VtLogChunk *c; + + if(l == nil) + return; + + qlock(&l->lk); + c = l->w; + n = c->ep - c->wp; + if(n < 512){ + c++; + if(c == l->chunk+l->nchunk) + c = l->chunk; + c->wp = c->p; + l->w = c; + } + p = vseprint(c->wp, c->ep, fmt, arg); + if(p) + c->wp = p; + qunlock(&l->lk); +} + +void +vtlogprint(VtLog *l, char *fmt, ...) +{ + va_list arg; + + if(l == nil) + return; + + va_start(arg, fmt); + vtlogvprint(l, fmt, arg); + va_end(arg); +} + +void +vtlog(char *name, char *fmt, ...) +{ + VtLog *l; + va_list arg; + + l = vtlogopen(name, LogSize); + va_start(arg, fmt); + vtlogvprint(l, fmt, arg); + va_end(arg); + vtlogclose(l); +} + +void +vtlogdump(int fd, VtLog *l) +{ + int i; + VtLogChunk *c; + + if(l == nil) + return; + + c = l->w; + for(i=0; i<l->nchunk; i++){ + if(++c == l->chunk+l->nchunk) + c = l->chunk; + write(fd, c->p, c->wp-c->p); + } + vtlogclose(l); +} + diff --git a/src/libventi/mkfile b/src/libventi/mkfile index 517e355f..2e7d04b3 100644 --- a/src/libventi/mkfile +++ b/src/libventi/mkfile @@ -14,6 +14,7 @@ OFILES=\ fcallfmt.$O\ file.$O\ hangup.$O\ + log.$O\ mem.$O\ packet.$O\ parsescore.$O\ |