mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-26 14:18:20 +00:00
Provide customisable mbuf allocation.
Patch from Steven Johnson <sjohnson@sakuraindustries.com>
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
2006-05-25 Eric Norum <norume@aps.anl.gov>
|
||||
|
||||
* libnetworking/Makefile.am,
|
||||
libnetworking/Makefile.in,
|
||||
libnetworking/rtems/rtems_bsdnet.h,
|
||||
libnetworking/rtems/rtems_glue.c,
|
||||
libnetworking/rtems/rtems_malloc_mbuf.c: Provide customisable mbuf
|
||||
allocation. Patch from Steven Johnson <sjohnson@sakuraindustries.com>
|
||||
|
||||
2006-05-16 Ralf Corsépius <ralf.corsepius@rtems.org>
|
||||
|
||||
* aclocal/rtems-ampolish.m4: New.
|
||||
|
||||
@@ -35,6 +35,46 @@
|
||||
|
||||
#include <rtems/chain.h>
|
||||
|
||||
#ifdef MALLOC_ARENA_CHECK
|
||||
#define SENTINELSIZE 12
|
||||
#define SENTINEL "\xD1\xAC\xB2\xF1" "BITE ME"
|
||||
#define CALLCHAINSIZE 5
|
||||
struct mallocNode {
|
||||
struct mallocNode *back;
|
||||
struct mallocNode *forw;
|
||||
int callChain[CALLCHAINSIZE];
|
||||
size_t size;
|
||||
void *memory;
|
||||
};
|
||||
static struct mallocNode mallocNodeHead = { &mallocNodeHead, &mallocNodeHead };
|
||||
void reportMallocError(const char *msg, struct mallocNode *mp)
|
||||
{
|
||||
unsigned char *sp = (unsigned char *)mp->memory + mp->size;
|
||||
int i, ind = 0;
|
||||
static char cbuf[500];
|
||||
ind += sprintf(cbuf+ind, "Malloc Error: %s\n", msg);
|
||||
if ((mp->forw->back != mp) || (mp->back->forw != mp))
|
||||
ind += sprintf(cbuf+ind, "mp:0x%x mp->forw:0x%x mp->forw->back:0x%x mp->back:0x%x mp->back->forw:0x%x\n",
|
||||
mp, mp->forw, mp->forw->back, mp->back, mp->back->forw);
|
||||
if (mp->memory != (mp + 1))
|
||||
ind += sprintf(cbuf+ind, "mp+1:0x%x ", mp + 1);
|
||||
ind += sprintf(cbuf+ind, "mp->memory:0x%x mp->size:%d\n", mp->memory, mp->size);
|
||||
if (memcmp((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE) != 0) {
|
||||
ind += sprintf(cbuf+ind, "mp->sentinel: ");
|
||||
for (i = 0 ; i < SENTINELSIZE ; i++)
|
||||
ind += sprintf(cbuf+ind, " 0x%x", sp[i]);
|
||||
ind += sprintf(cbuf+ind, "\n");
|
||||
}
|
||||
ind += sprintf(cbuf+ind, "Call chain:");
|
||||
for (i = 0 ; i < CALLCHAINSIZE ; i++) {
|
||||
if (mp->callChain[i] == 0)
|
||||
break;
|
||||
ind += sprintf(cbuf+ind, " 0x%x", mp->callChain[i]);
|
||||
}
|
||||
printk("\n\n%s\n\n", cbuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
Chain_Control RTEMS_Malloc_GC_list;
|
||||
|
||||
rtems_id RTEMS_Malloc_Heap;
|
||||
@@ -190,6 +230,9 @@ void *malloc(
|
||||
* If this fails then return a NULL pointer.
|
||||
*/
|
||||
|
||||
#ifdef MALLOC_ARENA_CHECK
|
||||
size += sizeof(struct mallocNode) + SENTINELSIZE;
|
||||
#endif
|
||||
status = rtems_region_get_segment(
|
||||
RTEMS_Malloc_Heap,
|
||||
size,
|
||||
@@ -261,6 +304,32 @@ void *malloc(
|
||||
(void) memset(return_this, 0xCF, size);
|
||||
#endif
|
||||
|
||||
#ifdef MALLOC_ARENA_CHECK
|
||||
{
|
||||
struct mallocNode *mp = (struct mallocNode *)return_this;
|
||||
int key, *fp, *nfp, i;
|
||||
rtems_interrupt_disable(key);
|
||||
mp->memory = mp + 1;
|
||||
return_this = mp->memory;
|
||||
mp->size = size - (sizeof(struct mallocNode) + SENTINELSIZE);
|
||||
fp = (int *)&size - 2;
|
||||
for (i = 0 ; i < CALLCHAINSIZE ; i++) {
|
||||
mp->callChain[i] = fp[1];
|
||||
nfp = (int *)(fp[0]);
|
||||
if((nfp <= fp) || (nfp > (int *)(1 << 24)))
|
||||
break;
|
||||
fp = nfp;
|
||||
}
|
||||
while (i < CALLCHAINSIZE)
|
||||
mp->callChain[i++] = 0;
|
||||
memcpy((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE);
|
||||
mp->forw = mallocNodeHead.forw;
|
||||
mp->back = &mallocNodeHead;
|
||||
mallocNodeHead.forw->back = mp;
|
||||
mallocNodeHead.forw = mp;
|
||||
rtems_interrupt_enable(key);
|
||||
}
|
||||
#endif
|
||||
return return_this;
|
||||
}
|
||||
|
||||
@@ -318,6 +387,16 @@ void *realloc(
|
||||
return (void *) 0;
|
||||
}
|
||||
|
||||
#ifdef MALLOC_ARENA_CHECK
|
||||
{
|
||||
void *np;
|
||||
np = malloc(size);
|
||||
if (!np) return np;
|
||||
memcpy(np,ptr,size);
|
||||
free(ptr);
|
||||
return np;
|
||||
}
|
||||
#endif
|
||||
status =
|
||||
rtems_region_resize_segment( RTEMS_Malloc_Heap, ptr, size, &old_size );
|
||||
|
||||
@@ -378,6 +457,30 @@ void free(
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MALLOC_ARENA_CHECK
|
||||
{
|
||||
struct mallocNode *mp = (struct mallocNode *)ptr - 1;
|
||||
struct mallocNode *mp1;
|
||||
int key;
|
||||
rtems_interrupt_disable(key);
|
||||
if ((mp->memory != (mp + 1))
|
||||
|| (memcmp((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE) != 0))
|
||||
reportMallocError("Freeing with inconsistent pointer/sentinel", mp);
|
||||
mp1 = mallocNodeHead.forw;
|
||||
while (mp1 != &mallocNodeHead) {
|
||||
if (mp1 == mp)
|
||||
break;
|
||||
mp1 = mp1->forw;
|
||||
}
|
||||
if (mp1 != mp)
|
||||
reportMallocError("Freeing, but not on allocated list", mp);
|
||||
mp->forw->back = mp->back;
|
||||
mp->back->forw = mp->forw;
|
||||
mp->back = mp->forw = NULL;
|
||||
ptr = mp;
|
||||
rtems_interrupt_enable(key);
|
||||
}
|
||||
#endif
|
||||
#ifdef MALLOC_STATS
|
||||
{
|
||||
size_t size;
|
||||
@@ -394,6 +497,26 @@ void free(
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MALLOC_ARENA_CHECK
|
||||
void checkMallocArena(void)
|
||||
{
|
||||
struct mallocNode *mp = mallocNodeHead.forw;
|
||||
int key;
|
||||
rtems_interrupt_disable(key);
|
||||
while (mp != &mallocNodeHead) {
|
||||
if ((mp->forw->back != mp)
|
||||
|| (mp->back->forw != mp))
|
||||
reportMallocError("Pointers mangled", mp);
|
||||
if((mp->memory != (mp + 1))
|
||||
|| (memcmp((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE) != 0))
|
||||
reportMallocError("Inconsistent pointer/sentinel", mp);
|
||||
mp = mp->forw;
|
||||
}
|
||||
rtems_interrupt_enable(key);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* end if RTEMS_NEWLIB */
|
||||
#endif
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ include_rtems_HEADERS = rtems/rtems_bsdnet.h rtems/rtems_bsdnet_internal.h \
|
||||
include_rtems_HEADERS += rtems/rtems_mii_ioctl.h
|
||||
|
||||
libnetworking_a_SOURCES += rtems/sghostname.c rtems/issetugid.c \
|
||||
rtems/rtems_glue.c rtems/rtems_syscall.c \
|
||||
rtems/rtems_glue.c rtems/rtems_malloc_mbuf.c rtems/rtems_syscall.c \
|
||||
rtems/rtems_bootp.c rtems/rtems_dhcp.c \
|
||||
rtems/rtems_showmbuf.c rtems/rtems_showroute.c rtems/rtems_showifstat.c \
|
||||
rtems/rtems_showipstat.c rtems/rtems_showicmpstat.c \
|
||||
|
||||
@@ -260,4 +260,20 @@ int rtems_bsdnet_synchronize_ntp (int interval, rtems_task_priority priority);
|
||||
*/
|
||||
void rtems_bsdnet_malloc_starvation(void);
|
||||
|
||||
/*
|
||||
* mbuf malloc interface to enable custom allocation of mbuf's
|
||||
*
|
||||
* May be declared in user code. If not, then the default is to
|
||||
* malloc.
|
||||
*/
|
||||
void* rtems_bsdnet_malloc_mbuf(size_t size, int type);
|
||||
|
||||
/*
|
||||
* Possible values of the type parameter to rtems_bsdnet_malloc_mbuf to assist
|
||||
* in allocation of the structure.
|
||||
*/
|
||||
#define MBUF_MALLOC_NMBCLUSTERS (0)
|
||||
#define MBUF_MALLOC_MCLREFCNT (1)
|
||||
#define MBUF_MALLOC_MBUF (2)
|
||||
|
||||
#endif /* _RTEMS_BSDNET_H */
|
||||
|
||||
@@ -149,7 +149,7 @@ bsd_init (void)
|
||||
/*
|
||||
* Set up mbuf cluster data strutures
|
||||
*/
|
||||
p = malloc ((nmbclusters*MCLBYTES)+MCLBYTES-1);
|
||||
p = rtems_bsdnet_malloc_mbuf ((nmbclusters*MCLBYTES)+MCLBYTES-1, MBUF_MALLOC_NMBCLUSTERS);
|
||||
if (p == NULL) {
|
||||
printf ("Can't get network cluster memory.\n");
|
||||
return -1;
|
||||
@@ -163,7 +163,7 @@ bsd_init (void)
|
||||
mbstat.m_clfree++;
|
||||
}
|
||||
mbstat.m_clusters = nmbclusters;
|
||||
mclrefcnt = malloc (nmbclusters);
|
||||
mclrefcnt = rtems_bsdnet_malloc_mbuf (nmbclusters, MBUF_MALLOC_MCLREFCNT);
|
||||
if (mclrefcnt == NULL) {
|
||||
printf ("Can't get mbuf cluster reference counts memory.\n");
|
||||
return -1;
|
||||
@@ -174,7 +174,7 @@ bsd_init (void)
|
||||
* Set up mbuf data structures
|
||||
*/
|
||||
|
||||
p = malloc(nmbuf * MSIZE + MSIZE - 1);
|
||||
p = rtems_bsdnet_malloc_mbuf(nmbuf * MSIZE + MSIZE - 1,MBUF_MALLOC_MBUF);
|
||||
p = (char *)(((unsigned int)p + MSIZE - 1) & ~(MSIZE - 1));
|
||||
if (p == NULL) {
|
||||
printf ("Can't get network memory.\n");
|
||||
|
||||
33
cpukit/libnetworking/rtems/rtems_malloc_mbuf.c
Normal file
33
cpukit/libnetworking/rtems/rtems_malloc_mbuf.c
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#define RTEMS_FAST_MUTEX
|
||||
|
||||
#ifdef RTEMS_FAST_MUTEX
|
||||
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/rtems_bsdnet.h>
|
||||
|
||||
/*
|
||||
* Default allocator for mbuf data. Over-ride in user code to change
|
||||
* the way mbuf's are allocated.
|
||||
*/
|
||||
|
||||
void* rtems_bsdnet_malloc_mbuf(size_t size, int type)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user