]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/5e/seg.c
webfs(4): document -d and -D flags
[plan9front.git] / sys / src / cmd / 5e / seg.c
1 #include <u.h>
2 #include <libc.h>
3 #include <thread.h>
4 #include "dat.h"
5 #include "fns.h"
6
7 Segment *
8 newseg(u32int start, u32int size, int idx)
9 {
10         Segment *s;
11         
12         s = emallocz(sizeof *s);
13         incref(s);
14         s->start = start;
15         s->size = size;
16         s->dref = emalloc(size + sizeof(Ref));
17         memset(s->dref, 0, sizeof(Ref));
18         incref(s->dref);
19         s->data = s->dref + 1;
20         if(idx == SEGBSS)
21                 s->flags = SEGFLLOCK;
22         P->S[idx] = s;
23         return s;
24 }
25
26 void
27 freesegs(void)
28 {
29         Segment **s;
30         
31         for(s = P->S; s < P->S + SEGNUM; s++) {
32                 if(*s == nil)
33                         continue;
34                 if(decref((*s)->dref) == 0)
35                         free((*s)->dref);
36                 if(decref(*s) == 0)
37                         free(*s);
38                 *s = nil;
39         }
40 }
41
42 void *
43 vaddr(u32int addr, u32int len, Segment **seg)
44 {
45         Segment **ss, *s;
46
47         for(ss = P->S; ss < P->S + SEGNUM; ss++) {
48                 if(*ss == nil)
49                         continue;
50                 s = *ss;
51                 if(addr >= s->start && addr < s->start + s->size) {
52                         if(addr + len > s->start + s->size)
53                                 break;
54                         if(s->flags & SEGFLLOCK)
55                                 rlock(&s->rw);
56                         *seg = s;
57                         return (char *)s->data + (addr - s->start);
58                 }
59         }
60         suicide("fault %.8ux (%d) @ %.8ux", addr, len, P->R[15]);
61         return nil;
62 }
63
64 void *
65 vaddrnol(u32int addr, u32int len)
66 {
67         Segment *seg;
68         void *ret;
69         
70         ret = vaddr(addr, len, &seg);
71         segunlock(seg);
72         return ret;
73 }
74
75 /* might be made a macro for hurr durr performance */
76 void
77 segunlock(Segment *s)
78 {
79         if(s->flags & SEGFLLOCK)
80                 runlock(&s->rw);
81 }
82
83 void *
84 copyifnec(u32int addr, int len, int *copied)
85 {
86         void *targ, *ret;
87         Segment *seg;
88         
89         targ = vaddr(addr, len > 0 ? len : 0, &seg);
90         if((seg->flags & SEGFLLOCK) == 0) {
91                 *copied = 0;
92                 return targ;
93         }
94         if(len < 0)
95                 len = strlen(targ) + 1;
96         ret = emalloc(len);
97         setmalloctag(ret, getcallerpc(&addr));
98         memcpy(ret, targ, len);
99         segunlock(seg);
100         *copied = 1;
101         return ret;
102 }
103
104 void *
105 bufifnec(u32int addr, int len, int *buffered)
106 {
107         void *targ, *v;
108         Segment *seg;
109         
110         targ = vaddr(addr, len, &seg);
111         if((seg->flags & SEGFLLOCK) == 0) {
112                 *buffered = 0;
113                 return targ;
114         }
115         segunlock(seg);
116         *buffered = 1;
117         v = emalloc(len);
118         setmalloctag(v, getcallerpc(&addr));
119         return v;
120 }
121
122 void
123 copyback(u32int addr, int len, void *data)
124 {
125         void *targ;
126         Segment *seg;
127
128         if(len <= 0) {
129                 free(data);
130                 return;
131         }
132         targ = vaddr(addr, len, &seg);
133         memmove(targ, data, len);
134         segunlock(seg);
135         free(data);
136 }