1 0faf0f0b 2005-02-13 devnull #include <u.h>
2 0faf0f0b 2005-02-13 devnull #include <libc.h>
3 0faf0f0b 2005-02-13 devnull #include <venti.h>
5 5ddc97fc 2005-02-14 devnull int ventilogging;
6 0faf0f0b 2005-02-13 devnull #define log not_the_log_library_call
8 5ddc97fc 2005-02-14 devnull static char Eremoved[] = "[removed]";
11 0faf0f0b 2005-02-13 devnull { /* defaults */
12 0faf0f0b 2005-02-13 devnull LogChunkSize = 8192,
13 0faf0f0b 2005-02-13 devnull LogSize = 65536,
16 0faf0f0b 2005-02-13 devnull static struct {
17 0faf0f0b 2005-02-13 devnull QLock lk;
18 0faf0f0b 2005-02-13 devnull VtLog *hash[1024];
21 0faf0f0b 2005-02-13 devnull static uint
22 0faf0f0b 2005-02-13 devnull hash(char *s)
25 0faf0f0b 2005-02-13 devnull uchar *p;
28 0faf0f0b 2005-02-13 devnull for(p=(uchar*)s; *p; p++)
29 0faf0f0b 2005-02-13 devnull h = h*37 + *p;
30 0faf0f0b 2005-02-13 devnull return h;
34 52006c82 2005-05-12 devnull vtlognames(int *pn)
36 52006c82 2005-05-12 devnull int i, nname, size;
37 52006c82 2005-05-12 devnull VtLog *l;
38 52006c82 2005-05-12 devnull char **s, *a, *e;
40 52006c82 2005-05-12 devnull qlock(&vl.lk);
41 52006c82 2005-05-12 devnull size = 0;
42 52006c82 2005-05-12 devnull nname = 0;
43 52006c82 2005-05-12 devnull for(i=0; i<nelem(vl.hash); i++)
44 52006c82 2005-05-12 devnull for(l=vl.hash[i]; l; l=l->next){
46 52006c82 2005-05-12 devnull size += strlen(l->name)+1;
49 52006c82 2005-05-12 devnull s = vtmalloc(nname*sizeof(char*)+size);
50 52006c82 2005-05-12 devnull a = (char*)(s+nname);
51 52006c82 2005-05-12 devnull e = (char*)s+nname*sizeof(char*)+size;
53 52006c82 2005-05-12 devnull size = 0;
54 52006c82 2005-05-12 devnull nname = 0;
55 52006c82 2005-05-12 devnull for(i=0; i<nelem(vl.hash); i++)
56 52006c82 2005-05-12 devnull for(l=vl.hash[i]; l; l=l->next){
57 52006c82 2005-05-12 devnull strcpy(a, l->name);
58 52006c82 2005-05-12 devnull s[nname++] = a;
59 52006c82 2005-05-12 devnull a += strlen(a)+1;
61 52006c82 2005-05-12 devnull *pn = nname;
62 52006c82 2005-05-12 devnull assert(a == e);
63 52006c82 2005-05-12 devnull qunlock(&vl.lk);
65 52006c82 2005-05-12 devnull return s;
69 0faf0f0b 2005-02-13 devnull vtlogopen(char *name, uint size)
72 0faf0f0b 2005-02-13 devnull int i, nc;
74 0faf0f0b 2005-02-13 devnull VtLog *l, *last;
76 5ddc97fc 2005-02-14 devnull if(!ventilogging)
77 5ddc97fc 2005-02-14 devnull return nil;
79 0faf0f0b 2005-02-13 devnull h = hash(name)%nelem(vl.hash);
80 0faf0f0b 2005-02-13 devnull qlock(&vl.lk);
81 0faf0f0b 2005-02-13 devnull last = nil;
82 0faf0f0b 2005-02-13 devnull for(l=vl.hash[h]; l; last=l, l=l->next)
83 0faf0f0b 2005-02-13 devnull if(strcmp(l->name, name) == 0){
84 0faf0f0b 2005-02-13 devnull if(last){ /* move to front */
85 0faf0f0b 2005-02-13 devnull last->next = l->next;
86 0faf0f0b 2005-02-13 devnull l->next = vl.hash[h];
87 0faf0f0b 2005-02-13 devnull vl.hash[h] = l;
89 0faf0f0b 2005-02-13 devnull l->ref++;
90 0faf0f0b 2005-02-13 devnull qunlock(&vl.lk);
91 0faf0f0b 2005-02-13 devnull return l;
94 0faf0f0b 2005-02-13 devnull if(size == 0){
95 0faf0f0b 2005-02-13 devnull qunlock(&vl.lk);
96 0faf0f0b 2005-02-13 devnull return nil;
99 0faf0f0b 2005-02-13 devnull /* allocate */
100 0faf0f0b 2005-02-13 devnull nc = (size+LogChunkSize-1)/LogChunkSize;
101 0faf0f0b 2005-02-13 devnull l = vtmalloc(sizeof *l + nc*(sizeof(*l->chunk)+LogChunkSize) + strlen(name)+1);
102 0faf0f0b 2005-02-13 devnull memset(l, 0, sizeof *l);
103 0faf0f0b 2005-02-13 devnull l->chunk = (VtLogChunk*)(l+1);
104 0faf0f0b 2005-02-13 devnull l->nchunk = nc;
105 0faf0f0b 2005-02-13 devnull l->w = l->chunk;
106 0faf0f0b 2005-02-13 devnull p = (char*)(l->chunk+nc);
107 0faf0f0b 2005-02-13 devnull for(i=0; i<nc; i++){
108 0faf0f0b 2005-02-13 devnull l->chunk[i].p = p;
109 5ddc97fc 2005-02-14 devnull l->chunk[i].wp = p;
110 0faf0f0b 2005-02-13 devnull p += LogChunkSize;
111 0faf0f0b 2005-02-13 devnull l->chunk[i].ep = p;
113 0faf0f0b 2005-02-13 devnull strcpy(p, name);
114 0faf0f0b 2005-02-13 devnull l->name = p;
116 0faf0f0b 2005-02-13 devnull /* insert */
117 0faf0f0b 2005-02-13 devnull l->next = vl.hash[h];
118 0faf0f0b 2005-02-13 devnull vl.hash[h] = l;
119 5ddc97fc 2005-02-14 devnull l->ref++;
121 0faf0f0b 2005-02-13 devnull l->ref++;
122 0faf0f0b 2005-02-13 devnull qunlock(&vl.lk);
123 0faf0f0b 2005-02-13 devnull return l;
127 0faf0f0b 2005-02-13 devnull vtlogclose(VtLog *l)
129 0faf0f0b 2005-02-13 devnull if(l == nil)
132 0faf0f0b 2005-02-13 devnull qlock(&vl.lk);
133 5ddc97fc 2005-02-14 devnull if(--l->ref == 0){
134 5ddc97fc 2005-02-14 devnull /* must not be in hash table */
135 5ddc97fc 2005-02-14 devnull assert(l->name == Eremoved);
136 0faf0f0b 2005-02-13 devnull free(l);
138 0faf0f0b 2005-02-13 devnull assert(l->ref > 0);
139 0faf0f0b 2005-02-13 devnull qunlock(&vl.lk);
143 0faf0f0b 2005-02-13 devnull vtlogremove(char *name)
146 0faf0f0b 2005-02-13 devnull VtLog *last, *l;
148 0faf0f0b 2005-02-13 devnull h = hash(name)%nelem(vl.hash);
149 0faf0f0b 2005-02-13 devnull qlock(&vl.lk);
150 0faf0f0b 2005-02-13 devnull last = nil;
151 0faf0f0b 2005-02-13 devnull for(l=vl.hash[h]; l; last=l, l=l->next)
152 0faf0f0b 2005-02-13 devnull if(strcmp(l->name, name) == 0){
153 0faf0f0b 2005-02-13 devnull if(last)
154 0faf0f0b 2005-02-13 devnull last->next = l->next;
156 0faf0f0b 2005-02-13 devnull vl.hash[h] = l->next;
157 5ddc97fc 2005-02-14 devnull l->name = Eremoved;
158 5ddc97fc 2005-02-14 devnull l->next = nil;
159 0faf0f0b 2005-02-13 devnull qunlock(&vl.lk);
160 0faf0f0b 2005-02-13 devnull vtlogclose(l);
163 0faf0f0b 2005-02-13 devnull qunlock(&vl.lk);
166 5ddc97fc 2005-02-14 devnull static int
167 5ddc97fc 2005-02-14 devnull timefmt(Fmt *fmt)
169 5ddc97fc 2005-02-14 devnull static uvlong t0;
170 5ddc97fc 2005-02-14 devnull uvlong t;
172 5ddc97fc 2005-02-14 devnull if(t0 == 0)
173 5ddc97fc 2005-02-14 devnull t0 = nsec();
174 5ddc97fc 2005-02-14 devnull t = nsec()-t0;
175 5ddc97fc 2005-02-14 devnull return fmtprint(fmt, "T+%d.%04d", (uint)(t/1000000000), (uint)(t%1000000000)/100000);
179 0faf0f0b 2005-02-13 devnull vtlogvprint(VtLog *l, char *fmt, va_list arg)
182 0faf0f0b 2005-02-13 devnull char *p;
183 0faf0f0b 2005-02-13 devnull VtLogChunk *c;
184 5ddc97fc 2005-02-14 devnull static int first = 1;
186 0faf0f0b 2005-02-13 devnull if(l == nil)
189 5ddc97fc 2005-02-14 devnull if(first){
190 5ddc97fc 2005-02-14 devnull fmtinstall('T', timefmt);
191 5ddc97fc 2005-02-14 devnull first = 0;
195 0faf0f0b 2005-02-13 devnull qlock(&l->lk);
196 0faf0f0b 2005-02-13 devnull c = l->w;
197 0faf0f0b 2005-02-13 devnull n = c->ep - c->wp;
198 0faf0f0b 2005-02-13 devnull if(n < 512){
200 0faf0f0b 2005-02-13 devnull if(c == l->chunk+l->nchunk)
201 0faf0f0b 2005-02-13 devnull c = l->chunk;
202 0faf0f0b 2005-02-13 devnull c->wp = c->p;
203 0faf0f0b 2005-02-13 devnull l->w = c;
205 0faf0f0b 2005-02-13 devnull p = vseprint(c->wp, c->ep, fmt, arg);
207 0faf0f0b 2005-02-13 devnull c->wp = p;
208 0faf0f0b 2005-02-13 devnull qunlock(&l->lk);
212 0faf0f0b 2005-02-13 devnull vtlogprint(VtLog *l, char *fmt, ...)
214 0faf0f0b 2005-02-13 devnull va_list arg;
216 0faf0f0b 2005-02-13 devnull if(l == nil)
219 0faf0f0b 2005-02-13 devnull va_start(arg, fmt);
220 0faf0f0b 2005-02-13 devnull vtlogvprint(l, fmt, arg);
221 0faf0f0b 2005-02-13 devnull va_end(arg);
225 0faf0f0b 2005-02-13 devnull vtlog(char *name, char *fmt, ...)
227 0faf0f0b 2005-02-13 devnull VtLog *l;
228 0faf0f0b 2005-02-13 devnull va_list arg;
230 0faf0f0b 2005-02-13 devnull l = vtlogopen(name, LogSize);
231 5ddc97fc 2005-02-14 devnull if(l == nil)
233 0faf0f0b 2005-02-13 devnull va_start(arg, fmt);
234 0faf0f0b 2005-02-13 devnull vtlogvprint(l, fmt, arg);
235 0faf0f0b 2005-02-13 devnull va_end(arg);
236 0faf0f0b 2005-02-13 devnull vtlogclose(l);
240 0faf0f0b 2005-02-13 devnull vtlogdump(int fd, VtLog *l)
243 0faf0f0b 2005-02-13 devnull VtLogChunk *c;
245 0faf0f0b 2005-02-13 devnull if(l == nil)
248 0faf0f0b 2005-02-13 devnull c = l->w;
249 0faf0f0b 2005-02-13 devnull for(i=0; i<l->nchunk; i++){
250 0faf0f0b 2005-02-13 devnull if(++c == l->chunk+l->nchunk)
251 0faf0f0b 2005-02-13 devnull c = l->chunk;
252 0faf0f0b 2005-02-13 devnull write(fd, c->p, c->wp-c->p);