TheNetNode-CB/src/buffer.c

837 lines
37 KiB
C
Executable File

/************************************************************************/
/* */
/* ***** ***** */
/* ***** ***** */
/* ***** ***** */
/* ***** ***** */
/* *************** *************** */
/* ***************** ***************** */
/* *************** *************** */
/* ***** ***** TheNetNode */
/* ***** ***** Portable */
/* ***** ***** Network */
/* ***** ***** Software */
/* */
/* File src/buffer.c (maintained by: DF6LN) */
/* */
/* This file is part of "TheNetNode" - Software Package */
/* */
/* Copyright (C) 1998 - 2008 NORD><LINK e.V. Braunschweig */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the NORD><LINK ALAS (Allgemeine Lizenz fuer */
/* Amateurfunk Software) as published by Hans Georg Giese (DF2AU) */
/* on 13/Oct/1992; either version 1, or (at your option) any later */
/* version. */
/* */
/* This program is distributed WITHOUT ANY WARRANTY only for further */
/* development and learning purposes. See the ALAS (Allgemeine Lizenz */
/* fuer Amateurfunk Software). */
/* */
/* You should have received a copy of the NORD><LINK ALAS (Allgemeine */
/* Lizenz fuer Amateurfunk Software) along with this program; if not, */
/* write to NORD><LINK e.V., Hinter dem Berge 5, D-38108 Braunschweig */
/* */
/* Dieses Programm ist PUBLIC DOMAIN, mit den Einschraenkungen durch */
/* die ALAS (Allgemeine Lizenz fuer Amateurfunk Software), entweder */
/* Version 1, veroeffentlicht von Hans Georg Giese (DF2AU), */
/* am 13.Oct.1992, oder (wenn gewuenscht) jede spaetere Version. */
/* */
/* Dieses Programm wird unter Haftungsausschluss vertrieben, aus- */
/* schliesslich fuer Weiterentwicklungs- und Lehrzwecke. Naeheres */
/* koennen Sie der ALAS (Allgemeine Lizenz fuer Amateurfunk Software) */
/* entnehmen. */
/* */
/* Sollte dieser Software keine ALAS (Allgemeine Lizenz fuer Amateur- */
/* funk Software) beigelegen haben, wenden Sie sich bitte an */
/* NORD><LINK e.V., Hinter dem Berge 5, D-38108 Braunschweig */
/* */
/************************************************************************/
#include "tnn.h"
#ifdef BUFFER_DEBUG
static void bufstat(void);
#endif
#ifdef INSANE_BUFFER_DEBUG
static void MBPTRCHECK(MBHEAD *);
#endif
static char huge *minmem(void);
static char huge *maxmem(void);
/************************************************************************\
* *
* "initialize head" *
* *
* Listenkopf, auf den hd zeigt, initialisieren : *
* *
* *
* +----------------------+ *
* | +------------------+ | *
* | | | | *
* +--------+ v v +--------+ | | *
* hd --->| | -> hd ------->| |-----+ | *
* +--------+ +--------+ | *
* | | | |-------+ *
* +--------+ +--------+ *
* | | | | *
* *
\************************************************************************/
void
inithd(LHEAD *hd)
{
hd->head = hd->tail = hd;
}
/************************************************************************/
/* Anfang des freien Speichers */
/*----------------------------------------------------------------------*/
static char huge *
minmem(void)
{
return (RAMBOT);
}
/************************************************************************/
/* Ende des freien Speichers */
/*----------------------------------------------------------------------*/
static char huge *
maxmem(void)
{
return (RAMTOP);
}
/************************************************************************/
/* Buffer-Verwaltung initialisieren. */
/*----------------------------------------------------------------------*/
void
init_buffers(void)
{
MAX_BUFFER huge *actbp;
ULONG n;
nmblks = nmbfre = nmblks_max = 0;
actbp = (MAX_BUFFER *)minmem();
n = (ULONG)((maxmem() - minmem()) / sizeof(MAX_BUFFER));
#ifdef __WIN32__
nmbfre_max = (unsigned short)n;
#else
nmbfre_max = n;
#endif /* WIN32 */
while (n--)
{
#ifdef BUFFER_DEBUG
((MBHEAD *)actbp)->owner = ALLOC_LEHEAD;
#endif
dealoc((MBHEAD *)actbp++);
}
nmbfre_min = nmbfre;
}
/************************************************************************\
* *
* action : Element aus Liste aushaengen. *
* *
* *
* le ---+ *
* vor | raus hinter *
* +--------+ +-->+--------+ +--------+ *
* ----->| |--------->| prevle |--------->| |-----> *
* +--------+ +--------+ +--------+ *
* <-----| |<---------| nextle |<---------| |<----- *
* +--------+ +--------+ +--------+ *
* | | | | | | *
* *
* *
* \/ *
* *
* *
* raus vor hinter *
* +--------+ +--------+ +--------+ *
* le --->| nextle | ----->| |----->| |-----> *
* +--------+ +--------+ +--------+ *
* | prevle | <-----| |<-----| |<----- *
* +--------+ +--------+ +--------+ *
* | | | | | | *
* *
* *
************************************************************************
* *
* parameter : le - Zeiger auf auszuhaengendes Listenelement *
* *
* returns : le *
* *
\************************************************************************/
LEHEAD *
ulink(LEHEAD *le)
{
le->prevle->nextle = le->nextle; /* Hinliste ohne le */
le->nextle->prevle = le->prevle; /* Rueckliste ohne le */
return (le); /* Zeiger auf das Element zurueck */
}
/************************************************************************\
* *
* action : Element in Liste einhaengen. *
* *
* *
* neu vor hinter *
* +--------+ +--------+ +--------+ *
* new --->| nextle | pred --->| |----->| |-----> *
* +--------+ +--------+ +--------+ *
* | prevle | <-----| |<-----| |<----- *
* +--------+ +--------+ +--------+ *
* | | | | | | *
* *
* *
* \/ *
* *
* *
* new ---+ *
* vor | neu hinter *
* +--------+ +-->+--------+ +--------+ *
* pred --->| |--------->| prevle |--------->| |-----> *
* +--------+ +--------+ +--------+ *
* <-----| |<---------| nextle |<---------| |<----- *
* +--------+ +--------+ +--------+ *
* | | | | | | *
* *
* *
************************************************************************
* *
* parameter : new - Zeiger auf einzuhaengendes Listenelement *
* pred - Zeiger auf Listenelement, hinter dem new *
* eingehaengt werden soll *
* *
* returns : new *
* *
\************************************************************************/
LEHEAD *
relink(LEHEAD *new, LEHEAD *pred)
{
new->nextle = pred->nextle; /* Vorzeiger im neuen Element */
new->prevle = pred; /* Rueckzeiger im neuen Element */
new->nextle->prevle = new; /* Rueckzeiger dahinter */
pred->nextle = new; /* Vorzeiger davor */
return (new); /* Zeiger auf neues Element */
}
/************************************************************************\
* *
* action : "allocate buffer" *
* *
* Leeren Buffer aus der Freiliste holen, Programmneustart *
* wenn keine Buffer mehr in Freiliste. *
* *
************************************************************************
* *
* r/w globals : nmbfre - Anzahl der Buffer in Freiliste freel *
* freel - verkettete Liste der freien Buffer *
* *
* locals : s.u. *
* *
* returns : Zeiger auf freien Buffer, fall vorhanden *
* *
\************************************************************************/
LEHEAD *
#ifdef BUFFER_DEBUG
allocb(int owner)
#else
allocb(void)
#endif
{
LEHEAD *ret; /* Buffer Rueckgabewert */
nmbfre--; /* 1 Buffer weniger */
if (nmbfre < nmbfre_min)
nmbfre_min = nmbfre;
if (!nmbfre) /* wenn nicht genug frei */
{
#ifdef BUFFER_DEBUG
bufstat(); /* Buffernutzung protokollieren */
#endif
HALT("allocb: no free buffers !"); /* dann Rechner neu starten.. */
}
ret = ulink((LEHEAD *)freel.head); /* Buffer aus Liste aushaengen */
#ifdef BUFFER_DEBUG
if (ret->owner != ALLOC_NO_OWNER)
{
bufstat(); /* Buffernutzung protokollieren */
HALT("allocb: buffer with owner in free-list !");
}
ret->owner = (UBYTE)owner;
#endif
return (ret); /* Zeiger auf Freibuffer zurueck */
}
/************************************************************************\
* *
* "deallocate" *
* *
* Buffer, auf den bp zeigt, initialisieren als neuen Messagebufferhead *
* (rwndmb()) und deallokieren, d.h. in die Freiliste freel einhaengen *
* und den Freibufferzaehler nmbfre inkrementieren. *
* *
* *
* +--------+ *
* bp --->| | deallokieren *
* +--------+ *
* | | *
* +--------+ *
* | | *
* *
\************************************************************************/
void
dealoc(MBHEAD *bp)
{
#ifdef INSANE_BUFFER_DEBUG
MBPTRCHECK(bp);
#endif
bp->mbl.head = /* als Messagehead initialisieren */
bp->mbl.tail = /* Bufferlistenkopf */
&bp->mbl; /* initialisieren */
bp->mbpc = 0; /* Message leer */
bp->mbgc = 0; /* Rest initialisieren */
bp->mbbp = NULL;
#ifdef BUFFER_DEBUG
if (bp->owner != ALLOC_NO_OWNER)
bp->owner = ALLOC_NO_OWNER;
else
HALT("dealoc: buffer with no owner !"); /* Rechner neu starten.. */
#endif
rwndmb(bp); /* Buffer an Freiliste anhaengen */
relink((LEHEAD *)bp, (LEHEAD *)freel.tail);
++nmbfre; /* 1 Freibuffer mehr */
if (nmbfre > nmbfre_max) /* > nmbfre_max darf nicht sein! */
HALT("dealoc: more buffers free than allocated !"); /* neu starten */
}
/************************************************************************\
* *
* "deallocate message buffer" *
* *
* Einen kompletten Messagespeicher, auf dessen Kopf mbhd zeigt, *
* deallokieren, d.h. sowohl den Messagebufferhead als auch alle an *
* dessen Messagebufferliste haengende Datenbuffer deallokieren. *
* *
* *
* +--------+ deallokieren *
* mbhd -->| | *
* +--------+ *
* | | *
* +--------+ +--------+ +--------+ *
* a --->| |----->| |---> --->| |---> a *
* + mbl + +--------+ ... +--------+ *
* b <---| |<-----| |<--- <---| |<--- b *
* +--------+ +--------+ +--------+ *
* | | | | | | *
* *
\************************************************************************/
void
dealmb(MBHEAD *mbhd)
{
MB *bp; /* Datenbufferzeiger */
#ifdef INSANE_BUFFER_DEBUG
MBPTRCHECK(mbhd);
#endif
/* alle Datenbuffer */
while ((bp = (MB *)mbhd->mbl.head) != (MB *)&mbhd->mbl)
dealoc((MBHEAD *)ulink((LEHEAD *)bp));
dealoc(mbhd); /* Am Ende den Kopf */
}
/************************************************************************\
* *
* "deallocate message list" *
* *
* Komplette Messageliste, auf deren Listenkopf mlp zeigt, deallokieren. *
* D.h. alle Messagespeicher (jeweils Kopf und daran haengende *
* Datenbuffer) deallokieren. *
* *
* *
* +--------+ +--------+ +--------+ *
* mlp --->| head |--->| |---> --->| |---> mlp *
* +--------+ +--------+ ... +--------+ *
* b <---| tail |<---| |<--- <---| |<--- b *
* +--------+ +--------+ +--------+ *
* | |---> \ | |---> \ *
* + + | + + | *
* | |<--- /| | |<--- /| *
* +--------+ | +--------+ | *
* | | | | | | *
* | | *
* deallokieren |------------------------| *
* siehe unten dealmb() *
* *
\************************************************************************/
/*#include "coredump.c" */
void
dealml(LEHEAD *mlp)
{
MBHEAD *bp; /* Zeiger auf Messagebufferhead */
#if 0
int i;
for (bp = (MBHEAD *)mlp->nextle, i = 0;
bp != (MBHEAD *)mlp;
bp = (MBHEAD *)bp->nextmh)
if (++i > 10000)
{ /* Fehler !!! */
coredump();
i = *((char *)NULL); /* Zugriff auf NULL-Pointer */
exit(-1); /* notfalls normaler exit */
}
#endif
LOOP /* fuer alle Messagebufferheads */
{ /* in Messagespeicherliste : */
bp = (MBHEAD *)mlp->nextle; /* Zeiger auf naechsten Msgbhead */
if (mlp == (LEHEAD *)bp) /* Schwanz beisst Kopf -> fertig */
break; /* sonst Messagespeicher deallok. */
dealmb((MBHEAD *)ulink((LEHEAD *)bp));
}
}
/************************************************************************\
* *
* action : "rewind message buffer" *
* *
* Message-Buffer (Kopf und Datenbufferliste) zuruecksetzen. *
* Get-Counter auf 0 setzen, Buffer-Pointer so setzen, dass *
* beim naechsten getchr() auf das das erste Datenbyte des *
* ersten Datenbuffers zugegriffen wird. *
* (Dies muss wie folgt geschehen, da der Get-Counter in *
* jedem Fall auf 0 stehen muss und in getchr() auf % 32 *
* fuer das Positionieren auf den naechsten Datenbuffer *
* abgetestet wird.) *
* *
************************************************************************
* *
* parameter : mbhd - Zeiger auf Kopf des Message-Buffers *
* *
\************************************************************************/
void
rwndmb(MBHEAD *mbhd)
{
#ifdef INSANE_BUFFER_DEBUG
MBPTRCHECK(mbhd);
#endif
/* Kopf wie Datenbufferende */
mbhd->mbbp = (char *)(((MAX_BUFFER huge *)&(mbhd->mbl)) + 1);
mbhd->mbgc = 0; /* Bufferanfang */
}
/************************************************************************\
* *
* action : "put character" *
* *
* Zeichen in Messagebuffer schreiben, Put-Counter erhoehen *
* und Buffer-Pointer setzen. Ist der aktuelle Datenbuffer *
* im Messagebuffer voll, dann neuen Datenbuffer allokieren *
* und ans Datenbufferlistenende des Messagebuffers *
* anhaengen. *
* *
************************************************************************
* *
* parameter : ch - in den Buffer zu schreibendes Zeichen *
* mbhd - Zeiger auf den Messagebuffer-Kopf, in den ch *
* zu schreiben ist *
* *
* r/o globals: - *
* *
* r/w globals: - *
* *
* locals : - *
* *
* returns : - *
* *
\************************************************************************/
void
putchr(char ch, MBHEAD *mbhd)
{
#ifdef INSANE_BUFFER_DEBUG
MBPTRCHECK(mbhd);
#endif
if (mbhd->mbpc++ % sizeof_MBDATA == 0)
mbhd->mbbp = ((MB *)(relink((LEHEAD *)allocb(ALLOC_LEHEAD),
(LEHEAD *)mbhd->mbl.tail)))->data;
*mbhd->mbbp++ = ch;
}
/************************************************************************\
* *
* action : "get character" *
* *
* Zeichen aus einem Messagebuffer holen. Datenbuffer-Poiner *
* setzen und Get-Count erhoehen. Uebergang in der *
* Datenbufferliste vom Ende eines Datenbuffers zum *
* naechsten ausfuehren. *
* *
************************************************************************
* *
* parameter : mbhd - Zeiger auf Kopf des Messagebuffers, aus dem *
* das Zeichen gelesen werden soll *
* *
* r/o globals: - *
* *
* r/w globals: - *
* *
* locals : - *
* *
* returns : aus dem Buffer gelesenes Zeichen *
* *
\************************************************************************/
#ifdef __WIN32__
unsigned char
#else
char
#endif /* WIN32 */
getchr(MBHEAD *mbhd)
{
#ifdef INSANE_BUFFER_DEBUG
MBPTRCHECK(mbhd);
#endif
if (mbhd->mbgc++ % sizeof_MBDATA == 0)
mbhd->mbbp = ((MB *)((MAX_BUFFER huge *)(mbhd->mbbp) - 1))->nextmb->data;
return (*mbhd->mbbp++);
}
#ifndef MC68K
/************************************************************************
* Function : 16 Bits aus einem Buffer lesen
*
* Inputs : Zeiger auf den Buffer
*
* Returns : unsigned integer
*
* Operation : Liest 2 Bytes und vertauscht sie
*----------------------------------------------------------------------*/
UWORD
get16(MBHEAD *mbhd)
{
UWORD retval;
#ifdef INSANE_BUFFER_DEBUG
MBPTRCHECK(mbhd);
#endif
retval = ((UWORD)(getchr(mbhd)) << 8);
retval |= (UWORD)getchr(mbhd);
return (retval);
}
/************************************************************************
* Function : Schreibt ein Word in den Buffer
*
* Inputs : Der Wert (Word), Zeiger auf den Buffer
*
* Returns : nothing
*
* Operation :
*----------------------------------------------------------------------*/
void
put16(UWORD value, MBHEAD *mbhd)
{
#ifdef INSANE_BUFFER_DEBUG
MBPTRCHECK(mbhd);
#endif
putchr((BYTE)((value >> 8) & 0xff), mbhd);
putchr((BYTE)(value & 0xff), mbhd);
}
/************************************************************************
* Function : 32 Bits aus einem Buffer lesen
*
* Inputs : Zeiger auf den Buffer
*
* Returns : unsigned long integer
*
* Operation : Liest 2 Words und vertauscht sie
*----------------------------------------------------------------------*/
ULONG
get32(MBHEAD *mbhd)
{
ULONG retval;
#ifdef INSANE_BUFFER_DEBUG
MBPTRCHECK(mbhd);
#endif
retval = ((ULONG)(getchr(mbhd)) << 24);
retval |= ((ULONG)(getchr(mbhd)) << 16);
retval |= ((ULONG)(getchr(mbhd)) << 8);
retval |= (ULONG)getchr(mbhd);
return (retval);
}
/************************************************************************
* Function : Schreibt ein Long in den Buffer
*
* Inputs : Der Wert (Long), Zeiger auf den Buffer
*
* Returns : nothing
*
* Operation :
*----------------------------------------------------------------------*/
void
put32(ULONG value, MBHEAD *mbhd)
{
#ifdef INSANE_BUFFER_DEBUG
MBPTRCHECK(mbhd);
#endif
putchr((BYTE)((value >> 24) & 0xff), mbhd);
putchr((BYTE)((value >> 16) & 0xff), mbhd);
putchr((BYTE)((value >> 8) & 0xff), mbhd);
putchr((BYTE)(value & 0xff), mbhd);
}
#else
UWORD
get16(MBHEAD *mbhd)
{
UWORD retval;
char *r = (UBYTE *)&retval;
#if defined(BUFFER_DEBUG) && defined(__LINUX__) || defined(__WIN32__)
MBPTRCHECK(mbhd);
#endif
*r++ = getchr(mbhd);
*r = getchr(mbhd);
return (retval);
}
void
put16(UWORD value, MBHEAD *mbhd)
{
char *r = (UBYTE *)&value;
#if defined(BUFFER_DEBUG) && defined(__LINUX__) || defined(__WIN32__)
MBPTRCHECK(mbhd);
#endif
putchr(*r++, mbhd);
putchr(*r, mbhd);
}
ULONG
get32(MBHEAD *mbhd)
{
ULONG retval;
char *r = (UBYTE *)&retval;
#if defined(BUFFER_DEBUG) && defined(__LINUX__) || defined(__WIN32__)
MBPTRCHECK(mbhd);
#endif
*r++ = getchr(mbhd);
*r++ = getchr(mbhd);
*r++ = getchr(mbhd);
*r = getchr(mbhd);
return (retval);
}
void
put32(ULONG value, MBHEAD *mbhd)
{
char *r = (UBYTE *)&value;
#if defined(BUFFER_DEBUG) && defined(__LINUX__) || defined(__WIN32__)
MBPTRCHECK(mbhd);
#endif
putchr(*r++, mbhd);
putchr(*r++, mbhd);
putchr(*r++, mbhd);
putchr(*r, mbhd);
}
#endif
/************************************************************************\
* *
* "split copy" *
* *
* Die Bytes aus dem Messagebuffer, auf dessen Kopf mbhd zeigt, in den *
* Framebuffer, auf dessen Kopf fbp zeigt, kopieren. Es werden hoechstens *
* max Bytes kopiert, hat die Message mehr Bytes, so wird ein neuer *
* Messagebuffer angelegt, die restlichen Messagebytes werden in diesen *
* Buffer kopiert, der neue Buffer wird hinter den alten Messagebuffer *
* gehaengt, der Putcount des alten Buffers wird auf max gestellt, das *
* "more follows"-Flag morflg des neuen Buffers wird geloescht, l2fflg *
* wird uebertragen. *
* *
* Return : TRUE - der Messagebuffer wurde aufgesplittet *
* FALSE - sonst *
* *
\************************************************************************/
BOOLEAN
splcpy(WORD max, MBHEAD *fbp, MBHEAD *mbhd)
{
char huge *mbbpsa; /* Sicherung mbbp */
BOOLEAN split; /* TRUE: Split erfolgt */
WORD mbgcsa; /* Sicherung mbgc */
WORD mbgc2; /* mbgc alt -> mbpc alt */
WORD n; /* Zaehler */
MBHEAD *mbhd2; /* Kopfzeiger neuer Messagebuffer */
split = FALSE; /* zunaechst nichts gesplittet */
mbbpsa = mbhd->mbbp; /* Bufferpointer sichern */
mbgcsa = mbhd->mbgc; /* Getcounter sichern */
for (n = 0; mbhd->mbgc < mbhd->mbpc && n < max; ++n)
putchr(getchr(mbhd), fbp); /* maximal max Bytes kopieren */
if (mbhd->mbgc < mbhd->mbpc) /* noch Bytes ueber -> Split ! */
{
mbgc2 = mbhd->mbgc; /* Getcount fuer spaeter merken */
mbhd2 = (MBHEAD *)allocb(ALLOC_MBHEAD); /* neuen Buffer erzeugen */
while (mbhd->mbgc < mbhd->mbpc) /* die restlichen Bytes in diesen */
putchr(getchr(mbhd), mbhd2); /* Buffer kopieren */
rwndmb(mbhd2); /* neuen Buffer rewinden */
mbhd2->morflg = FALSE; /* noch dem neuen folgt keiner */
mbhd2->l2fflg = mbhd->l2fflg; /* Frameflag uebertragen */
mbhd2->repeated = 0; /* noch nicht erneut gesendet */
relink((LEHEAD *)mbhd2,
(LEHEAD *)mbhd); /* neu. Buf. hinter alten haengen */
mbhd->mbpc = mbgc2; /* alter Buffer nur max Zeichen ! */
split = TRUE; /* wir mussten splitten */
}
mbhd->mbbp = mbbpsa; /* Bufferpointer restaurieren */
mbhd->mbgc = mbgcsa; /* Getcount restaurieren */
return (split); /* Split oder nicht */
}
#ifdef BUFFER_DEBUG
/* Schreibt die aktuelle Buffer-Benutzung in eine Datei */
/* Wichtig: hier nichts benutzen, was irgendwie wieder */
/* neue Buffer belegen oder freigeben wuerde ! */
static
void bufstat(void)
{
MAX_BUFFER huge *actbp;
ULONG i, n;
ULONG used[ALLOC_MAXELEMENTE + 1];
FILE *fp;
if ((fp = fopen("buffer.log", "a+")) != NULL)
{
for (i = 0; i < ALLOC_MAXELEMENTE + 1; i++)
used[i] = 0;
actbp = (MAX_BUFFER *)RAMBOT;
n = (ULONG)((RAMTOP - RAMBOT) / sizeof(MAX_BUFFER));
fprintf(fp, "\rTotal Buffers : %ld (%u free) at %u Bytes each\r", n, nmbfre_max, (unsigned int)sizeof(MAX_BUFFER));
while (n--)
{
if ((UBYTE) ((USRBLK *)actbp)->owner >= ALLOC_MAXELEMENTE)
{
used[ALLOC_MAXELEMENTE]++;
fprintf(fp,"Wrong Owner: Buffer:%lu Owner:%d\r", n, (UBYTE) ((USRBLK *)actbp)->owner);
}
else
used[(UBYTE) ((USRBLK *)actbp)->owner]++;
actbp++;
}
fprintf(fp, "Free : by owner %lu, by counter %u\r", used[ALLOC_NO_OWNER], nmbfre);
fprintf(fp, "LEHEAD : %lu\r", used[ALLOC_LEHEAD]);
fprintf(fp, "MBHEAD : %lu\r", used[ALLOC_MBHEAD]);
fprintf(fp, "USRBLK1: %lu\r", used[ALLOC_USRBLK1]);
fprintf(fp, "USRBLK2: %lu\r", used[ALLOC_USRBLK2]);
fprintf(fp, "L2LINK : %lu\r", used[ALLOC_L2LINK]);
fprintf(fp, "MB : %lu\r", used[ALLOC_MB]);
fprintf(fp, "MONBUF : %lu\r", used[ALLOC_MONBUF]);
fprintf(fp, "CQBUF : %lu\r", used[ALLOC_CQBUF]);
fprintf(fp, "IPROUTE: %lu\r", used[ALLOC_IP_ROUTE]);
fprintf(fp, "ARPTAB : %lu\r", used[ALLOC_ARP_TAB]);
fprintf(fp, "MHEARD : %lu\r", used[ALLOC_MHEARD]);
fprintf(fp, "PACSAT : %lu\r", used[ALLOC_PACSATBLK]);
#ifdef TCP_STACK
fprintf(fp, "TCPSTA : %lu\r", used[ALLOC_TCPSTACK]);
#endif /* TCP_STACK */
#ifdef L1TCPIP
fprintf(fp, "TCPIP : %lu\r", used[ALLOC_L1TCPIP]);
#endif /* L1TCPIP */
#ifdef L1HTTPD
fprintf(fp, "HTTPDRX: %lu\r", used[ALLOC_L1HTTPD_RX]);
fprintf(fp, "HTTPDTX: %lu\r", used[ALLOC_L1HTTPD_TX]);
#endif /* L1HTTPD */
fprintf(fp, "INPOPT : %lu\r", used[ALLOC_INPOPT]);
if (used[0] != 0L)
fprintf(fp, "??? : %lu\r", used[0]);
fprintf(fp, "Errors : %lu\r", used[ALLOC_MAXELEMENTE]);
fclose(fp);
}
}
#ifdef INSANE_BUFFER_DEBUG
/************************************************************************/
/* Log-Funktion zum Debugging */
/************************************************************************/
static void
TOLOG(const char *format, ...)
{
FILE *fp;
va_list arg_ptr;
struct timeval tv;
static char str[30];
char *ptr;
if ((fp = fopen("buffer.log", "a+")) != NULL)
{
gettimeofday(&tv, NULL);
ptr = ctime(&tv.tv_sec);
strcpy(str, &ptr[11]);
fprintf(fp, "%s:", str);
va_start(arg_ptr, format);
vfprintf(fp, format, arg_ptr);
va_end(arg_ptr);
fprintf(fp, "\n");
fclose(fp);
}
}
/************************************************************************\
* Prueft, ob der uebergebene Pointer im Bufferbereich liegt *
\************************************************************************/
static void
MBPTRCHECK(MBHEAD* checkme)
{
/* Ist der uebergebene Zeiger im gueltigen Bereich ? */
if (((char*)checkme < RAMBOT) || ((char*)checkme > RAMTOP))
{
TOLOG("An error occured while accessing one of my buffers, the\r");
TOLOG("desired buffer at adress %p is outside of my allocted\r", checkme);
TOLOG("memory range from %p to %p (%ld bytes) !\r", RAMBOT, RAMTOP, (RAMTOP - RAMBOT));
TOLOG("Here is the actual usage of the buffer system:\r");
bufstat();
TOLOG("I will crash now for conservation of the stack ...\r");
HALT("MBPTRCHECK: crash !\r");
}
}
#endif /* INSANE_BUFFER_DEBUG */
#endif /* BUFFER_DEBUG */
/* End of src/buffer.c */