]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/port/log.c
pc kernel: fix wrong simd exception mask (fixes go bootstrap)
[plan9front.git] / sys / src / 9 / port / log.c
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "../port/error.h"
7
8 static char Ebadlogctl[] = "unknown log ctl message";
9
10 void
11 logopen(Log *alog)
12 {
13         lock(alog);
14         if(waserror()){
15                 unlock(alog);
16                 nexterror();
17         }
18         if(alog->opens == 0){
19                 if(alog->nlog == 0)
20                         alog->nlog = 4*1024;
21                 if(alog->minread == 0)
22                         alog->minread = 1;
23                 if(alog->buf == nil)
24                         alog->buf = smalloc(alog->nlog);
25                 alog->rptr = alog->buf;
26                 alog->end = alog->buf + alog->nlog;
27                 alog->len = 0;
28         }
29         alog->opens++;
30         unlock(alog);
31         poperror();
32 }
33
34 void
35 logclose(Log *alog)
36 {
37         lock(alog);
38         alog->opens--;
39         if(alog->opens == 0){
40                 free(alog->buf);
41                 alog->buf = nil;
42         }
43         unlock(alog);
44 }
45
46 static int
47 logready(void *a)
48 {
49         Log *alog = a;
50
51         return alog->len >= alog->minread;
52 }
53
54 long
55 logread(Log *alog, void *a, ulong, long n)
56 {
57         int i, d;
58         char *p, *rptr;
59
60         eqlock(&alog->readq);
61         if(waserror()){
62                 qunlock(&alog->readq);
63                 nexterror();
64         }
65
66         for(;;){
67                 lock(alog);
68                 if(alog->len >= alog->minread || alog->len >= n){
69                         if(n > alog->len)
70                                 n = alog->len;
71                         d = 0;
72                         rptr = alog->rptr;
73                         alog->rptr += n;
74                         if(alog->rptr >= alog->end){
75                                 d = alog->rptr - alog->end;
76                                 alog->rptr = alog->buf + d;
77                         }
78                         alog->len -= n;
79                         unlock(alog);
80
81                         i = n-d;
82                         p = a;
83                         memmove(p, rptr, i);
84                         memmove(p+i, alog->buf, d);
85                         break;
86                 }
87                 else
88                         unlock(alog);
89
90                 sleep(&alog->readr, logready, alog);
91         }
92
93         qunlock(&alog->readq);
94         poperror();
95
96         return n;
97 }
98
99 char*
100 logctl(Log *alog, int argc, char *argv[], Logflag *flags)
101 {
102         int i, set;
103         Logflag *fp;
104
105         if(argc < 2)
106                 return Ebadlogctl;
107
108         if(strcmp("set", argv[0]) == 0)
109                 set = 1;
110         else if(strcmp("clear", argv[0]) == 0)
111                 set = 0;
112         else
113                 return Ebadlogctl;
114
115         for(i = 1; i < argc; i++){
116                 for(fp = flags; fp->name; fp++)
117                         if(strcmp(fp->name, argv[i]) == 0)
118                                 break;
119                 if(fp->name == nil)
120                         continue;
121                 if(set)
122                         alog->logmask |= fp->mask;
123                 else
124                         alog->logmask &= ~fp->mask;
125         }
126
127         return nil;
128 }
129
130 void
131 logn(Log *alog, int mask, void *buf, int n)
132 {
133         char *fp, *t;
134         int dowake, i;
135
136         if(!(alog->logmask & mask))
137                 return;
138
139         if(alog->opens == 0)
140                 return;
141
142         if(n > alog->nlog)
143                 return;
144
145         lock(alog);
146         i = alog->len + n - alog->nlog;
147         if(i > 0){
148                 alog->len -= i;
149                 alog->rptr += i;
150                 if(alog->rptr >= alog->end)
151                         alog->rptr = alog->buf + (alog->rptr - alog->end);
152         }
153         t = alog->rptr + alog->len;
154         fp = buf;
155         alog->len += n;
156         while(n-- > 0){
157                 if(t >= alog->end)
158                         t = alog->buf + (t - alog->end);
159                 *t++ = *fp++;
160         }
161         dowake = alog->len >= alog->minread;
162         unlock(alog);
163
164         if(dowake)
165                 wakeup(&alog->readr);
166 }
167
168 void
169 log(Log *alog, int mask, char *fmt, ...)
170 {
171         int n;
172         va_list arg;
173         char buf[128];
174
175         if(!(alog->logmask & mask))
176                 return;
177
178         if(alog->opens == 0)
179                 return;
180
181         va_start(arg, fmt);
182         n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
183         va_end(arg);
184
185         logn(alog, mask, buf, n);
186 }