Blame


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>
4 0faf0f0b 2005-02-13 devnull
5 5ddc97fc 2005-02-14 devnull int ventilogging;
6 0faf0f0b 2005-02-13 devnull #define log not_the_log_library_call
7 0faf0f0b 2005-02-13 devnull
8 5ddc97fc 2005-02-14 devnull static char Eremoved[] = "[removed]";
9 5ddc97fc 2005-02-14 devnull
10 0faf0f0b 2005-02-13 devnull enum
11 0faf0f0b 2005-02-13 devnull { /* defaults */
12 0faf0f0b 2005-02-13 devnull LogChunkSize = 8192,
13 0faf0f0b 2005-02-13 devnull LogSize = 65536,
14 0faf0f0b 2005-02-13 devnull };
15 0faf0f0b 2005-02-13 devnull
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];
19 0faf0f0b 2005-02-13 devnull } vl;
20 0faf0f0b 2005-02-13 devnull
21 0faf0f0b 2005-02-13 devnull static uint
22 0faf0f0b 2005-02-13 devnull hash(char *s)
23 0faf0f0b 2005-02-13 devnull {
24 0faf0f0b 2005-02-13 devnull uint h;
25 0faf0f0b 2005-02-13 devnull uchar *p;
26 0faf0f0b 2005-02-13 devnull
27 0faf0f0b 2005-02-13 devnull h = 0;
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;
31 0faf0f0b 2005-02-13 devnull }
32 0faf0f0b 2005-02-13 devnull
33 0faf0f0b 2005-02-13 devnull VtLog*
34 0faf0f0b 2005-02-13 devnull vtlogopen(char *name, uint size)
35 0faf0f0b 2005-02-13 devnull {
36 0faf0f0b 2005-02-13 devnull uint h;
37 0faf0f0b 2005-02-13 devnull int i, nc;
38 0faf0f0b 2005-02-13 devnull char *p;
39 0faf0f0b 2005-02-13 devnull VtLog *l, *last;
40 0faf0f0b 2005-02-13 devnull
41 5ddc97fc 2005-02-14 devnull if(!ventilogging)
42 5ddc97fc 2005-02-14 devnull return nil;
43 5ddc97fc 2005-02-14 devnull
44 0faf0f0b 2005-02-13 devnull h = hash(name)%nelem(vl.hash);
45 0faf0f0b 2005-02-13 devnull qlock(&vl.lk);
46 0faf0f0b 2005-02-13 devnull last = nil;
47 0faf0f0b 2005-02-13 devnull for(l=vl.hash[h]; l; last=l, l=l->next)
48 0faf0f0b 2005-02-13 devnull if(strcmp(l->name, name) == 0){
49 0faf0f0b 2005-02-13 devnull if(last){ /* move to front */
50 0faf0f0b 2005-02-13 devnull last->next = l->next;
51 0faf0f0b 2005-02-13 devnull l->next = vl.hash[h];
52 0faf0f0b 2005-02-13 devnull vl.hash[h] = l;
53 0faf0f0b 2005-02-13 devnull }
54 0faf0f0b 2005-02-13 devnull l->ref++;
55 0faf0f0b 2005-02-13 devnull qunlock(&vl.lk);
56 0faf0f0b 2005-02-13 devnull return l;
57 0faf0f0b 2005-02-13 devnull }
58 0faf0f0b 2005-02-13 devnull
59 0faf0f0b 2005-02-13 devnull if(size == 0){
60 0faf0f0b 2005-02-13 devnull qunlock(&vl.lk);
61 0faf0f0b 2005-02-13 devnull return nil;
62 0faf0f0b 2005-02-13 devnull }
63 0faf0f0b 2005-02-13 devnull
64 0faf0f0b 2005-02-13 devnull /* allocate */
65 0faf0f0b 2005-02-13 devnull nc = (size+LogChunkSize-1)/LogChunkSize;
66 0faf0f0b 2005-02-13 devnull l = vtmalloc(sizeof *l + nc*(sizeof(*l->chunk)+LogChunkSize) + strlen(name)+1);
67 0faf0f0b 2005-02-13 devnull memset(l, 0, sizeof *l);
68 0faf0f0b 2005-02-13 devnull l->chunk = (VtLogChunk*)(l+1);
69 0faf0f0b 2005-02-13 devnull l->nchunk = nc;
70 0faf0f0b 2005-02-13 devnull l->w = l->chunk;
71 0faf0f0b 2005-02-13 devnull p = (char*)(l->chunk+nc);
72 0faf0f0b 2005-02-13 devnull for(i=0; i<nc; i++){
73 0faf0f0b 2005-02-13 devnull l->chunk[i].p = p;
74 5ddc97fc 2005-02-14 devnull l->chunk[i].wp = p;
75 0faf0f0b 2005-02-13 devnull p += LogChunkSize;
76 0faf0f0b 2005-02-13 devnull l->chunk[i].ep = p;
77 0faf0f0b 2005-02-13 devnull }
78 0faf0f0b 2005-02-13 devnull strcpy(p, name);
79 0faf0f0b 2005-02-13 devnull l->name = p;
80 0faf0f0b 2005-02-13 devnull
81 0faf0f0b 2005-02-13 devnull /* insert */
82 0faf0f0b 2005-02-13 devnull l->next = vl.hash[h];
83 0faf0f0b 2005-02-13 devnull vl.hash[h] = l;
84 5ddc97fc 2005-02-14 devnull l->ref++;
85 0faf0f0b 2005-02-13 devnull
86 0faf0f0b 2005-02-13 devnull l->ref++;
87 0faf0f0b 2005-02-13 devnull qunlock(&vl.lk);
88 0faf0f0b 2005-02-13 devnull return l;
89 0faf0f0b 2005-02-13 devnull }
90 0faf0f0b 2005-02-13 devnull
91 0faf0f0b 2005-02-13 devnull void
92 0faf0f0b 2005-02-13 devnull vtlogclose(VtLog *l)
93 0faf0f0b 2005-02-13 devnull {
94 0faf0f0b 2005-02-13 devnull if(l == nil)
95 0faf0f0b 2005-02-13 devnull return;
96 0faf0f0b 2005-02-13 devnull
97 0faf0f0b 2005-02-13 devnull qlock(&vl.lk);
98 5ddc97fc 2005-02-14 devnull if(--l->ref == 0){
99 5ddc97fc 2005-02-14 devnull /* must not be in hash table */
100 5ddc97fc 2005-02-14 devnull assert(l->name == Eremoved);
101 0faf0f0b 2005-02-13 devnull free(l);
102 5ddc97fc 2005-02-14 devnull }else
103 0faf0f0b 2005-02-13 devnull assert(l->ref > 0);
104 0faf0f0b 2005-02-13 devnull qunlock(&vl.lk);
105 0faf0f0b 2005-02-13 devnull }
106 0faf0f0b 2005-02-13 devnull
107 0faf0f0b 2005-02-13 devnull void
108 0faf0f0b 2005-02-13 devnull vtlogremove(char *name)
109 0faf0f0b 2005-02-13 devnull {
110 0faf0f0b 2005-02-13 devnull uint h;
111 0faf0f0b 2005-02-13 devnull VtLog *last, *l;
112 0faf0f0b 2005-02-13 devnull
113 0faf0f0b 2005-02-13 devnull h = hash(name)%nelem(vl.hash);
114 0faf0f0b 2005-02-13 devnull qlock(&vl.lk);
115 0faf0f0b 2005-02-13 devnull last = nil;
116 0faf0f0b 2005-02-13 devnull for(l=vl.hash[h]; l; last=l, l=l->next)
117 0faf0f0b 2005-02-13 devnull if(strcmp(l->name, name) == 0){
118 0faf0f0b 2005-02-13 devnull if(last)
119 0faf0f0b 2005-02-13 devnull last->next = l->next;
120 0faf0f0b 2005-02-13 devnull else
121 0faf0f0b 2005-02-13 devnull vl.hash[h] = l->next;
122 5ddc97fc 2005-02-14 devnull l->name = Eremoved;
123 5ddc97fc 2005-02-14 devnull l->next = nil;
124 0faf0f0b 2005-02-13 devnull qunlock(&vl.lk);
125 0faf0f0b 2005-02-13 devnull vtlogclose(l);
126 0faf0f0b 2005-02-13 devnull return;
127 0faf0f0b 2005-02-13 devnull }
128 0faf0f0b 2005-02-13 devnull qunlock(&vl.lk);
129 0faf0f0b 2005-02-13 devnull }
130 0faf0f0b 2005-02-13 devnull
131 5ddc97fc 2005-02-14 devnull static int
132 5ddc97fc 2005-02-14 devnull timefmt(Fmt *fmt)
133 5ddc97fc 2005-02-14 devnull {
134 5ddc97fc 2005-02-14 devnull static uvlong t0;
135 5ddc97fc 2005-02-14 devnull uvlong t;
136 5ddc97fc 2005-02-14 devnull
137 5ddc97fc 2005-02-14 devnull if(t0 == 0)
138 5ddc97fc 2005-02-14 devnull t0 = nsec();
139 5ddc97fc 2005-02-14 devnull t = nsec()-t0;
140 5ddc97fc 2005-02-14 devnull return fmtprint(fmt, "T+%d.%04d", (uint)(t/1000000000), (uint)(t%1000000000)/100000);
141 5ddc97fc 2005-02-14 devnull }
142 5ddc97fc 2005-02-14 devnull
143 0faf0f0b 2005-02-13 devnull void
144 0faf0f0b 2005-02-13 devnull vtlogvprint(VtLog *l, char *fmt, va_list arg)
145 0faf0f0b 2005-02-13 devnull {
146 0faf0f0b 2005-02-13 devnull int n;
147 0faf0f0b 2005-02-13 devnull char *p;
148 0faf0f0b 2005-02-13 devnull VtLogChunk *c;
149 5ddc97fc 2005-02-14 devnull static int first = 1;
150 0faf0f0b 2005-02-13 devnull
151 0faf0f0b 2005-02-13 devnull if(l == nil)
152 0faf0f0b 2005-02-13 devnull return;
153 0faf0f0b 2005-02-13 devnull
154 5ddc97fc 2005-02-14 devnull if(first){
155 5ddc97fc 2005-02-14 devnull fmtinstall('T', timefmt);
156 5ddc97fc 2005-02-14 devnull first = 0;
157 5ddc97fc 2005-02-14 devnull }
158 5ddc97fc 2005-02-14 devnull
159 5ddc97fc 2005-02-14 devnull
160 0faf0f0b 2005-02-13 devnull qlock(&l->lk);
161 0faf0f0b 2005-02-13 devnull c = l->w;
162 0faf0f0b 2005-02-13 devnull n = c->ep - c->wp;
163 0faf0f0b 2005-02-13 devnull if(n < 512){
164 0faf0f0b 2005-02-13 devnull c++;
165 0faf0f0b 2005-02-13 devnull if(c == l->chunk+l->nchunk)
166 0faf0f0b 2005-02-13 devnull c = l->chunk;
167 0faf0f0b 2005-02-13 devnull c->wp = c->p;
168 0faf0f0b 2005-02-13 devnull l->w = c;
169 0faf0f0b 2005-02-13 devnull }
170 0faf0f0b 2005-02-13 devnull p = vseprint(c->wp, c->ep, fmt, arg);
171 0faf0f0b 2005-02-13 devnull if(p)
172 0faf0f0b 2005-02-13 devnull c->wp = p;
173 0faf0f0b 2005-02-13 devnull qunlock(&l->lk);
174 0faf0f0b 2005-02-13 devnull }
175 0faf0f0b 2005-02-13 devnull
176 0faf0f0b 2005-02-13 devnull void
177 0faf0f0b 2005-02-13 devnull vtlogprint(VtLog *l, char *fmt, ...)
178 0faf0f0b 2005-02-13 devnull {
179 0faf0f0b 2005-02-13 devnull va_list arg;
180 0faf0f0b 2005-02-13 devnull
181 0faf0f0b 2005-02-13 devnull if(l == nil)
182 0faf0f0b 2005-02-13 devnull return;
183 0faf0f0b 2005-02-13 devnull
184 0faf0f0b 2005-02-13 devnull va_start(arg, fmt);
185 0faf0f0b 2005-02-13 devnull vtlogvprint(l, fmt, arg);
186 0faf0f0b 2005-02-13 devnull va_end(arg);
187 0faf0f0b 2005-02-13 devnull }
188 0faf0f0b 2005-02-13 devnull
189 0faf0f0b 2005-02-13 devnull void
190 0faf0f0b 2005-02-13 devnull vtlog(char *name, char *fmt, ...)
191 0faf0f0b 2005-02-13 devnull {
192 0faf0f0b 2005-02-13 devnull VtLog *l;
193 0faf0f0b 2005-02-13 devnull va_list arg;
194 5ddc97fc 2005-02-14 devnull
195 0faf0f0b 2005-02-13 devnull l = vtlogopen(name, LogSize);
196 5ddc97fc 2005-02-14 devnull if(l == nil)
197 5ddc97fc 2005-02-14 devnull return;
198 0faf0f0b 2005-02-13 devnull va_start(arg, fmt);
199 0faf0f0b 2005-02-13 devnull vtlogvprint(l, fmt, arg);
200 0faf0f0b 2005-02-13 devnull va_end(arg);
201 0faf0f0b 2005-02-13 devnull vtlogclose(l);
202 0faf0f0b 2005-02-13 devnull }
203 0faf0f0b 2005-02-13 devnull
204 0faf0f0b 2005-02-13 devnull void
205 0faf0f0b 2005-02-13 devnull vtlogdump(int fd, VtLog *l)
206 0faf0f0b 2005-02-13 devnull {
207 0faf0f0b 2005-02-13 devnull int i;
208 0faf0f0b 2005-02-13 devnull VtLogChunk *c;
209 0faf0f0b 2005-02-13 devnull
210 0faf0f0b 2005-02-13 devnull if(l == nil)
211 0faf0f0b 2005-02-13 devnull return;
212 0faf0f0b 2005-02-13 devnull
213 0faf0f0b 2005-02-13 devnull c = l->w;
214 0faf0f0b 2005-02-13 devnull for(i=0; i<l->nchunk; i++){
215 0faf0f0b 2005-02-13 devnull if(++c == l->chunk+l->nchunk)
216 0faf0f0b 2005-02-13 devnull c = l->chunk;
217 0faf0f0b 2005-02-13 devnull write(fd, c->p, c->wp-c->p);
218 0faf0f0b 2005-02-13 devnull }
219 0faf0f0b 2005-02-13 devnull }
220 0faf0f0b 2005-02-13 devnull