mbuf.c revision 37011
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.15 1998/06/15 19:06:17 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 count;
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  u_char *p;
60  struct mbuf *bp;
61
62  if (type > MB_MAX)
63    log_Printf(LogERROR, "Bad mbuf type %d\n", type);
64  bp = (struct mbuf *) malloc(sizeof(struct mbuf));
65  if (bp == NULL) {
66    log_Printf(LogALERT, "failed to allocate memory: %u\n", sizeof(struct mbuf));
67    AbortProgram(EX_OSERR);
68  }
69  memset(bp, '\0', sizeof(struct mbuf));
70  p = (u_char *) malloc(cnt);
71  if (p == NULL) {
72    log_Printf(LogALERT, "failed to allocate memory: %d\n", cnt);
73    AbortProgram(EX_OSERR);
74  }
75  MemMap[type].count += cnt;
76  totalalloced += cnt;
77  bp->base = p;
78  bp->size = bp->cnt = cnt;
79  bp->type = type;
80  bp->pnext = NULL;
81  return (bp);
82}
83
84struct mbuf *
85mbuf_FreeSeg(struct mbuf * bp)
86{
87  struct mbuf *nbp;
88
89  if (bp) {
90    nbp = bp->next;
91    MemMap[bp->type].count -= bp->size;
92    totalalloced -= bp->size;
93    free(bp->base);
94    free(bp);
95    return (nbp);
96  }
97  return (bp);
98}
99
100void
101mbuf_Free(struct mbuf * bp)
102{
103  while (bp)
104    bp = mbuf_FreeSeg(bp);
105}
106
107struct mbuf *
108mbuf_Read(struct mbuf * bp, u_char * ptr, int len)
109{
110  int nb;
111
112  while (bp && len > 0) {
113    if (len > bp->cnt)
114      nb = bp->cnt;
115    else
116      nb = len;
117    memcpy(ptr, MBUF_CTOP(bp), nb);
118    ptr += nb;
119    bp->cnt -= nb;
120    len -= nb;
121    bp->offset += nb;
122    if (bp->cnt == 0) {
123#ifdef notdef
124      bp = bp->next;
125#else
126      bp = mbuf_FreeSeg(bp);
127#endif
128    }
129  }
130  return (bp);
131}
132
133void
134mbuf_Write(struct mbuf * bp, u_char * ptr, int cnt)
135{
136  int plen;
137  int nb;
138
139  plen = mbuf_Length(bp);
140  if (plen < cnt)
141    cnt = plen;
142
143  while (cnt > 0) {
144    nb = (cnt < bp->cnt) ? cnt : bp->cnt;
145    memcpy(MBUF_CTOP(bp), ptr, nb);
146    cnt -= bp->cnt;
147    bp = bp->next;
148  }
149}
150
151int
152mbuf_Show(struct cmdargs const *arg)
153{
154  int i;
155  static const char *mbuftype[] = {
156    "async", "fsm", "hdlcout", "ipin", "echo", "lqr", "link", "vjcomp",
157    "ipq", "mp" };
158
159  for (i = 1; i < MB_MAX; i += 2)
160    prompt_Printf(arg->prompt, "%10.10s: %04d\t%10.10s: %04d\n",
161	    mbuftype[i-1], MemMap[i].count, mbuftype[i], MemMap[i+1].count);
162
163  if (i == MB_MAX)
164    prompt_Printf(arg->prompt, "%10.10s: %04d\n",
165                  mbuftype[i-1], MemMap[i].count);
166
167  return 0;
168}
169
170void
171mbuf_Log()
172{
173  log_Printf(LogDEBUG, "mbuf_Log: mem alloced: %d\n", totalalloced);
174  log_Printf(LogDEBUG, "mbuf_Log:  1: %d  2: %d   3: %d   4: %d\n",
175	MemMap[1].count, MemMap[2].count, MemMap[3].count, MemMap[4].count);
176  log_Printf(LogDEBUG, "mbuf_Log:  5: %d  6: %d   7: %d   8: %d\n",
177	MemMap[5].count, MemMap[6].count, MemMap[7].count, MemMap[8].count);
178  log_Printf(LogDEBUG, "mbuf_Log:  9: %d 10: %d\n",
179	MemMap[9].count, MemMap[10].count);
180}
181
182struct mbuf *
183mbuf_Dequeue(struct mqueue *q)
184{
185  struct mbuf *bp;
186
187  log_Printf(LogDEBUG, "mbuf_Dequeue: queue len = %d\n", q->qlen);
188  bp = q->top;
189  if (bp) {
190    q->top = q->top->pnext;
191    q->qlen--;
192    if (q->top == NULL) {
193      q->last = q->top;
194      if (q->qlen)
195	log_Printf(LogERROR, "mbuf_Dequeue: Not zero (%d)!!!\n", q->qlen);
196    }
197  }
198
199  return bp;
200}
201
202void
203mbuf_Enqueue(struct mqueue *queue, struct mbuf *bp)
204{
205  if (queue->last) {
206    queue->last->pnext = bp;
207    queue->last = bp;
208  } else
209    queue->last = queue->top = bp;
210  queue->qlen++;
211  log_Printf(LogDEBUG, "mbuf_Enqueue: len = %d\n", queue->qlen);
212}
213