6 static Frag *fragAlloc(Packet*, int n, int pos, Frag *next);
7 static Frag *fragDup(Packet*, Frag*);
8 static void fragFree(Frag*);
10 static Mem *memAlloc(int, int);
11 static void memFree(Mem*);
12 static int memHead(Mem *m, uchar *rp, int n);
13 static int memTail(Mem *m, uchar *wp, int n);
15 static char EPacketSize[] = "bad packet size";
16 static char EPacketOffset[] = "bad packet offset";
17 static char EBadSize[] = "bad size";
31 #define FRAGSIZE(f) ((f)->wp - (f)->rp)
32 #define FRAGASIZE(f) ((f)->mem->ep - (f)->mem->bp)
34 #define NOTFREE(p) assert((p)->size>=0)
44 freeList.packet = p->next;
50 p = vtMemBrk(sizeof(Packet));
52 assert(p->size == -1);
67 if(0)fprint(2, "packetFree %p\n", p);
72 for(f=p->first; f!=nil; f=ff) {
80 p->next = freeList.packet;
86 packetDup(Packet *p, int offset, int n)
92 if(offset < 0 || n < 0 || offset+n > p->size) {
104 for(f=p->first; offset >= FRAGSIZE(f); f=f->next)
105 offset -= FRAGSIZE(f);
112 pp->asize += FRAGASIZE(ff);
117 ff->next = fragDup(pp, f);
120 pp->asize += FRAGASIZE(ff);
123 /* fix up last frag: note n <= 0 */
132 packetSplit(Packet *p, int n)
138 if(n < 0 || n > p->size) {
139 vtSetError(EPacketSize);
150 for(f=p->first; n > 0 && n >= FRAGSIZE(f); f=f->next) {
152 p->asize -= FRAGASIZE(f);
153 pp->asize += FRAGASIZE(f);
157 /* split shared frag */
161 pp->asize += FRAGASIZE(ff);
167 pp->first = p->first;
174 packetConsume(Packet *p, uchar *buf, int n)
177 if(buf && !packetCopy(p, buf, 0, n))
179 return packetTrim(p, n, p->size-n);
183 packetTrim(Packet *p, int offset, int n)
188 if(offset < 0 || offset > p->size) {
189 vtSetError(EPacketOffset);
193 if(n < 0 || offset + n > p->size) {
194 vtSetError(EPacketOffset);
202 for(f=p->first; f != nil; f=ff) {
206 p->first = p->last = nil;
211 /* free before offset */
212 for(f=p->first; offset >= FRAGSIZE(f); f=ff) {
213 p->asize -= FRAGASIZE(f);
214 offset -= FRAGSIZE(f);
224 for(; n > 0 && n > FRAGSIZE(f); f=f->next)
234 for(f=ff; f != nil; f=ff) {
235 p->asize -= FRAGASIZE(f);
243 packetHeader(Packet *p, int n)
249 if(n <= 0 || n > MaxFragSize) {
250 vtSetError(EPacketSize);
256 /* try and fix in current frag */
260 if(n <= f->rp - m->bp)
261 if(m->ref == 1 || memHead(m, f->rp, n)) {
267 /* add frag to front */
268 f = fragAlloc(p, n, PEnd, p->first);
269 p->asize += FRAGASIZE(f);
277 packetTrailer(Packet *p, int n)
283 if(n <= 0 || n > MaxFragSize) {
284 vtSetError(EPacketSize);
290 /* try and fix in current frag */
291 if(p->first != nil) {
294 if(n <= m->ep - f->wp)
295 if(m->ref == 1 || memTail(m, f->wp, n)) {
301 /* add frag to end */
302 f = fragAlloc(p, n, (p->first == nil)?PMiddle:PFront, nil);
303 p->asize += FRAGASIZE(f);
313 packetPrefix(Packet *p, uchar *buf, int n)
325 /* try and fix in current frag */
332 if(m->ref == 1 || memHead(m, f->rp, nn)) {
335 memmove(f->rp, buf+n, nn);
343 f = fragAlloc(p, nn, PEnd, p->first);
344 p->asize += FRAGASIZE(f);
349 memmove(f->rp, buf+n, nn);
355 packetAppend(Packet *p, uchar *buf, int n)
366 /* try and fix in current frag */
367 if(p->first != nil) {
373 if(m->ref == 1 || memTail(m, f->wp, nn)) {
374 memmove(f->wp, buf, nn);
385 f = fragAlloc(p, nn, (p->first == nil)?PMiddle:PFront, nil);
386 p->asize += FRAGASIZE(f);
392 memmove(f->rp, buf, nn);
400 packetConcat(Packet *p, Packet *pp)
407 p->asize += pp->asize;
410 p->last->next = pp->first;
412 p->first = pp->first;
422 packetPeek(Packet *p, uchar *buf, int offset, int n)
432 if(offset < 0 || offset >= p->size) {
433 vtSetError(EPacketOffset);
437 if(n < 0 || offset + n > p->size) {
438 vtSetError(EPacketSize);
442 /* skip up to offset */
443 for(f=p->first; offset >= FRAGSIZE(f); f=f->next)
444 offset -= FRAGSIZE(f);
447 if(offset + n <= FRAGSIZE(f))
448 return f->rp + offset;
450 for(b=buf; n>0; n -= nn) {
451 nn = FRAGSIZE(f) - offset;
454 memmove(b, f->rp+offset, nn);
464 packetCopy(Packet *p, uchar *buf, int offset, int n)
469 b = packetPeek(p, buf, offset, n);
478 packetFragments(Packet *p, IOchunk *io, int nio, int offset)
485 if(p->size == 0 || nio <= 0)
488 if(offset < 0 || offset > p->size) {
489 vtSetError(EPacketOffset);
493 for(f=p->first; offset >= FRAGSIZE(f); f=f->next)
494 offset -= FRAGSIZE(f);
498 for(; f != nil && io < eio; f=f->next) {
499 io->addr = f->rp + offset;
500 io->len = f->wp - (f->rp + offset);
516 int np, nf, nsm, nbm;
520 for(p=freeList.packet; p; p=p->next)
523 for(f=freeList.frag; f; f=f->next)
526 for(m=freeList.smallMem; m; m=m->next)
529 for(m=freeList.bigMem; m; m=m->next)
532 fprint(2, "packet: %d/%d frag: %d/%d small mem: %d/%d big mem: %d/%d\n",
533 np, freeList.npacket,
535 nsm, freeList.nsmallMem,
536 nbm, freeList.nbigMem);
538 unlock(&freeList.lk);
543 packetSize(Packet *p)
550 for(f=p->first; f; f=f->next)
553 fprint(2, "packetSize %d %d\n", size, p->size);
554 assert(size == p->size);
560 packetAllocatedSize(Packet *p)
567 for(f=p->first; f; f=f->next)
568 asize += FRAGASIZE(f);
569 if(asize != p->asize)
570 fprint(2, "packetAllocatedSize %d %d\n", asize, p->asize);
571 assert(asize == p->asize);
577 packetSha1(Packet *p, uchar sha1[VtScoreSize])
586 for(f=p->first; f; f=f->next) {
587 vtSha1Update(s, f->rp, FRAGSIZE(f));
591 vtSha1Final(s, sha1);
596 packetCmp(Packet *pkt0, Packet *pkt1)
607 return (f1 == nil)?0:-1;
615 x = memcmp(f0->wp - n0, f1->wp - n1, n0);
623 } else if (n0 > n1) {
624 x = memcmp(f0->wp - n0, f1->wp - n1, n1);
632 } else { /* n0 == n1 */
633 x = memcmp(f0->wp - n0, f1->wp - n1, n0);
639 return (f1 == nil)?0:-1;
650 fragAlloc(Packet *p, int n, int pos, Frag *next)
655 /* look for local frag */
657 ef = &p->local[NLocalFrag];
659 if(f->state == FragLocalFree) {
660 f->state = FragLocalAlloc;
667 freeList.frag = f->next;
670 unlock(&freeList.lk);
673 f = vtMemBrk(sizeof(Frag));
674 f->state = FragGlobal;
681 if(pos == PEnd && next == nil)
683 m = memAlloc(n, pos);
693 fragDup(Packet *p, Frag *f)
701 * m->rp && m->wp can be out of date when ref == 1
702 * also, potentially reclaims space from previous frags
709 ff = fragAlloc(p, 0, 0, nil);
723 if(f->state == FragLocalAlloc) {
724 f->state = FragLocalFree;
729 f->next = freeList.frag;
731 unlock(&freeList.lk);
735 memAlloc(int n, int pos)
740 if(n < 0 || n > MaxFragSize) {
741 vtSetError(EPacketSize);
744 if(n <= SmallMemSize) {
746 m = freeList.smallMem;
748 freeList.smallMem = m->next;
750 freeList.nsmallMem++;
751 unlock(&freeList.lk);
757 freeList.bigMem = m->next;
760 unlock(&freeList.lk);
765 m = vtMemBrk(sizeof(Mem));
766 m->bp = vtMemBrk(nn);
779 /* leave a little bit at end */
780 m->rp = m->ep - n - 32;
786 /* check we did not blow it */
790 assert(m->rp >= m->bp && m->wp <= m->ep);
806 switch(m->ep - m->bp) {
811 m->next = freeList.smallMem;
812 freeList.smallMem = m;
813 unlock(&freeList.lk);
817 m->next = freeList.bigMem;
819 unlock(&freeList.lk);
825 memHead(Mem *m, uchar *rp, int n)
838 memTail(Mem *m, uchar *wp, int n)