packet.c 16 KB

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