Commit Diff


commit - 06f4d9201a6552b3c832fccc72ff0627986977e5
commit + 0faf0f0baa92349a203a419f8e1db76104e42313
blob - /dev/null
blob + fdf6ceee093bb38dc411619cf20f7fcf834714c5 (mode 644)
--- /dev/null
+++ 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);
+}
+
blob - 517e355f3584df05a2a6deb0bf3b0c4fe1a179a8
blob + 2e7d04b3d63943ca894816ffd9dd2481df743da2
--- src/libventi/mkfile
+++ src/libventi/mkfile
@@ -14,6 +14,7 @@ OFILES=\
 	fcallfmt.$O\
 	file.$O\
 	hangup.$O\
+	log.$O\
 	mem.$O\
 	packet.$O\
 	parsescore.$O\