packet.c 16 KB

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