packet.c (15872B)
1 #include <u.h> 2 #include <libc.h> 3 #include <venti.h> 4 #include <libsec.h> 5 6 typedef struct Mem Mem; 7 typedef struct Frag Frag; 8 9 enum { 10 BigMemSize = MaxFragSize, 11 SmallMemSize = BigMemSize/8, 12 NLocalFrag = 2 13 }; 14 15 /* position to carve out of a Mem */ 16 enum { 17 PFront, 18 PMiddle, 19 PEnd 20 }; 21 22 struct Mem 23 { 24 Lock lk; 25 int ref; 26 uchar *bp; 27 uchar *ep; 28 uchar *rp; 29 uchar *wp; 30 Mem *next; 31 }; 32 33 enum { 34 FragLocalFree, 35 FragLocalAlloc, 36 FragGlobal 37 }; 38 39 struct Frag 40 { 41 int state; 42 Mem *mem; 43 uchar *rp; 44 uchar *wp; 45 Frag *next; 46 void (*free)(void*); 47 void *a; 48 Packet *p; /* parent packet, for debugging only */ 49 }; 50 51 struct Packet 52 { 53 int size; 54 int asize; /* allocated memory - greater than size unless foreign frags */ 55 ulong pc; 56 57 Packet *next; 58 59 Frag *first; 60 Frag *last; 61 62 Frag local[NLocalFrag]; 63 }; 64 65 static Frag *fragalloc(Packet*, int n, int pos, Frag *next); 66 static Frag *fragdup(Packet*, Frag*); 67 static void fragfree(Frag*); 68 69 static Mem *memalloc(int, int); 70 static void memfree(Mem*); 71 static int memhead(Mem *m, uchar *rp, int n); 72 static int memtail(Mem *m, uchar *wp, int n); 73 74 static char EPacketSize[] = "bad packet size"; 75 static char EPacketOffset[] = "bad packet offset"; 76 static char EBadSize[] = "bad size"; 77 78 #ifdef NOTDEF 79 static void checkpacket(Packet*); 80 #endif 81 82 /* 83 * the free list is primarily for speed, but it is 84 * also necessary for packetsplit that packets 85 * are never freed -- a packet can contain a different 86 * packet's local fragments, thanks to packetsplit! 87 */ 88 static struct { 89 Lock lk; 90 Packet *packet; 91 int npacket; 92 Frag *frag; 93 int nfrag; 94 Mem *bigmem; 95 int nbigmem; 96 Mem *smallmem; 97 int nsmallmem; 98 } freelist; 99 100 #define FRAGSIZE(f) ((f)->wp - (f)->rp) 101 #define FRAGASIZE(f) ((f)->mem ? (f)->mem->ep - (f)->mem->bp : 0) 102 103 #define NOTFREE(p) assert((p)->size>=0)/*; checkpacket(p)*/ 104 105 Packet * 106 packetalloc(void) 107 { 108 Packet *p; 109 110 lock(&freelist.lk); 111 p = freelist.packet; 112 if(p != nil) 113 freelist.packet = p->next; 114 else 115 freelist.npacket++; 116 unlock(&freelist.lk); 117 118 if(p == nil) 119 p = vtbrk(sizeof(Packet)); 120 else 121 assert(p->size == -1); 122 p->size = 0; 123 p->asize = 0; 124 p->first = nil; 125 p->last = nil; 126 p->next = nil; 127 p->pc = getcallerpc((char*)&p+8); /* might not work, but fine */ 128 129 NOTFREE(p); 130 return p; 131 } 132 133 void 134 packetfree(Packet *p) 135 { 136 Frag *f, *ff; 137 138 if(p == nil) 139 return; 140 141 NOTFREE(p); 142 p->pc = getcallerpc(&p); 143 144 for(f=p->first; f!=nil; f=ff) { 145 ff = f->next; 146 fragfree(f); 147 } 148 p->first = (void*)0xDeadBeef; 149 p->last = (void*)0xDeadBeef; 150 p->size = -1; 151 152 lock(&freelist.lk); 153 p->next = freelist.packet; 154 freelist.packet = p; 155 unlock(&freelist.lk); 156 } 157 158 Packet * 159 packetdup(Packet *p, int offset, int n) 160 { 161 Frag *f, *ff; 162 Packet *pp; 163 164 NOTFREE(p); 165 if(offset < 0 || n < 0 || offset+n > p->size) { 166 werrstr(EBadSize); 167 return nil; 168 } 169 170 pp = packetalloc(); 171 pp->pc = getcallerpc(&p); 172 if(n == 0){ 173 NOTFREE(pp); 174 return pp; 175 } 176 177 pp->size = n; 178 179 /* skip offset */ 180 for(f=p->first; offset >= FRAGSIZE(f); f=f->next) 181 offset -= FRAGSIZE(f); 182 183 /* first frag */ 184 ff = fragdup(pp, f); 185 ff->rp += offset; 186 pp->first = ff; 187 n -= FRAGSIZE(ff); 188 pp->asize += FRAGASIZE(ff); 189 190 /* the remaining */ 191 while(n > 0) { 192 f = f->next; 193 ff->next = fragdup(pp, f); 194 ff = ff->next; 195 n -= FRAGSIZE(ff); 196 pp->asize += FRAGASIZE(ff); 197 } 198 199 /* fix up last frag: note n <= 0 */ 200 ff->wp += n; 201 ff->next = nil; 202 pp->last = ff; 203 204 NOTFREE(pp); 205 NOTFREE(p); 206 return pp; 207 } 208 209 Packet * 210 packetsplit(Packet *p, int n) 211 { 212 Packet *pp; 213 Frag *f, *ff; 214 215 NOTFREE(p); 216 if(n < 0 || n > p->size) { 217 werrstr(EPacketSize); 218 return nil; 219 } 220 221 pp = packetalloc(); 222 pp->pc = getcallerpc(&p); 223 if(n == 0){ 224 NOTFREE(pp); 225 return pp; 226 } 227 228 pp->size = n; 229 p->size -= n; 230 ff = nil; 231 for(f=p->first; n > 0 && n >= FRAGSIZE(f); f=f->next) { 232 n -= FRAGSIZE(f); 233 p->asize -= FRAGASIZE(f); 234 pp->asize += FRAGASIZE(f); 235 f->p = pp; 236 ff = f; 237 } 238 239 /* split shared frag */ 240 if(n > 0) { 241 f->p = pp; 242 ff = f; 243 f = fragdup(p, ff); 244 pp->asize += FRAGASIZE(ff); 245 ff->wp = ff->rp + n; 246 f->rp += n; 247 } 248 249 pp->first = p->first; 250 pp->last = ff; 251 ff->next = nil; 252 p->first = f; 253 if(f == nil || f->next == nil) 254 p->last = f; 255 NOTFREE(pp); 256 NOTFREE(p); 257 return pp; 258 } 259 260 int 261 packetconsume(Packet *p, uchar *buf, int n) 262 { 263 NOTFREE(p); 264 if(buf && packetcopy(p, buf, 0, n) < 0) 265 return -1; 266 return packettrim(p, n, p->size-n); 267 } 268 269 int 270 packettrim(Packet *p, int offset, int n) 271 { 272 Frag *f, *ff; 273 274 NOTFREE(p); 275 if(offset < 0 || offset > p->size) { 276 werrstr(EPacketOffset); 277 return -1; 278 } 279 280 if(n < 0 || offset + n > p->size) { 281 werrstr(EPacketOffset); 282 return -1; 283 } 284 285 p->size = n; 286 287 /* easy case */ 288 if(n == 0) { 289 for(f=p->first; f != nil; f=ff) { 290 ff = f->next; 291 fragfree(f); 292 } 293 p->first = p->last = nil; 294 p->asize = 0; 295 NOTFREE(p); 296 return 0; 297 } 298 299 /* free before offset */ 300 for(f=p->first; offset >= FRAGSIZE(f); f=ff) { 301 p->asize -= FRAGASIZE(f); 302 offset -= FRAGSIZE(f); 303 ff = f->next; 304 fragfree(f); 305 } 306 307 /* adjust frag */ 308 f->rp += offset; 309 p->first = f; 310 311 /* skip middle */ 312 for(; n > 0 && n > FRAGSIZE(f); f=f->next) 313 n -= FRAGSIZE(f); 314 315 /* adjust end */ 316 f->wp = f->rp + n; 317 p->last = f; 318 ff = f->next; 319 f->next = nil; 320 321 /* free after */ 322 for(f=ff; f != nil; f=ff) { 323 p->asize -= FRAGASIZE(f); 324 ff = f->next; 325 fragfree(f); 326 } 327 NOTFREE(p); 328 return 0; 329 } 330 331 uchar * 332 packetheader(Packet *p, int n) 333 { 334 Frag *f; 335 Mem *m; 336 337 NOTFREE(p); 338 if(n <= 0 || n > MaxFragSize) { 339 werrstr(EPacketSize); 340 return nil; 341 } 342 343 p->size += n; 344 345 /* try and fix in current frag */ 346 f = p->first; 347 if(f != nil) { 348 m = f->mem; 349 if(n <= f->rp - m->bp) 350 if(m->ref == 1 || memhead(m, f->rp, n) >= 0) { 351 f->rp -= n; 352 NOTFREE(p); 353 return f->rp; 354 } 355 } 356 357 /* add frag to front */ 358 f = fragalloc(p, n, PEnd, p->first); 359 p->asize += FRAGASIZE(f); 360 if(p->first == nil) 361 p->last = f; 362 p->first = f; 363 NOTFREE(p); 364 return f->rp; 365 } 366 367 uchar * 368 packettrailer(Packet *p, int n) 369 { 370 Mem *m; 371 Frag *f; 372 373 NOTFREE(p); 374 if(n <= 0 || n > MaxFragSize) { 375 werrstr(EPacketSize); 376 return nil; 377 } 378 379 p->size += n; 380 381 /* try and fix in current frag */ 382 if(p->first != nil) { 383 f = p->last; 384 m = f->mem; 385 if(n <= m->ep - f->wp) 386 if(m->ref == 1 || memtail(m, f->wp, n) >= 0) { 387 f->wp += n; 388 NOTFREE(p); 389 return f->wp - n; 390 } 391 } 392 393 /* add frag to end */ 394 f = fragalloc(p, n, (p->first == nil)?PMiddle:PFront, nil); 395 p->asize += FRAGASIZE(f); 396 if(p->first == nil) 397 p->first = f; 398 else 399 p->last->next = f; 400 p->last = f; 401 NOTFREE(p); 402 return f->rp; 403 } 404 405 void 406 packetprefix(Packet *p, uchar *buf, int n) 407 { 408 Frag *f; 409 int nn; 410 Mem *m; 411 412 NOTFREE(p); 413 if(n <= 0) 414 return; 415 416 p->size += n; 417 418 /* try and fix in current frag */ 419 f = p->first; 420 if(f != nil) { 421 m = f->mem; 422 nn = f->rp - m->bp; 423 if(nn > n) 424 nn = n; 425 if(m->ref == 1 || memhead(m, f->rp, nn) >= 0) { 426 f->rp -= nn; 427 n -= nn; 428 memmove(f->rp, buf+n, nn); 429 } 430 } 431 432 while(n > 0) { 433 nn = n; 434 if(nn > MaxFragSize) 435 nn = MaxFragSize; 436 f = fragalloc(p, nn, PEnd, p->first); 437 p->asize += FRAGASIZE(f); 438 if(p->first == nil) 439 p->last = f; 440 p->first = f; 441 n -= nn; 442 memmove(f->rp, buf+n, nn); 443 } 444 NOTFREE(p); 445 } 446 447 void 448 packetappend(Packet *p, uchar *buf, int n) 449 { 450 Frag *f; 451 int nn; 452 Mem *m; 453 454 NOTFREE(p); 455 if(n <= 0) 456 return; 457 458 p->size += n; 459 /* try and fix in current frag */ 460 if(p->first != nil) { 461 f = p->last; 462 m = f->mem; 463 nn = m->ep - f->wp; 464 if(nn > n) 465 nn = n; 466 if(m->ref == 1 || memtail(m, f->wp, nn) >= 0) { 467 memmove(f->wp, buf, nn); 468 f->wp += nn; 469 buf += nn; 470 n -= nn; 471 } 472 } 473 474 while(n > 0) { 475 nn = n; 476 if(nn > MaxFragSize) 477 nn = MaxFragSize; 478 f = fragalloc(p, nn, (p->first == nil)?PMiddle:PFront, nil); 479 p->asize += FRAGASIZE(f); 480 if(p->first == nil) 481 p->first = f; 482 else 483 p->last->next = f; 484 p->last = f; 485 memmove(f->rp, buf, nn); 486 buf += nn; 487 n -= nn; 488 } 489 NOTFREE(p); 490 } 491 492 void 493 packetconcat(Packet *p, Packet *pp) 494 { 495 Frag *f; 496 497 NOTFREE(p); 498 NOTFREE(pp); 499 if(pp->size == 0) 500 return; 501 p->size += pp->size; 502 p->asize += pp->asize; 503 for(f=pp->first; f; f=f->next) 504 f->p = p; 505 506 if(p->first != nil) 507 p->last->next = pp->first; 508 else 509 p->first = pp->first; 510 511 p->last = pp->last; 512 pp->size = 0; 513 pp->asize = 0; 514 pp->first = nil; 515 pp->last = nil; 516 NOTFREE(p); 517 NOTFREE(pp); 518 } 519 520 uchar * 521 packetpeek(Packet *p, uchar *buf, int offset, int n) 522 { 523 Frag *f; 524 int nn; 525 uchar *b; 526 527 NOTFREE(p); 528 if(n == 0) 529 return buf; 530 531 if(offset < 0 || offset >= p->size) { 532 werrstr(EPacketOffset); 533 return nil; 534 } 535 536 if(n < 0 || offset + n > p->size) { 537 werrstr(EPacketSize); 538 return nil; 539 } 540 541 /* skip up to offset */ 542 for(f=p->first; offset >= FRAGSIZE(f); f=f->next) 543 offset -= FRAGSIZE(f); 544 545 /* easy case */ 546 if(offset + n <= FRAGSIZE(f)){ 547 NOTFREE(p); 548 return f->rp + offset; 549 } 550 551 for(b=buf; n>0; n -= nn) { 552 nn = FRAGSIZE(f) - offset; 553 if(nn > n) 554 nn = n; 555 memmove(b, f->rp+offset, nn); 556 offset = 0; 557 f = f->next; 558 b += nn; 559 } 560 561 NOTFREE(p); 562 return buf; 563 } 564 565 int 566 packetcopy(Packet *p, uchar *buf, int offset, int n) 567 { 568 uchar *b; 569 570 NOTFREE(p); 571 b = packetpeek(p, buf, offset, n); 572 if(b == nil) 573 return -1; 574 if(b != buf) 575 memmove(buf, b, n); 576 return 0; 577 } 578 579 int 580 packetfragments(Packet *p, IOchunk *io, int nio, int offset) 581 { 582 Frag *f; 583 int size; 584 IOchunk *eio; 585 586 NOTFREE(p); 587 if(p->size == 0 || nio <= 0) 588 return 0; 589 590 if(offset < 0 || offset > p->size) { 591 werrstr(EPacketOffset); 592 return -1; 593 } 594 595 for(f=p->first; offset >= FRAGSIZE(f); f=f->next) 596 offset -= FRAGSIZE(f); 597 598 size = 0; 599 eio = io + nio; 600 for(; f != nil && io < eio; f=f->next) { 601 io->addr = f->rp + offset; 602 io->len = f->wp - (f->rp + offset); 603 offset = 0; 604 size += io->len; 605 io++; 606 } 607 for(; io < eio; io++){ 608 io->addr = nil; 609 io->len = 0; 610 } 611 return size; 612 } 613 614 void 615 packetstats(void) 616 { 617 Packet *p; 618 Frag *f; 619 Mem *m; 620 621 int np, nf, nsm, nbm; 622 623 lock(&freelist.lk); 624 np = 0; 625 for(p=freelist.packet; p; p=p->next) 626 np++; 627 nf = 0; 628 for(f=freelist.frag; f; f=f->next) 629 nf++; 630 nsm = 0; 631 for(m=freelist.smallmem; m; m=m->next) 632 nsm++; 633 nbm = 0; 634 for(m=freelist.bigmem; m; m=m->next) 635 nbm++; 636 637 fprint(2, "packet: %d/%d frag: %d/%d small mem: %d/%d big mem: %d/%d\n", 638 np, freelist.npacket, 639 nf, freelist.nfrag, 640 nsm, freelist.nsmallmem, 641 nbm, freelist.nbigmem); 642 643 unlock(&freelist.lk); 644 } 645 646 647 uint 648 packetsize(Packet *p) 649 { 650 NOTFREE(p); 651 if(1) { 652 Frag *f; 653 int size = 0; 654 655 for(f=p->first; f; f=f->next) 656 size += FRAGSIZE(f); 657 if(size != p->size) 658 fprint(2, "packetsize %d %d\n", size, p->size); 659 assert(size == p->size); 660 } 661 return p->size; 662 } 663 664 uint 665 packetasize(Packet *p) 666 { 667 NOTFREE(p); 668 if(0) { 669 Frag *f; 670 int asize = 0; 671 672 for(f=p->first; f; f=f->next) 673 asize += FRAGASIZE(f); 674 if(asize != p->asize) 675 fprint(2, "packetasize %d %d\n", asize, p->asize); 676 assert(asize == p->asize); 677 } 678 return p->asize; 679 } 680 681 void 682 packetsha1(Packet *p, uchar digest[VtScoreSize]) 683 { 684 DigestState ds; 685 Frag *f; 686 int size; 687 688 NOTFREE(p); 689 memset(&ds, 0, sizeof ds); 690 size = p->size; 691 for(f=p->first; f; f=f->next) { 692 sha1(f->rp, FRAGSIZE(f), nil, &ds); 693 size -= FRAGSIZE(f); 694 } 695 assert(size == 0); 696 sha1(nil, 0, digest, &ds); 697 } 698 699 int 700 packetcmp(Packet *pkt0, Packet *pkt1) 701 { 702 Frag *f0, *f1; 703 int n0, n1, x; 704 705 NOTFREE(pkt0); 706 NOTFREE(pkt1); 707 f0 = pkt0->first; 708 f1 = pkt1->first; 709 710 if(f0 == nil) 711 return (f1 == nil)?0:-1; 712 if(f1 == nil) 713 return 1; 714 n0 = FRAGSIZE(f0); 715 n1 = FRAGSIZE(f1); 716 717 for(;;) { 718 if(n0 < n1) { 719 x = memcmp(f0->wp - n0, f1->wp - n1, n0); 720 if(x != 0) 721 return x; 722 n1 -= n0; 723 f0 = f0->next; 724 if(f0 == nil) 725 return -1; 726 n0 = FRAGSIZE(f0); 727 } else if (n0 > n1) { 728 x = memcmp(f0->wp - n0, f1->wp - n1, n1); 729 if(x != 0) 730 return x; 731 n0 -= n1; 732 f1 = f1->next; 733 if(f1 == nil) 734 return 1; 735 n1 = FRAGSIZE(f1); 736 } else { /* n0 == n1 */ 737 x = memcmp(f0->wp - n0, f1->wp - n1, n0); 738 if(x != 0) 739 return x; 740 f0 = f0->next; 741 f1 = f1->next; 742 if(f0 == nil) 743 return (f1 == nil)?0:-1; 744 if(f1 == nil) 745 return 1; 746 n0 = FRAGSIZE(f0); 747 n1 = FRAGSIZE(f1); 748 } 749 } 750 } 751 752 static Frag * 753 fragalloc(Packet *p, int n, int pos, Frag *next) 754 { 755 Frag *f, *ef; 756 Mem *m; 757 758 /* look for local frag */ 759 f = &p->local[0]; 760 ef = &p->local[NLocalFrag]; 761 for(;f<ef; f++) { 762 if(f->state == FragLocalFree) { 763 f->state = FragLocalAlloc; 764 goto Found; 765 } 766 } 767 lock(&freelist.lk); 768 f = freelist.frag; 769 if(f != nil) 770 freelist.frag = f->next; 771 else 772 freelist.nfrag++; 773 unlock(&freelist.lk); 774 775 if(f == nil) { 776 f = vtbrk(sizeof(Frag)); 777 f->state = FragGlobal; 778 } 779 780 Found: 781 f->next = next; 782 f->p = p; 783 784 if(n == 0){ 785 f->mem = 0; 786 f->rp = 0; 787 f->wp = 0; 788 return f; 789 } 790 791 if(pos == PEnd && next == nil) 792 pos = PMiddle; 793 m = memalloc(n, pos); 794 f->mem = m; 795 f->rp = m->rp; 796 f->wp = m->wp; 797 return f; 798 } 799 800 Packet* 801 packetforeign(uchar *buf, int n, void (*free)(void *a), void *a) 802 { 803 Packet *p; 804 Frag *f; 805 806 p = packetalloc(); 807 p->pc = getcallerpc(&buf); 808 f = fragalloc(p, 0, 0, nil); 809 f->free = free; 810 f->a = a; 811 f->next = nil; 812 f->rp = buf; 813 f->wp = buf+n; 814 815 p->first = f; 816 p->last = f; 817 p->size = n; 818 NOTFREE(p); 819 return p; 820 } 821 822 static Frag * 823 fragdup(Packet *p, Frag *f) 824 { 825 Frag *ff; 826 Mem *m; 827 828 m = f->mem; 829 830 /* 831 * m->rp && m->wp can be out of date when ref == 1 832 * also, potentially reclaims space from previous frags 833 */ 834 if(m && m->ref == 1) { 835 m->rp = f->rp; 836 m->wp = f->wp; 837 } 838 839 ff = fragalloc(p, 0, 0, nil); 840 ff->mem = f->mem; 841 ff->rp = f->rp; 842 ff->wp = f->wp; 843 ff->next = f->next; 844 845 /* 846 * We can't duplicate these -- there's no dup function. 847 */ 848 assert(f->free==nil && f->a==nil); 849 850 if(m){ 851 lock(&m->lk); 852 m->ref++; 853 unlock(&m->lk); 854 } 855 856 857 return ff; 858 } 859 860 861 static void 862 fragfree(Frag *f) 863 { 864 if(f->mem == nil){ 865 if(f->free) 866 (*f->free)(f->a); 867 }else{ 868 memfree(f->mem); 869 f->mem = 0; 870 } 871 872 if(f->state == FragLocalAlloc) { 873 f->state = FragLocalFree; 874 return; 875 } 876 877 lock(&freelist.lk); 878 f->next = freelist.frag; 879 freelist.frag = f; 880 unlock(&freelist.lk); 881 } 882 883 static Mem * 884 memalloc(int n, int pos) 885 { 886 Mem *m; 887 int nn; 888 889 if(n < 0 || n > MaxFragSize) { 890 werrstr(EPacketSize); 891 return nil; 892 } 893 if(n <= SmallMemSize) { 894 lock(&freelist.lk); 895 m = freelist.smallmem; 896 if(m != nil) 897 freelist.smallmem = m->next; 898 else 899 freelist.nsmallmem++; 900 unlock(&freelist.lk); 901 nn = SmallMemSize; 902 } else { 903 lock(&freelist.lk); 904 m = freelist.bigmem; 905 if(m != nil) 906 freelist.bigmem = m->next; 907 else 908 freelist.nbigmem++; 909 unlock(&freelist.lk); 910 nn = BigMemSize; 911 } 912 913 if(m == nil) { 914 m = vtbrk(sizeof(Mem)); 915 m->bp = vtbrk(nn); 916 m->ep = m->bp + nn; 917 } 918 assert(m->ref == 0); 919 m->ref = 1; 920 921 switch(pos) { 922 default: 923 assert(0); 924 case PFront: 925 m->rp = m->bp; 926 break; 927 case PMiddle: 928 /* leave a little bit at end */ 929 m->rp = m->ep - n - 32; 930 break; 931 case PEnd: 932 m->rp = m->ep - n; 933 break; 934 } 935 /* check we did not blow it */ 936 if(m->rp < m->bp) 937 m->rp = m->bp; 938 m->wp = m->rp + n; 939 assert(m->rp >= m->bp && m->wp <= m->ep); 940 return m; 941 } 942 943 static void 944 memfree(Mem *m) 945 { 946 lock(&m->lk); 947 m->ref--; 948 if(m->ref > 0) { 949 unlock(&m->lk); 950 return; 951 } 952 unlock(&m->lk); 953 assert(m->ref == 0); 954 955 /* memset(m->bp, 0xEF, m->ep-m->bp); */ 956 switch(m->ep - m->bp) { 957 default: 958 assert(0); 959 case SmallMemSize: 960 lock(&freelist.lk); 961 m->next = freelist.smallmem; 962 freelist.smallmem = m; 963 unlock(&freelist.lk); 964 break; 965 case BigMemSize: 966 lock(&freelist.lk); 967 m->next = freelist.bigmem; 968 freelist.bigmem = m; 969 unlock(&freelist.lk); 970 break; 971 } 972 } 973 974 static int 975 memhead(Mem *m, uchar *rp, int n) 976 { 977 fprint(2, "memhead called\n"); 978 abort(); 979 lock(&m->lk); 980 if(m->rp != rp) { 981 unlock(&m->lk); 982 return -1; 983 } 984 m->rp -= n; 985 unlock(&m->lk); 986 return 0; 987 } 988 989 static int 990 memtail(Mem *m, uchar *wp, int n) 991 { 992 fprint(2, "memtail called\n"); 993 abort(); 994 lock(&m->lk); 995 if(m->wp != wp) { 996 unlock(&m->lk); 997 return -1; 998 } 999 m->wp += n; 1000 unlock(&m->lk); 1001 return 0; 1002 } 1003 1004 #ifdef NOTDEF 1005 static void 1006 checkpacket(Packet *p) 1007 { 1008 int s, as; 1009 Frag *f; 1010 Frag *ff; 1011 1012 s = 0; 1013 as = 0; 1014 ff=p->first; 1015 for(f=p->first; f; ff=f,f=f->next){ 1016 assert(f->p == p); 1017 s += FRAGSIZE(f); 1018 as += FRAGASIZE(f); 1019 } 1020 assert(s == p->size); 1021 assert(as == p->asize); 1022 if(p->first) 1023 assert(ff==p->last); 1024 } 1025 #endif