14 typedef struct Barena Barena;
32 typedef struct Arefent Arefent;
38 typedef struct Aref Aref;
46 static ulong callerpc(void*);
47 static void aref(Aref*, ulong);
48 static void aunref(Aref*, ulong);
57 sz = (len>>BPOW)&(NLIST-1);
61 for(bp = *l; bp; bp = bp->flist) {
69 bp->base = (uchar*)bp+sizeof(Block);
70 bp->rptr = bp->base+PAD;
72 bp->lim = bp->base+bp->bsz;
76 bp->pc = callerpc(&len);
77 aref(&arefblock, bp->pc);
86 bp = mallocz(sizeof(Block)+len, 1);
89 bp->base = (uchar*)bp+sizeof(Block);
90 bp->rptr = bp->base+PAD;
92 bp->lim = bp->base+len;
94 bp->pc = callerpc(&len);
95 aref(&arefblock, bp->pc);
108 sz = (bp->bsz>>BPOW)&(NLIST-1);
116 /* to catch use after free */
117 bp->rptr = (uchar*)0xdeadbabe;
118 bp->wptr = (uchar*)0xdeadbabe;
119 bp->next = (Block*)0xdeadbabe;
120 bp->list = (Block*)0xdeadbabe;
122 ADEBUG aunref(&arefblock, bp->pc);
130 * concatenate a list of blocks into a single one and make sure
131 * the result is at least min uchars
139 nb = allocb(blen(bp));
140 for(f = bp; f; f = f->next) {
142 memmove(nb->wptr, f->rptr, len);
163 pullup(Block *bp, int n)
169 * this should almost always be true, the rest it
170 * just for to avoid every caller checking.
176 * if not enough room in the first block,
177 * add another to the front of the list.
179 if(bp->lim - bp->rptr < n){
186 * copy uchars from the trailing blocks into the first
189 while(nbp = bp->next){
192 memmove(bp->wptr, nbp->rptr, n);
198 memmove(bp->wptr, nbp->rptr, i);
200 bp->next = nbp->next;
211 * Pad a block to the front with n uchars. This is used to add protocol
212 * headers to the front of blocks.
215 padb(Block *bp, int n)
219 if(bp->rptr-bp->base >= n) {
224 /* fprint(2, "padb: required %d PAD %d\n", n, PAD) = malloc(sizeof(*required %d PAD %d\n", n, PAD))); */
226 nbp->wptr = nbp->lim;
227 nbp->rptr = nbp->wptr - n;
234 btrim(Block *bp, int offset, int len)
239 if(blen(bp) < offset+len) {
244 while((l = BLEN(bp)) < offset) {
255 while((l = BLEN(bp)) < len) {
260 bp->wptr -= (BLEN(bp) - len);
261 bp->flags |= S_DELIM;
272 copyb(Block *bp, int count)
275 Block *nb, *head, **p;
279 while(bp != nil && count != 0) {
284 memmove(nb->wptr, bp->rptr, l);
287 nb->flags = bp->flags;
294 memset(nb->wptr, 0, count);
296 nb->flags |= S_DELIM;
300 fprint(2, "copyb: zero length\n");
306 pullb(Block **bph, int count)
315 while(*bph != nil && count != 0) {
333 * handy routines for keeping track of allocations
338 return ((ulong*)a)[-1];
341 aref(Aref *ap, ulong pc)
347 for(a = ap->tab; a < e; a++)
348 if(a->pc == pc || a->pc == 0)
355 aunref(Aref *ap, ulong pc)
361 for(a = ap->tab; a < e; a++)
362 if(a->pc == pc || a->pc == 0)