packet.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857
  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 <oventi.h>
  12. #include "packet.h"
  13. static Frag *fragAlloc(Packet*, int n, int pos, Frag *next);
  14. static Frag *fragDup(Packet*, Frag*);
  15. static void fragFree(Frag*);
  16. static Mem *memAlloc(int, int);
  17. static void memFree(Mem*);
  18. static int memHead(Mem *m, uint8_t *rp, int n);
  19. static int memTail(Mem *m, uint8_t *wp, int n);
  20. static char EPacketSize[] = "bad packet size";
  21. static char EPacketOffset[] = "bad packet offset";
  22. static char EBadSize[] = "bad size";
  23. static struct {
  24. Lock lk;
  25. Packet *packet;
  26. int npacket;
  27. Frag *frag;
  28. int nfrag;
  29. Mem *bigMem;
  30. int nbigMem;
  31. Mem *smallMem;
  32. int nsmallMem;
  33. } freeList;
  34. #define FRAGSIZE(f) ((f)->wp - (f)->rp)
  35. #define FRAGASIZE(f) ((f)->mem->ep - (f)->mem->bp)
  36. #define NOTFREE(p) assert((p)->size>=0)
  37. Packet *
  38. packetAlloc(void)
  39. {
  40. Packet *p;
  41. lock(&freeList.lk);
  42. p = freeList.packet;
  43. if(p != nil)
  44. freeList.packet = p->next;
  45. else
  46. freeList.npacket++;
  47. unlock(&freeList.lk);
  48. if(p == nil)
  49. p = vtMemBrk(sizeof(Packet));
  50. else
  51. assert(p->size == -1);
  52. p->size = 0;
  53. p->asize = 0;
  54. p->first = nil;
  55. p->last = nil;
  56. p->next = nil;
  57. return p;
  58. }
  59. void
  60. packetFree(Packet *p)
  61. {
  62. Frag *f, *ff;
  63. if(0)fprint(2, "packetFree %p\n", p);
  64. NOTFREE(p);
  65. p->size = -1;
  66. for(f=p->first; f!=nil; f=ff) {
  67. ff = f->next;
  68. fragFree(f);
  69. }
  70. p->first = nil;
  71. p->last = nil;
  72. lock(&freeList.lk);
  73. p->next = freeList.packet;
  74. freeList.packet = p;
  75. unlock(&freeList.lk);
  76. }
  77. Packet *
  78. packetDup(Packet *p, int offset, int n)
  79. {
  80. Frag *f, *ff;
  81. Packet *pp;
  82. NOTFREE(p);
  83. if(offset < 0 || n < 0 || offset+n > p->size) {
  84. vtSetError(EBadSize);
  85. return nil;
  86. }
  87. pp = packetAlloc();
  88. if(n == 0)
  89. return pp;
  90. pp->size = n;
  91. /* skip offset */
  92. for(f=p->first; offset >= FRAGSIZE(f); f=f->next)
  93. offset -= FRAGSIZE(f);
  94. /* first frag */
  95. ff = fragDup(pp, f);
  96. ff->rp += offset;
  97. pp->first = ff;
  98. n -= FRAGSIZE(ff);
  99. pp->asize += FRAGASIZE(ff);
  100. /* the remaining */
  101. while(n > 0) {
  102. f = f->next;
  103. ff->next = fragDup(pp, f);
  104. ff = ff->next;
  105. n -= FRAGSIZE(ff);
  106. pp->asize += FRAGASIZE(ff);
  107. }
  108. /* fix up last frag: note n <= 0 */
  109. ff->wp += n;
  110. ff->next = nil;
  111. pp->last = ff;
  112. return pp;
  113. }
  114. Packet *
  115. packetSplit(Packet *p, int n)
  116. {
  117. Packet *pp;
  118. Frag *f, *ff;
  119. NOTFREE(p);
  120. if(n < 0 || n > p->size) {
  121. vtSetError(EPacketSize);
  122. return nil;
  123. }
  124. pp = packetAlloc();
  125. if(n == 0)
  126. return pp;
  127. pp->size = n;
  128. p->size -= n;
  129. ff = nil;
  130. for(f=p->first; n > 0 && n >= FRAGSIZE(f); f=f->next) {
  131. n -= FRAGSIZE(f);
  132. p->asize -= FRAGASIZE(f);
  133. pp->asize += FRAGASIZE(f);
  134. ff = f;
  135. }
  136. /* split shared frag */
  137. if(n > 0) {
  138. ff = f;
  139. f = fragDup(pp, ff);
  140. pp->asize += FRAGASIZE(ff);
  141. ff->next = nil;
  142. ff->wp = ff->rp + n;
  143. f->rp += n;
  144. }
  145. pp->first = p->first;
  146. pp->last = ff;
  147. p->first = f;
  148. return pp;
  149. }
  150. int
  151. packetConsume(Packet *p, uint8_t *buf, int n)
  152. {
  153. NOTFREE(p);
  154. if(buf && !packetCopy(p, buf, 0, n))
  155. return 0;
  156. return packetTrim(p, n, p->size-n);
  157. }
  158. int
  159. packetTrim(Packet *p, int offset, int n)
  160. {
  161. Frag *f, *ff;
  162. NOTFREE(p);
  163. if(offset < 0 || offset > p->size) {
  164. vtSetError(EPacketOffset);
  165. return 0;
  166. }
  167. if(n < 0 || offset + n > p->size) {
  168. vtSetError(EPacketOffset);
  169. return 0;
  170. }
  171. p->size = n;
  172. /* easy case */
  173. if(n == 0) {
  174. for(f=p->first; f != nil; f=ff) {
  175. ff = f->next;
  176. fragFree(f);
  177. }
  178. p->first = p->last = nil;
  179. p->asize = 0;
  180. return 1;
  181. }
  182. /* free before offset */
  183. for(f=p->first; offset >= FRAGSIZE(f); f=ff) {
  184. p->asize -= FRAGASIZE(f);
  185. offset -= FRAGSIZE(f);
  186. ff = f->next;
  187. fragFree(f);
  188. }
  189. /* adjust frag */
  190. f->rp += offset;
  191. p->first = f;
  192. /* skip middle */
  193. for(; n > 0 && n > FRAGSIZE(f); f=f->next)
  194. n -= FRAGSIZE(f);
  195. /* adjust end */
  196. f->wp = f->rp + n;
  197. p->last = f;
  198. ff = f->next;
  199. f->next = nil;
  200. /* free after */
  201. for(f=ff; f != nil; f=ff) {
  202. p->asize -= FRAGASIZE(f);
  203. ff = f->next;
  204. fragFree(f);
  205. }
  206. return 1;
  207. }
  208. uint8_t *
  209. packetHeader(Packet *p, int n)
  210. {
  211. Frag *f;
  212. Mem *m;
  213. NOTFREE(p);
  214. if(n <= 0 || n > MaxFragSize) {
  215. vtSetError(EPacketSize);
  216. return 0;
  217. }
  218. p->size += n;
  219. /* try and fix in current frag */
  220. f = p->first;
  221. if(f != nil) {
  222. m = f->mem;
  223. if(n <= f->rp - m->bp)
  224. if(m->ref == 1 || memHead(m, f->rp, n)) {
  225. f->rp -= n;
  226. return f->rp;
  227. }
  228. }
  229. /* add frag to front */
  230. f = fragAlloc(p, n, PEnd, p->first);
  231. p->asize += FRAGASIZE(f);
  232. if(p->first == nil)
  233. p->last = f;
  234. p->first = f;
  235. return f->rp;
  236. }
  237. uint8_t *
  238. packetTrailer(Packet *p, int n)
  239. {
  240. Mem *m;
  241. Frag *f;
  242. NOTFREE(p);
  243. if(n <= 0 || n > MaxFragSize) {
  244. vtSetError(EPacketSize);
  245. return 0;
  246. }
  247. p->size += n;
  248. /* try and fix in current frag */
  249. if(p->first != nil) {
  250. f = p->last;
  251. m = f->mem;
  252. if(n <= m->ep - f->wp)
  253. if(m->ref == 1 || memTail(m, f->wp, n)) {
  254. f->wp += n;
  255. return f->wp - n;
  256. }
  257. }
  258. /* add frag to end */
  259. f = fragAlloc(p, n, (p->first == nil)?PMiddle:PFront, nil);
  260. p->asize += FRAGASIZE(f);
  261. if(p->first == nil)
  262. p->first = f;
  263. else
  264. p->last->next = f;
  265. p->last = f;
  266. return f->rp;
  267. }
  268. int
  269. packetPrefix(Packet *p, uint8_t *buf, int n)
  270. {
  271. Frag *f;
  272. int nn;
  273. Mem *m;
  274. NOTFREE(p);
  275. if(n <= 0)
  276. return 1;
  277. p->size += n;
  278. /* try and fix in current frag */
  279. f = p->first;
  280. if(f != nil) {
  281. m = f->mem;
  282. nn = f->rp - m->bp;
  283. if(nn > n)
  284. nn = n;
  285. if(m->ref == 1 || memHead(m, f->rp, nn)) {
  286. f->rp -= nn;
  287. n -= nn;
  288. memmove(f->rp, buf+n, nn);
  289. }
  290. }
  291. while(n > 0) {
  292. nn = n;
  293. if(nn > MaxFragSize)
  294. nn = MaxFragSize;
  295. f = fragAlloc(p, nn, PEnd, p->first);
  296. p->asize += FRAGASIZE(f);
  297. if(p->first == nil)
  298. p->last = f;
  299. p->first = f;
  300. n -= nn;
  301. memmove(f->rp, buf+n, nn);
  302. }
  303. return 1;
  304. }
  305. int
  306. packetAppend(Packet *p, uint8_t *buf, int n)
  307. {
  308. Frag *f;
  309. int nn;
  310. Mem *m;
  311. NOTFREE(p);
  312. if(n <= 0)
  313. return 1;
  314. p->size += n;
  315. /* try and fix in current frag */
  316. if(p->first != nil) {
  317. f = p->last;
  318. m = f->mem;
  319. nn = m->ep - f->wp;
  320. if(nn > n)
  321. nn = n;
  322. if(m->ref == 1 || memTail(m, f->wp, nn)) {
  323. memmove(f->wp, buf, nn);
  324. f->wp += nn;
  325. buf += nn;
  326. n -= nn;
  327. }
  328. }
  329. while(n > 0) {
  330. nn = n;
  331. if(nn > MaxFragSize)
  332. nn = MaxFragSize;
  333. f = fragAlloc(p, nn, (p->first == nil)?PMiddle:PFront, nil);
  334. p->asize += FRAGASIZE(f);
  335. if(p->first == nil)
  336. p->first = f;
  337. else
  338. p->last->next = f;
  339. p->last = f;
  340. memmove(f->rp, buf, nn);
  341. buf += nn;
  342. n -= nn;
  343. }
  344. return 1;
  345. }
  346. int
  347. packetConcat(Packet *p, Packet *pp)
  348. {
  349. NOTFREE(p);
  350. NOTFREE(pp);
  351. if(pp->size == 0)
  352. return 1;
  353. p->size += pp->size;
  354. p->asize += pp->asize;
  355. if(p->first != nil)
  356. p->last->next = pp->first;
  357. else
  358. p->first = pp->first;
  359. p->last = pp->last;
  360. pp->size = 0;
  361. pp->asize = 0;
  362. pp->first = nil;
  363. pp->last = nil;
  364. return 1;
  365. }
  366. uint8_t *
  367. packetPeek(Packet *p, uint8_t *buf, int offset, int n)
  368. {
  369. Frag *f;
  370. int nn;
  371. uint8_t *b;
  372. NOTFREE(p);
  373. if(n == 0)
  374. return buf;
  375. if(offset < 0 || offset >= p->size) {
  376. vtSetError(EPacketOffset);
  377. return 0;
  378. }
  379. if(n < 0 || offset + n > p->size) {
  380. vtSetError(EPacketSize);
  381. return 0;
  382. }
  383. /* skip up to offset */
  384. for(f=p->first; offset >= FRAGSIZE(f); f=f->next)
  385. offset -= FRAGSIZE(f);
  386. /* easy case */
  387. if(offset + n <= FRAGSIZE(f))
  388. return f->rp + offset;
  389. for(b=buf; n>0; n -= nn) {
  390. nn = FRAGSIZE(f) - offset;
  391. if(nn > n)
  392. nn = n;
  393. memmove(b, f->rp+offset, nn);
  394. offset = 0;
  395. f = f->next;
  396. b += nn;
  397. }
  398. return buf;
  399. }
  400. int
  401. packetCopy(Packet *p, uint8_t *buf, int offset, int n)
  402. {
  403. uint8_t *b;
  404. NOTFREE(p);
  405. b = packetPeek(p, buf, offset, n);
  406. if(b == nil)
  407. return 0;
  408. if(b != buf)
  409. memmove(buf, b, n);
  410. return 1;
  411. }
  412. int
  413. packetFragments(Packet *p, IOchunk *io, int nio, int offset)
  414. {
  415. Frag *f;
  416. int size;
  417. IOchunk *eio;
  418. NOTFREE(p);
  419. if(p->size == 0 || nio <= 0)
  420. return 0;
  421. if(offset < 0 || offset > p->size) {
  422. vtSetError(EPacketOffset);
  423. return -1;
  424. }
  425. for(f=p->first; offset >= FRAGSIZE(f); f=f->next)
  426. offset -= FRAGSIZE(f);
  427. size = 0;
  428. eio = io + nio;
  429. for(; f != nil && io < eio; f=f->next) {
  430. io->addr = f->rp + offset;
  431. io->len = f->wp - (f->rp + offset);
  432. offset = 0;
  433. size += io->len;
  434. io++;
  435. }
  436. return size;
  437. }
  438. void
  439. packetStats(void)
  440. {
  441. Packet *p;
  442. Frag *f;
  443. Mem *m;
  444. int np, nf, nsm, nbm;
  445. lock(&freeList.lk);
  446. np = 0;
  447. for(p=freeList.packet; p; p=p->next)
  448. np++;
  449. nf = 0;
  450. for(f=freeList.frag; f; f=f->next)
  451. nf++;
  452. nsm = 0;
  453. for(m=freeList.smallMem; m; m=m->next)
  454. nsm++;
  455. nbm = 0;
  456. for(m=freeList.bigMem; m; m=m->next)
  457. nbm++;
  458. fprint(2, "packet: %d/%d frag: %d/%d small mem: %d/%d big mem: %d/%d\n",
  459. np, freeList.npacket,
  460. nf, freeList.nfrag,
  461. nsm, freeList.nsmallMem,
  462. nbm, freeList.nbigMem);
  463. unlock(&freeList.lk);
  464. }
  465. int
  466. packetSize(Packet *p)
  467. {
  468. NOTFREE(p);
  469. if(0) {
  470. Frag *f;
  471. int size = 0;
  472. for(f=p->first; f; f=f->next)
  473. size += FRAGSIZE(f);
  474. if(size != p->size)
  475. fprint(2, "packetSize %d %d\n", size, p->size);
  476. assert(size == p->size);
  477. }
  478. return p->size;
  479. }
  480. int
  481. packetAllocatedSize(Packet *p)
  482. {
  483. NOTFREE(p);
  484. if(0) {
  485. Frag *f;
  486. int asize = 0;
  487. for(f=p->first; f; f=f->next)
  488. asize += FRAGASIZE(f);
  489. if(asize != p->asize)
  490. fprint(2, "packetAllocatedSize %d %d\n", asize, p->asize);
  491. assert(asize == p->asize);
  492. }
  493. return p->asize;
  494. }
  495. void
  496. packetSha1(Packet *p, uint8_t sha1[VtScoreSize])
  497. {
  498. Frag *f;
  499. VtSha1 *s;
  500. int size;
  501. NOTFREE(p);
  502. s = vtSha1Alloc();
  503. size = p->size;
  504. for(f=p->first; f; f=f->next) {
  505. vtSha1Update(s, f->rp, FRAGSIZE(f));
  506. size -= FRAGSIZE(f);
  507. }
  508. assert(size == 0);
  509. vtSha1Final(s, sha1);
  510. vtSha1Free(s);
  511. }
  512. int
  513. packetCmp(Packet *pkt0, Packet *pkt1)
  514. {
  515. Frag *f0, *f1;
  516. int n0, n1, x;
  517. NOTFREE(pkt0);
  518. NOTFREE(pkt1);
  519. f0 = pkt0->first;
  520. f1 = pkt1->first;
  521. if(f0 == nil)
  522. return (f1 == nil)?0:-1;
  523. if(f1 == nil)
  524. return 1;
  525. n0 = FRAGSIZE(f0);
  526. n1 = FRAGSIZE(f1);
  527. for(;;) {
  528. if(n0 < n1) {
  529. x = memcmp(f0->wp - n0, f1->wp - n1, n0);
  530. if(x != 0)
  531. return x;
  532. n1 -= n0;
  533. f0 = f0->next;
  534. if(f0 == nil)
  535. return -1;
  536. n0 = FRAGSIZE(f0);
  537. } else if (n0 > n1) {
  538. x = memcmp(f0->wp - n0, f1->wp - n1, n1);
  539. if(x != 0)
  540. return x;
  541. n0 -= n1;
  542. f1 = f1->next;
  543. if(f1 == nil)
  544. return 1;
  545. n1 = FRAGSIZE(f1);
  546. } else { /* n0 == n1 */
  547. x = memcmp(f0->wp - n0, f1->wp - n1, n0);
  548. if(x != 0)
  549. return x;
  550. f0 = f0->next;
  551. f1 = f1->next;
  552. if(f0 == nil)
  553. return (f1 == nil)?0:-1;
  554. if(f1 == nil)
  555. return 1;
  556. n0 = FRAGSIZE(f0);
  557. n1 = FRAGSIZE(f1);
  558. }
  559. }
  560. }
  561. static Frag *
  562. fragAlloc(Packet *p, int n, int pos, Frag *next)
  563. {
  564. Frag *f, *ef;
  565. Mem *m;
  566. /* look for local frag */
  567. f = &p->local[0];
  568. ef = &p->local[NLocalFrag];
  569. for(;f<ef; f++) {
  570. if(f->state == FragLocalFree) {
  571. f->state = FragLocalAlloc;
  572. goto Found;
  573. }
  574. }
  575. lock(&freeList.lk);
  576. f = freeList.frag;
  577. if(f != nil)
  578. freeList.frag = f->next;
  579. else
  580. freeList.nfrag++;
  581. unlock(&freeList.lk);
  582. if(f == nil) {
  583. f = vtMemBrk(sizeof(Frag));
  584. f->state = FragGlobal;
  585. }
  586. Found:
  587. if(n == 0)
  588. return f;
  589. if(pos == PEnd && next == nil)
  590. pos = PMiddle;
  591. m = memAlloc(n, pos);
  592. f->mem = m;
  593. f->rp = m->rp;
  594. f->wp = m->wp;
  595. f->next = next;
  596. return f;
  597. }
  598. static Frag *
  599. fragDup(Packet *p, Frag *f)
  600. {
  601. Frag *ff;
  602. Mem *m;
  603. m = f->mem;
  604. /*
  605. * m->rp && m->wp can be out of date when ref == 1
  606. * also, potentially reclaims space from previous frags
  607. */
  608. if(m->ref == 1) {
  609. m->rp = f->rp;
  610. m->wp = f->wp;
  611. }
  612. ff = fragAlloc(p, 0, 0, nil);
  613. *ff = *f;
  614. lock(&m->lk);
  615. m->ref++;
  616. unlock(&m->lk);
  617. return ff;
  618. }
  619. static void
  620. fragFree(Frag *f)
  621. {
  622. memFree(f->mem);
  623. if(f->state == FragLocalAlloc) {
  624. f->state = FragLocalFree;
  625. return;
  626. }
  627. lock(&freeList.lk);
  628. f->next = freeList.frag;
  629. freeList.frag = f;
  630. unlock(&freeList.lk);
  631. }
  632. static Mem *
  633. memAlloc(int n, int pos)
  634. {
  635. Mem *m;
  636. int nn;
  637. if(n < 0 || n > MaxFragSize) {
  638. vtSetError(EPacketSize);
  639. return 0;
  640. }
  641. if(n <= SmallMemSize) {
  642. lock(&freeList.lk);
  643. m = freeList.smallMem;
  644. if(m != nil)
  645. freeList.smallMem = m->next;
  646. else
  647. freeList.nsmallMem++;
  648. unlock(&freeList.lk);
  649. nn = SmallMemSize;
  650. } else {
  651. lock(&freeList.lk);
  652. m = freeList.bigMem;
  653. if(m != nil)
  654. freeList.bigMem = m->next;
  655. else
  656. freeList.nbigMem++;
  657. unlock(&freeList.lk);
  658. nn = BigMemSize;
  659. }
  660. if(m == nil) {
  661. m = vtMemBrk(sizeof(Mem));
  662. m->bp = vtMemBrk(nn);
  663. m->ep = m->bp + nn;
  664. }
  665. assert(m->ref == 0);
  666. m->ref = 1;
  667. switch(pos) {
  668. default:
  669. assert(0);
  670. case PFront:
  671. m->rp = m->bp;
  672. break;
  673. case PMiddle:
  674. /* leave a little bit at end */
  675. m->rp = m->ep - n - 32;
  676. break;
  677. case PEnd:
  678. m->rp = m->ep - n;
  679. break;
  680. }
  681. /* check we did not blow it */
  682. if(m->rp < m->bp)
  683. m->rp = m->bp;
  684. m->wp = m->rp + n;
  685. assert(m->rp >= m->bp && m->wp <= m->ep);
  686. return m;
  687. }
  688. static void
  689. memFree(Mem *m)
  690. {
  691. lock(&m->lk);
  692. m->ref--;
  693. if(m->ref > 0) {
  694. unlock(&m->lk);
  695. return;
  696. }
  697. unlock(&m->lk);
  698. assert(m->ref == 0);
  699. switch(m->ep - m->bp) {
  700. default:
  701. assert(0);
  702. case SmallMemSize:
  703. lock(&freeList.lk);
  704. m->next = freeList.smallMem;
  705. freeList.smallMem = m;
  706. unlock(&freeList.lk);
  707. break;
  708. case BigMemSize:
  709. lock(&freeList.lk);
  710. m->next = freeList.bigMem;
  711. freeList.bigMem = m;
  712. unlock(&freeList.lk);
  713. break;
  714. }
  715. }
  716. static int
  717. memHead(Mem *m, uint8_t *rp, int n)
  718. {
  719. lock(&m->lk);
  720. if(m->rp != rp) {
  721. unlock(&m->lk);
  722. return 0;
  723. }
  724. m->rp -= n;
  725. unlock(&m->lk);
  726. return 1;
  727. }
  728. static int
  729. memTail(Mem *m, uint8_t *wp, int n)
  730. {
  731. lock(&m->lk);
  732. if(m->wp != wp) {
  733. unlock(&m->lk);
  734. return 0;
  735. }
  736. m->wp += n;
  737. unlock(&m->lk);
  738. return 1;
  739. }