mbuf.c revision 45103
1/* 2 * PPP Memory handling module 3 * 4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5 * 6 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 7 * 8 * Redistribution and use in source and binary forms are permitted 9 * provided that the above copyright notice and this paragraph are 10 * duplicated in all such forms and that any documentation, 11 * advertising materials, and other materials related to such 12 * distribution and use acknowledge that the software was developed 13 * by the Internet Initiative Japan, Inc. The name of the 14 * IIJ may not be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 * 20 * $Id: mbuf.c,v 1.23 1999/02/06 02:54:47 brian Exp $ 21 * 22 */ 23#include <sys/types.h> 24 25#include <stdio.h> 26#include <stdlib.h> 27#include <string.h> 28#include <sysexits.h> 29#include <termios.h> 30 31#include "defs.h" 32#include "command.h" 33#include "mbuf.h" 34#include "log.h" 35#include "descriptor.h" 36#include "prompt.h" 37#include "main.h" 38 39static struct memmap { 40 struct mbuf *queue; 41 int fragments, octets; 42} MemMap[MB_MAX + 2]; 43 44static int totalalloced; 45 46int 47mbuf_Length(struct mbuf * bp) 48{ 49 int len; 50 51 for (len = 0; bp; bp = bp->next) 52 len += bp->cnt; 53 return (len); 54} 55 56struct mbuf * 57mbuf_Alloc(int cnt, int type) 58{ 59 struct mbuf *bp; 60 61 if (type > MB_MAX) 62 log_Printf(LogERROR, "Bad mbuf type %d\n", type); 63 bp = malloc(sizeof(struct mbuf) + cnt); 64 if (bp == NULL) { 65 log_Printf(LogALERT, "failed to allocate memory: %ld\n", 66 (long)sizeof(struct mbuf)); 67 AbortProgram(EX_OSERR); 68 } 69 memset(bp, '\0', sizeof(struct mbuf)); 70 MemMap[type].fragments++; 71 MemMap[type].octets += cnt; 72 totalalloced += cnt; 73 bp->size = bp->cnt = cnt; 74 bp->type = type; 75 return bp; 76} 77 78struct mbuf * 79mbuf_FreeSeg(struct mbuf * bp) 80{ 81 struct mbuf *nbp; 82 83 if (bp) { 84 nbp = bp->next; 85 MemMap[bp->type].fragments--; 86 MemMap[bp->type].octets -= bp->size; 87 totalalloced -= bp->size; 88 free(bp); 89 bp = nbp; 90 } 91 92 return bp; 93} 94 95void 96mbuf_Free(struct mbuf * bp) 97{ 98 while (bp) 99 bp = mbuf_FreeSeg(bp); 100} 101 102struct mbuf * 103mbuf_Read(struct mbuf * bp, u_char * ptr, int len) 104{ 105 int nb; 106 107 while (bp && len > 0) { 108 if (len > bp->cnt) 109 nb = bp->cnt; 110 else 111 nb = len; 112 memcpy(ptr, MBUF_CTOP(bp), nb); 113 ptr += nb; 114 bp->cnt -= nb; 115 len -= nb; 116 bp->offset += nb; 117 if (bp->cnt == 0) 118 bp = mbuf_FreeSeg(bp); 119 } 120 return (bp); 121} 122 123void 124mbuf_Write(struct mbuf * bp, u_char * ptr, int cnt) 125{ 126 int plen; 127 int nb; 128 129 plen = mbuf_Length(bp); 130 if (plen < cnt) 131 cnt = plen; 132 133 while (cnt > 0) { 134 nb = (cnt < bp->cnt) ? cnt : bp->cnt; 135 memcpy(MBUF_CTOP(bp), ptr, nb); 136 cnt -= bp->cnt; 137 bp = bp->next; 138 } 139} 140 141int 142mbuf_Show(struct cmdargs const *arg) 143{ 144 int i; 145 static const char *mbuftype[] = { 146 "async", "fsm", "cbcp", "hdlcout", "ipin", "echo", "lqr", "link", 147 "vjcomp", "ipq", "mp" }; 148 149 prompt_Printf(arg->prompt, "Fragments (octets) in use:\n"); 150 for (i = 1; i < MB_MAX; i += 2) 151 prompt_Printf(arg->prompt, "%10.10s: %04d (%06d)\t%10.10s: %04d (%06d)\n", 152 mbuftype[i-1], MemMap[i].fragments, MemMap[i].octets, mbuftype[i], 153 MemMap[i+1].fragments, MemMap[i+1].octets); 154 155 if (i == MB_MAX) 156 prompt_Printf(arg->prompt, "%10.10s: %04d (%06d)\n", 157 mbuftype[i-1], MemMap[i].fragments, MemMap[i].octets); 158 159 return 0; 160} 161 162void 163mbuf_Log() 164{ 165 log_Printf(LogDEBUG, "mbuf_Log: mem alloced: %d\n", totalalloced); 166 log_Printf(LogDEBUG, "mbuf_Log: 1: %d 2: %d 3: %d 4: %d\n", 167 MemMap[1].octets, MemMap[2].octets, MemMap[3].octets, MemMap[4].octets); 168 log_Printf(LogDEBUG, "mbuf_Log: 5: %d 6: %d 7: %d 8: %d\n", 169 MemMap[5].octets, MemMap[6].octets, MemMap[7].octets, MemMap[8].octets); 170 log_Printf(LogDEBUG, "mbuf_Log: 9: %d 10: %d 11: %d\n", 171 MemMap[9].octets, MemMap[10].octets, MemMap[11].octets); 172} 173 174struct mbuf * 175mbuf_Dequeue(struct mqueue *q) 176{ 177 struct mbuf *bp; 178 179 log_Printf(LogDEBUG, "mbuf_Dequeue: queue len = %d\n", q->qlen); 180 bp = q->top; 181 if (bp) { 182 q->top = q->top->pnext; 183 q->qlen--; 184 if (q->top == NULL) { 185 q->last = q->top; 186 if (q->qlen) 187 log_Printf(LogERROR, "mbuf_Dequeue: Not zero (%d)!!!\n", q->qlen); 188 } 189 bp->pnext = NULL; 190 } 191 192 return bp; 193} 194 195void 196mbuf_Enqueue(struct mqueue *queue, struct mbuf *bp) 197{ 198 if (queue->last) { 199 queue->last->pnext = bp; 200 queue->last = bp; 201 } else 202 queue->last = queue->top = bp; 203 queue->qlen++; 204 log_Printf(LogDEBUG, "mbuf_Enqueue: len = %d\n", queue->qlen); 205} 206 207struct mbuf * 208mbuf_Contiguous(struct mbuf *bp) 209{ 210 /* Put it all in one contigous (aligned) mbuf */ 211 212 if (bp->next != NULL) { 213 struct mbuf *nbp; 214 u_char *cp; 215 216 nbp = mbuf_Alloc(mbuf_Length(bp), bp->type); 217 218 for (cp = MBUF_CTOP(nbp); bp; bp = mbuf_FreeSeg(bp)) { 219 memcpy(cp, MBUF_CTOP(bp), bp->cnt); 220 cp += bp->cnt; 221 } 222 bp = nbp; 223 } 224#ifndef __i386__ /* Do any other archs not care about alignment ? */ 225 else if ((bp->offset & 0x03) != 0) { 226 bcopy(MBUF_CTOP(bp), bp + 1, bp->cnt); 227 bp->offset = 0; 228 } 229#endif 230 231 return bp; 232} 233