packet.c 16 KB

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