File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / mbuf.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 08:44:29 2013 UTC (10 years, 11 months ago) by misho
Branches: mpd, MAIN
CVS tags: v5_8p1_cross, v5_8p1, v5_8, v5_7p0, v5_7, v5_6, HEAD
5.7

    1: 
    2: /*
    3:  * mbuf.c
    4:  *
    5:  * Written by Toshiharu OHNO <tony-o@iij.ad.jp>
    6:  * Copyright (c) 1993, Internet Initiative Japan, Inc. All rights reserved.
    7:  * See ``COPYRIGHT.iij''
    8:  * 
    9:  * Rewritten by Archie Cobbs <archie@freebsd.org>
   10:  * Copyright (c) 1995-1999 Whistle Communications, Inc. All rights reserved.
   11:  * See ``COPYRIGHT.whistle''
   12:  */
   13: 
   14: #include "ppp.h"
   15: 
   16: /*
   17:  * Malloc()
   18:  *
   19:  * Replacement for the usual malloc()
   20:  */
   21: 
   22: void *
   23: Malloc(const char *type, size_t size)
   24: {
   25:     const char	**memory;
   26: 
   27:     if ((memory = MALLOC(type, sizeof(char *) + size)) == NULL) {
   28: 	Perror("Malloc: malloc");
   29: 	DoExit(EX_ERRDEAD);
   30:     }
   31: 
   32:     memory[0] = type;
   33:     bzero(memory + 1, size);
   34:     return (memory + 1);
   35: }
   36: 
   37: /*
   38:  * Mdup()
   39:  *
   40:  * Malloc() + memcpy()
   41:  */
   42: 
   43: void *
   44: Mdup(const char *type, const void *src, size_t size)
   45: {
   46:     const char	**memory;
   47:     if ((memory = MALLOC(type, sizeof(char *) + size)) == NULL) {
   48: 	Perror("Mdup: malloc");
   49: 	DoExit(EX_ERRDEAD);
   50:     }
   51: 
   52:     memory[0] = type;
   53:     memcpy(memory + 1, src, size);
   54:     return(memory + 1);
   55: }
   56: 
   57: void *
   58: Mstrdup(const char *type, const void *src)
   59: {
   60:     return (Mdup(type, src, strlen(src) + 1));
   61: }
   62: 
   63: /*
   64:  * Freee()
   65:  *
   66:  * Replacement for the ususal free()
   67:  */
   68: 
   69: void
   70: Freee(void *ptr)
   71: {
   72:     if (ptr) {
   73: 	char	**memory = ptr;
   74: 	memory--;
   75: 	FREE(memory[0], memory);
   76:     }
   77: }
   78: 
   79: /*
   80:  * mballoc()
   81:  *
   82:  * Allocate an mbuf with memory
   83:  */
   84: 
   85: Mbuf
   86: mballoc(int size)
   87: {
   88:     u_char	*memory;
   89:     int		amount, osize;
   90:     Mbuf	bp;
   91: 
   92:     assert(size >= 0);
   93: 
   94:     if (size == 0) {
   95: 	osize = 64 - sizeof(*bp);
   96:     } else if (size < 512)
   97: 	osize = ((size - 1) / 32 + 1) * 64 - sizeof(*bp);
   98:     else
   99: 	osize = ((size - 1) / 64 + 1) * 64 + 512 - sizeof(*bp);
  100:     amount = sizeof(*bp) + osize;
  101: 
  102:     if ((memory = MALLOC(MB_MBUF, amount)) == NULL) {
  103: 	Perror("mballoc: malloc");
  104: 	DoExit(EX_ERRDEAD);
  105:     }
  106: 
  107:     /* Put mbuf at front of memory region */
  108:     bp = (Mbuf)(void *)memory;
  109:     bp->size = osize;
  110:     bp->offset = (osize - size) / 2;
  111:     bp->cnt = 0;
  112: 
  113:     return (bp);
  114: }
  115: 
  116: /*
  117:  * mbfree()
  118:  *
  119:  * Free head of chain, return next
  120:  */
  121: 
  122: void
  123: mbfree(Mbuf bp)
  124: {
  125:     if (bp)
  126: 	FREE(MB_MBUF, bp);
  127: }
  128: 
  129: /*
  130:  * mbread()
  131:  *
  132:  * Read contents of an mbuf chain into buffer, consuming len bytes.
  133:  * If all of the chain is consumed, return NULL.
  134:  *
  135:  * This should ALWAYS be called like this:
  136:  *	bp = mbread(bp, ... );
  137:  */
  138: 
  139: Mbuf
  140: mbread(Mbuf bp, void *buf, int cnt)
  141: {
  142:     int nread;
  143: 
  144:     assert(cnt >= 0);
  145: 
  146:     if (!bp)
  147: 	return (NULL);
  148:     if (cnt > bp->cnt)
  149: 	nread = bp->cnt;
  150:     else
  151:         nread = cnt;
  152:     memcpy(buf, MBDATAU(bp), nread);
  153:     bp->offset += nread;
  154:     bp->cnt -= nread;
  155:     if (bp->cnt == 0) {
  156:     	mbfree(bp);
  157: 	return (NULL);
  158:     }
  159:     return(bp);
  160: }
  161: 
  162: /*
  163:  * mbcopy()
  164:  *
  165:  * Copy contents of an mbuf chain into buffer, up to "cnt" bytes.
  166:  * This does not consume any of the mbuf chain. Returns number copied.
  167:  */
  168: 
  169: int
  170: mbcopy(Mbuf bp, int offset, void *buf, int cnt)
  171: {
  172:     int nread;
  173: 
  174:     assert(offset >= 0);
  175:     assert(cnt >= 0);
  176: 
  177:     if (!bp)
  178: 	return (0);
  179:     if (offset >= bp->cnt)
  180: 	return (0);
  181: 
  182:     if (cnt > bp->cnt - offset)
  183: 	nread = bp->cnt - offset;
  184:     else
  185:         nread = cnt;
  186:     memcpy(buf, MBDATAU(bp) + offset, nread);
  187:     return (nread);
  188: }
  189: 
  190: /*
  191:  * mbcopyback()
  192:  *
  193:  * Write bytes from buffer into an mbuf chain. Returns first argument.
  194:  */
  195: 
  196: Mbuf
  197: mbcopyback(Mbuf bp, int offset, const void *buf, int cnt)
  198: {
  199:     int		b, e;
  200: 
  201:     if (!bp) {
  202: 	if (offset < 0)
  203: 	    offset = 0;
  204: 	bp = mballoc(offset + cnt);
  205: 	memcpy(MBDATAU(bp) + offset, buf, cnt);
  206: 	bp->cnt = offset + cnt;
  207: 	return (bp);
  208:     }
  209: 
  210:     b = (offset > 0) ? 0 : -offset;
  211:     e = (offset + cnt > bp->cnt) ? offset + cnt - bp->cnt : 0;
  212:     
  213:     if (b + bp->cnt + e > bp->size) {
  214: 	Mbuf	nbp = mballoc(b + bp->cnt + e);
  215: 	memcpy(MBDATAU(nbp) + b, MBDATAU(bp), bp->cnt);
  216: 	nbp->cnt = bp->cnt;
  217: 	mbfree(bp);
  218: 	bp = nbp;
  219:     } else if ((b > bp->offset) || (bp->offset + bp->cnt + e > bp->size)) {
  220: 	int	noff = (bp->size - (b + bp->cnt + e)) / 2;
  221: 	memmove(MBDATAU(bp) - bp->offset + noff + b, MBDATAU(bp), bp->cnt);
  222: 	bp->offset = noff;
  223:     } else {
  224: 	bp->offset -= b;
  225:     }
  226:     bp->cnt = b + bp->cnt + e;
  227:     memcpy(MBDATAU(bp) + offset + b, buf, cnt);
  228:     return(bp);
  229: }
  230: 
  231: /*
  232:  * mbtrunc()
  233:  *
  234:  * Truncate mbuf to total of "max" bytes. If max is zero
  235:  * then a zero length mbuf is returned (rather than a NULL mbuf).
  236:  */
  237: 
  238: Mbuf
  239: mbtrunc(Mbuf bp, int max)
  240: {
  241:     assert(max >= 0);
  242: 
  243:     if (!bp)
  244: 	return (NULL);
  245: 
  246:     if (bp->cnt > max)
  247: 	bp->cnt = max;
  248: 
  249:     return (bp);
  250: }
  251: 
  252: /*
  253:  * mbadj()
  254:  *
  255:  * Truncate mbuf cutting "cnt" bytes from begin or end.
  256:  */
  257: 
  258: Mbuf
  259: mbadj(Mbuf bp, int cnt)
  260: {
  261:     if (!bp)
  262: 	return (NULL);
  263: 
  264:     if (cnt >= 0) {
  265: 	if (bp->cnt > cnt) {
  266: 	    bp->cnt -= cnt;
  267: 	    bp->offset += cnt;
  268: 	} else {
  269: 	    bp->cnt = 0;
  270: 	}
  271:     } else {
  272: 	if (bp->cnt > -cnt) {
  273: 	    bp->cnt -= -cnt;
  274: 	} else {
  275: 	    bp->cnt = 0;
  276: 	}
  277:     }
  278: 
  279:     return (bp);
  280: }
  281: 
  282: /*
  283:  * mbsplit()
  284:  *
  285:  * Break an mbuf chain after "cnt" bytes.
  286:  * Return the newly created mbuf chain that
  287:  * starts after "cnt" bytes. If MBLEN(bp) <= cnt,
  288:  * then returns NULL.  The first part of
  289:  * the chain remains pointed to by "bp".
  290:  */
  291: 
  292: Mbuf
  293: mbsplit(Mbuf bp, int cnt)
  294: {
  295:     Mbuf	nbp;
  296:     
  297:     assert(cnt >= 0);
  298: 
  299:     if (!bp)
  300: 	return (NULL);
  301: 
  302:     if (MBLEN(bp) <= cnt)
  303: 	return (NULL);
  304: 
  305:     nbp = mballoc(bp->cnt - cnt);
  306:     memcpy(MBDATAU(nbp), MBDATAU(bp) + cnt, bp->cnt - cnt);
  307:     nbp->cnt = bp->cnt - cnt;
  308:     bp->cnt = cnt;
  309: 
  310:     return(nbp);
  311: }
  312: 
  313: /*
  314:  * MemStat()
  315:  */
  316: 
  317: int
  318: MemStat(Context ctx, int ac, char *av[], void *arg)
  319: {
  320:     struct typed_mem_stats stats;
  321:     u_int	i;
  322:     u_int	total_allocs = 0;
  323:     u_int	total_bytes = 0;
  324: 
  325:     if (typed_mem_usage(&stats))
  326: 	Error("typed_mem_usage() error");
  327:     
  328:     /* Print header */
  329:     Printf("   %-28s %10s %10s\r\n", "Type", "Count", "Total");
  330:     Printf("   %-28s %10s %10s\r\n", "----", "-----", "-----");
  331: 
  332:     for (i = 0; i < stats.length; i++) {
  333: 	struct typed_mem_typestats *type = &stats.elems[i];
  334: 
  335: 	Printf("   %-28s %10u %10lu\r\n",
  336: 	    type->type, (int)type->allocs, (u_long)type->bytes);
  337: 	total_allocs += type->allocs;
  338: 	total_bytes += type->bytes;
  339:     }
  340:     /* Print totals */
  341:     Printf("   %-28s %10s %10s\r\n", "", "-----", "-----");
  342:     Printf("   %-28s %10lu %10lu\r\n",
  343:         "Totals", total_allocs, total_bytes);
  344: 
  345:     structs_free(&typed_mem_stats_type, NULL, &stats);
  346:     return(0);
  347: }
  348: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>