📄 pktalloc.c
字号:
/*
* FILENAME: pktalloc.c
*
* Copyright 2000 By InterNiche Technologies Inc. All rights reserved
*
* Code to manage the queues of free packet buffers.
*
* MODULE: INET
*
* ROUTINES: pk_init(), pk_alloc(), pk_free(), pk_init(), *
* PORTABLE: yes
*/
/* Additional Copyrights: */
/* Portions Copyright 1990-1994 by NetPort Software */
/* Portions Copyright 1986 by Carnegie Mellon */
/* Portions Copyright 1984, 1985 by the Massachusetts Institute of Technology */
#include "ipport.h"
#include "q.h"
#include "netbuf.h"
#include "net.h"
#include "ip.h"
#include "minip.h" /* (yaxon add) */
#include "zprint.h"
/* We maintain 2 queues of free buffers, one for smallish packets
* like ARPs, TCP acks,and PINGs; and big buffers for large datagrams
* like FTP transfers.
*/
queue bigfreeq; /* big free buffers */
queue lilfreeq; /* small free buffers */
/* these next four values control the number and sizes of free
* buffers. The defaults below can be overwritten by the caller prior
* to calling
*/
/* define deffaults */
#ifndef NUMBIGBUFS
#define NUMBIGBUFS 30
#endif /* NUMBIGBUFS */
#ifndef NUMLILBUFS
#define NUMLILBUFS 30
#endif /* NUMLILBUFS */
#ifndef BIGBUFSIZE
#define BIGBUFSIZE 1536
#endif /* BIGBUFSIZE */
#ifndef LILBUFSIZE
#ifdef WEBPORT /* web severs send a lot of packets <> 160 bytes */
#define LILBUFSIZE 200
#else /* no Web server in this link */
#define LILBUFSIZE 128
#endif /* WEBPORT */
#endif /* LILBUFSIZE */
unsigned lilbufs = NUMLILBUFS; /* number of small bufs to init */
unsigned lilbufsiz = LILBUFSIZE; /* big enough for most non-full size packets */
unsigned bigbufs = NUMBIGBUFS; /* number of big bufs to init */
unsigned bigbufsiz = BIGBUFSIZE; /* big enough for max. ethernet packet */
#ifdef NPDEBUG
PACKET pktlog[MAXPACKETS]; /* record where the packets are */
#endif
/* FUNCTION: pk_alloc()
*
* PACKET pk_alloc(len) Returns a pointer to a netbuf structure
* (PACKET) with a buffer big enough for len bytes, or NULL if none
* is available.
*
*
* PARAM1: unsigned len
*
* RETURNS: a pointer to a netbuf structure
* (PACKET) with a buffer big enough for len bytes, or NULL if none
* is available.
*/
PACKET
pk_alloc(unsigned len)
{
PACKET p;
if (len > bigbufsiz) /* caller wants oversize buffer? */
return(NULL);
if ((len > lilbufsiz) || (lilfreeq.q_len == 0)) /* must use a big buffer */
p = (PACKET)getq(&bigfreeq);
else
p = (PACKET)getq(&lilfreeq);
if (!p)
return NULL;
p->nb_prot = p->nb_buff + MaxLnh; /* point past biggest mac header */
p->nb_plen = 0; /* no protocol data there yet */
p->net = NULL;
#ifdef NPDEBUG
if ((p->nb_blen != bigbufsiz) && (p->nb_blen != lilbufsiz))
panic("pk_alloc: illegal nb_blen size");
#endif
p->inuse = 1; /* initially buffer in use by 1 user */
return(p);
}
/* FUNCTION: pk_free()
*
* pk_free() - Return a packet to the free queue.
*
* PARAM1: PACKET pkt
*
* RETURNS: void
*/
void
pk_free(PACKET pkt) /* PACKET to place in free queue */
{
#ifdef NPDEBUG
PACKET p;
int j;
/* check if the packet is already in a freeq */
ENTER_CRIT_SECTION(&bigfreeq);
for (p=(PACKET)bigfreeq.q_head; p; p = p->next)
if (p == pkt)
{
dprintf("pk_free: buffer %p already in bigfreeq\n", pkt);
/* dtrap("pktalloc 0\n");*//* (yaxon del) */
EXIT_CRIT_SECTION(&bigfreeq);
return; /* should this be a fatal error? -later. */
}
EXIT_CRIT_SECTION(&bigfreeq);
ENTER_CRIT_SECTION(&lilfreeq);
for (p=(PACKET)lilfreeq.q_head; p; p = p->next)
if (p == pkt)
{
dprintf("pk_free: buffer %p already in lilfreeq\n", pkt);
/* dtrap("pktalloc 1\n");*//* (yaxon del) */
EXIT_CRIT_SECTION(&lilfreeq);
return; /* should this be a fatal error? -later. */
}
EXIT_CRIT_SECTION(&lilfreeq);
/* check if packet link is not zero */
if ((pkt->next) && (pkt->inuse == 1))
panic("pk_free: packet is in a queue");
if ((pkt->nb_blen != bigbufsiz) && (pkt->nb_blen != lilbufsiz))
panic("pk_free: illegal nb_blen size");
/* check for corruption of memory markers */
for(j = ALIGN_TYPE; j > 0; j--)
{
if (*(pkt->nb_buff - j) != 'M')
{
panic("pk_free: corrupt packet buffer");
}
}
#endif /* NPDEBUG */
if (pkt->inuse-- > 1) /* more than 1 owner? */
return; /* packet was cloned, don't delete yet */
if (pkt->nb_blen == bigbufsiz)
q_add(&bigfreeq, (qp)pkt);
else
q_add(&lilfreeq, (qp)pkt);
}
/* FUNCTION: pk_init()
*
* init the free queue (or queues) for use by pk_alloc() and
* pk_free() above.
*
*
* PARAM1: none
*
* RETURNS: Returns 0 if OK, else negative error code.
*/
int
pk_init()
{
PACKET packet;
unsigned i;
unsigned numpkts = bigbufs + lilbufs;
for (i = 0; i < numpkts; i++)
{
packet = (PACKET)NB_ALLOC(sizeof(struct netbuf));
if (packet == NULL)
goto no_pkt_buf;
#ifdef NPDEBUG
if (i >= MAXPACKETS)
{
dprintf("pk_init: bad define\n");
return -1;
}
pktlog[i] = packet; /* save for debugging */
#endif
packet->nb_tstamp = 0L;
if (i < bigbufs)
{
#ifdef NPDEBUG
{
int j;
/* for DEBUG compiles, bracket the data area with special chars */
packet->nb_buff = (char *)BB_ALLOC(bigbufsiz+ALIGN_TYPE+1);
if (!(packet->nb_buff))
goto no_pkt_buf;
/* Add memory markers for sanity check */
for(j = 0; j < ALIGN_TYPE; j++)
*(packet->nb_buff + j) = 'M'; /* MMs at start of buf */
*(packet->nb_buff + bigbufsiz + ALIGN_TYPE) = 'M';
packet->nb_buff += ALIGN_TYPE; /* bump buf past MMs */
}
#else
packet->nb_buff = (char *)BB_ALLOC(bigbufsiz);
#endif
if (!(packet->nb_buff))
goto no_pkt_buf;
packet->nb_blen = bigbufsiz;
q_add(&bigfreeq, packet); /* save it in big pkt free queue */
}
else /* get a small buffer */
{
#ifdef NPDEBUG
{
int j;
/* for DEBUG compiles, bracket the data area with special chars */
packet->nb_buff = (char *)LB_ALLOC(lilbufsiz+ALIGN_TYPE+1);
if (!(packet->nb_buff))
goto no_pkt_buf;
/* Add memory markers for sanity check */
for(j = 0; j < ALIGN_TYPE; j++)
*(packet->nb_buff + j) = 'M'; /* MMs at start of buf */
*(packet->nb_buff + lilbufsiz + ALIGN_TYPE) = 'M';
packet->nb_buff += ALIGN_TYPE;
}
#else
packet->nb_buff = (char *)LB_ALLOC(lilbufsiz);
#endif
if (!(packet->nb_buff))
goto no_pkt_buf;
packet->nb_blen = lilbufsiz;
q_add(&lilfreeq, packet); /* save it in little free queue */
}
}
bigfreeq.q_min = bigbufs;
lilfreeq.q_min = lilbufs;
return 0;
no_pkt_buf:
#ifdef NPDEBUG
dprintf("Netinit: calloc failed getting buffer %d\n", i);
#endif
return(-1);
}
/* end of file pktalloc.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -