aboutsummaryrefslogtreecommitdiff
path: root/src/libventi
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-02-13 19:26:14 +0000
committerrsc <devnull@localhost>2005-02-13 19:26:14 +0000
commit0faf0f0baa92349a203a419f8e1db76104e42313 (patch)
tree1fd281fb6bec5526f62f5298bf6f85f13b2816c9 /src/libventi
parent06f4d9201a6552b3c832fccc72ff0627986977e5 (diff)
downloadplan9port-0faf0f0baa92349a203a419f8e1db76104e42313.tar.gz
plan9port-0faf0f0baa92349a203a419f8e1db76104e42313.tar.bz2
plan9port-0faf0f0baa92349a203a419f8e1db76104e42313.zip
add log
Diffstat (limited to 'src/libventi')
-rw-r--r--src/libventi/log.c188
-rw-r--r--src/libventi/mkfile1
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\