Files
m241Neelima/components/ip_net2-6.9/ipcom/src/ipcom_dmalloc.c
T
2026-07-30 11:19:44 +05:30

1091 lines
32 KiB
C

/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipcom_dmalloc.c,v $ $Revision: 1.63.10.3 $
* $Source: /home/interpeak/CVSRoot/ipcom/src/ipcom_dmalloc.c,v $
* $Author: svc-cmnet $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Lennart Bang <lob@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#define IPCOM_KERNEL
#include "ipcom_config.h"
/* IPCOM_ALLOC_SPACE
* Space after allocated buffers to detect bad memory writes.
*/
#define IPCOM_ALLOC_SPACE 16
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_DMALLOC_C
#define IPCOM_USE_CLIB_PROTO
#include "ipcom_type.h"
#include "ipcom_time.h"
#include "ipcom_cstyle.h"
#include "ipcom_clib.h"
#include "ipcom_getopt.h"
#include "ipcom_err.h"
#include "ipcom_os.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPCOM_MEM_MAXBUF 100
#ifdef IP_PORT_VXWORKS
/*
* In the VxWorks command interpreter shell, 'mem list' conflicts
* with a 'mem list' command that disassembles machine instructions.
* So, we name the 'mem' command 'ipmem' in VxWorks.
*/
#define MEM "ipmem"
#else
#define MEM "mem"
#endif
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
*===========================================================================
* Ipcom_membuf
*===========================================================================
* 32 bytes sized memory buffer header.
*/
typedef struct Ipcom_membuf_struct
{
struct Ipcom_membuf_struct *next;
struct Ipcom_membuf_struct *prev;
Ip_size_t size; /* Size of user memory */
Ip_u32 line; /* The line on which the memory block was allocated */
Ip_u32 msec;
Ip_u32 id;
Ip_u8 flags;
Ip_u8 unused[3];
Ip_u32 magic;
/* User memory of size 'size'. */
/* Ip_u8 pad[X]; */
/* null terminated file name. */
/* null terminated function (optional). */
}
Ipcom_membuf;
#define IPCOM_MEMBUF_MAGIC 0xbabebeef
#define IPCOM_MEMBUF_FLAG_FUNCTION 0x1 /* got function string. */
/*
*===========================================================================
* Ipcom_mem_summary
*===========================================================================
*/
typedef struct Ipcom_mem_summary_struct
{
int totbufs;
Ip_u32 totsize;
Ip_u32 maxsize;
}
Ipcom_mem_summary;
/*
*===========================================================================
* Global ipcom_mem data
*===========================================================================
* Internal global Ipcom_mem data.
*/
typedef struct Ipcom_mem_data_struct
{
Ip_time_t boot_time;
Ipcom_membuf mem;
Ip_u32 mark_id;
}
Ipcom_mem_data;
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
#ifdef ZEBOS
extern char *zebos_memory_name(int type);
#endif
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
#if IPCOM_USE_SHELL >= IPCOM_SHELL_IPCOM
IP_PUBLIC int ipcom_cmd_mem(int argc, char **argv);
#endif
IP_PUBLIC void *ipcom_dmalloc(Ip_size_t size, const char *file, const char *function, Ip_u32 line);
IP_PUBLIC void *ipcom_dcalloc(Ip_size_t nelem, Ip_size_t elsize, const char *file, const char *function, Ip_u32 line);
IP_PUBLIC void *ipcom_drealloc(void *ptr, Ip_size_t size, const char *file, const char *function, Ip_u32 line);
IP_PUBLIC char *ipcom_dstrdup(const char *s1, const char *file, const char *function, Ip_u32 line);
IP_PUBLIC void ipcom_dfree(void *ptr);
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
#if IPCOM_USE_SHELL >= IPCOM_SHELL_IPCOM && !defined(IP_PORT_LKM)
IP_STATIC const char *ipcom_dmalloc_product[] =
{
"total",
"ipcom total",
"ipcom_pkt",
"ipcom_sysvar",
"ipcom_telnet",
"ipcom_file",
"ipcom_shell",
"ipcom_os",
"ipcom_tmo",
"ipcom_func",
"ipcom_auth",
"ipcom_syslog",
"ipcom_drv_eth",
"ipcom_drv_ppp",
"ipcom",
"ipcrypto",
"ipipsec",
"ipike",
"ipl2tp",
"ipldapc",
"iplite",
"ipnat",
"ippppoe",
"ipradius",
"iprip",
"ipssh",
"ipsslproxy",
"ipssl",
"ipftp",
"ipfirewall",
"ipdhcpd",
"ipdhcpc",
"ipwebs",
"ipnetsnmp",
"ipnet",
"iptftp",
"ipsntp",
"ipdhcps6",
"ipdhcps",
"ipsnmp",
"ipdhcpr",
"ipdnsc",
"ipemanate",
"ipfreescale",
"ipprism",
"ipsafenet",
"ip8021x",
"ipeap",
"iphwcrypto",
"ipcavium",
"wrnad",
IP_NULL
};
#endif
IP_STATIC Ipcom_mem_data ipcom_mem;
IP_STATIC Ip_bool ipcom_mem_initialized = IP_FALSE;
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipcom_dmalloc_init
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipcom_dmalloc_init(void)
{
Ip_u32 msr;
if (ipcom_mem_initialized)
return;
msr = ipcom_interrupt_disable();
/* Check again to avoid a small race condition. */
if (ipcom_mem_initialized)
{
ipcom_interrupt_enable(msr);
return;
}
ipcom_mem_initialized = IP_TRUE;
ipcom_memset(&ipcom_mem, 0, sizeof(ipcom_mem));
ipcom_mem.mem.next = &ipcom_mem.mem;
ipcom_mem.mem.prev = &ipcom_mem.mem;
ipcom_mem.mem.magic = IPCOM_MEMBUF_MAGIC;
ipcom_interrupt_enable(msr);
#ifdef IPCOM_USE_TIME
{
struct Ip_tms tms;
(void)ipcom_times(&tms);
ipcom_mem.boot_time = ipcom_time(IP_NULL);
}
#endif
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipcom_dmalloc
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC void *
ipcom_dmalloc(Ip_size_t size, const char *file, const char *function, Ip_u32 line)
{
Ipcom_membuf *membuf;
Ip_u8 *buf;
int i;
int file_length;
int function_length;
Ip_size_t memsize;
Ip_u32 msr;
ipcom_dmalloc_init();
#ifdef ZEBOS
/* Special ZebOS memory debug fix. */
char funcbuf[32];
if (function && (int)function < 1000)
{
ipcom_sprintf(funcbuf, "zebos%d", (int)function);
function = (const char *)funcbuf;
}
#endif /* ZEBOS */
(void)file;
(void)function;
(void)line;
/*ip_assert2(size > 0);*/
if (size == 0)
return IP_NULL;
if (file)
{
for (i = (int)ipcom_strlen(file) - 1; i >= 0; i--)
if (file[i] == '/' || file[i] == '\\')
{
file = &file[i+1]; /*lint !e679 */
break;
}
file_length = (int)ipcom_strlen(file) + 1;
}
else
file_length = 0;
function_length = function ? ((int)ipcom_strlen(function) + 1) : 0;
memsize = sizeof(Ipcom_membuf) + size + (Ip_size_t) (IPCOM_ALLOC_SPACE + file_length + function_length);
membuf = ipcom_malloc(memsize);
if (membuf == IP_NULL)
return IP_NULL;
membuf->size = size;
membuf->line = line;
membuf->msec = (Ip_u32)(ipcom_time(IP_NULL) - ipcom_mem.boot_time);
membuf->id = ++ipcom_mem.mem.id;
membuf->flags = 0;
membuf->magic = IPCOM_MEMBUF_MAGIC;
buf = (Ip_u8 *)membuf + sizeof(Ipcom_membuf);
for (i = 0; i < IPCOM_ALLOC_SPACE; i++)
buf[(Ip_size_t)i+size] = (Ip_u8)0xee;
if (file)
ipcom_strcpy((char *)(buf + size + IPCOM_ALLOC_SPACE), file);
if (function)
{
ipcom_strcpy((char *)(buf + size + IPCOM_ALLOC_SPACE + file_length), function);
IP_BIT_SET(membuf->flags, IPCOM_MEMBUF_FLAG_FUNCTION);
}
/* Insert membuf last in list. */
msr = ipcom_interrupt_disable();
#ifdef IP_ASSERT2
{
Ipcom_membuf *tmp;
for (tmp = ipcom_mem.mem.next; tmp != &ipcom_mem.mem; tmp = tmp->next)
{
ip_assert(tmp != membuf);
#ifdef IP_ASSERT3
ipcom_bufcheck((Ip_u8 *)tmp + sizeof(Ipcom_membuf));
#endif
}
}
#endif /* IP_ASSERT2 */
membuf->prev = ipcom_mem.mem.prev;
membuf->next = &ipcom_mem.mem;
membuf->next->prev = membuf;
membuf->prev->next = membuf;
ipcom_mem.mem.size += membuf->size;
ipcom_mem.mem.line++;
ipcom_interrupt_enable(msr);
return buf;
}
/*
*===========================================================================
* ipcom_dmalloc_ptr
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC void *
ipcom_dmalloc_ptr(Ip_size_t size)
{
return ipcom_dmalloc(size, IP_NULL, IP_NULL, 0);
}
/*
*===========================================================================
* ipcom_dcalloc
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC void *
ipcom_dcalloc(Ip_size_t nelem, Ip_size_t elsize, const char *file, const char *function, Ip_u32 line)
{
Ip_size_t tot;
void *buf;
tot = nelem * elsize;
if (tot > 0)
{
buf = ipcom_dmalloc(tot, file, function, line);
if (buf != IP_NULL)
{
ipcom_memset(buf, 0, tot);
return buf;
}
}
return IP_NULL;
}
/*
*===========================================================================
* ipcom_drealloc
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC void *
ipcom_drealloc(void *ptr, Ip_size_t size, const char *file, const char *function, Ip_u32 line)
{
Ipcom_membuf *membuf;
void *buf;
if (ptr != IP_NULL)
{
if (size == 0)
{
ipcom_dfree(ptr);
return IP_NULL;
}
membuf = (Ipcom_membuf *)((Ip_u8 *)ptr - sizeof(Ipcom_membuf));
if (size <= membuf->size)
return ptr;
buf = ipcom_dmalloc(size, file, function, line);
if (buf != IP_NULL)
{
ipcom_memcpy(buf, ptr, membuf->size);
ipcom_dfree(ptr);
}
}
else
{
buf = ipcom_dmalloc(size, file, function, line);
}
return buf;
}
/*
*===========================================================================
* ipcom_dfree
*===========================================================================
* Description: Free the dynamic memory pointer to by 'ptr'. If 'ptr'
* is IP_NULL, no operation is performed.
* Parameters: ptr - Pointer to the dynamic memory to free.
* Returns: .
*
*/
IP_PUBLIC void
ipcom_dfree(void *ptr)
{
Ipcom_membuf *membuf;
Ip_u32 msr;
if (ptr == IP_NULL)
return;
ipcom_bufcheck(ptr);
membuf = (Ipcom_membuf *)((Ip_u8 *)ptr - sizeof(Ipcom_membuf));
msr = ipcom_interrupt_disable();
#ifdef IP_ASSERT2
{
Ipcom_membuf *tmp;
Ip_bool found = IP_FALSE;
for (tmp = ipcom_mem.mem.next; tmp != &ipcom_mem.mem; tmp = tmp->next)
{
#ifdef IP_ASSERT3
ipcom_bufcheck((Ip_u8 *)tmp + sizeof(Ipcom_membuf));
#endif
if (tmp == membuf)
found = IP_TRUE;
}
ip_assert(found);
}
#endif /* IP_ASSERT2 */
/* remove entry from list. */
membuf->next->prev = membuf->prev;
membuf->prev->next = membuf->next;
ipcom_mem.mem.size -= membuf->size;
ip_assert(ipcom_mem.mem.line > 0);
ipcom_mem.mem.line--;
ipcom_interrupt_enable(msr);
/* garble memory to cause crash if access pointer inside it */
ipcom_memset(ptr, 0xfe, membuf->size);
ipcom_free(membuf);
}
/*
*===========================================================================
* ipcom_dstrdup
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC char *
ipcom_dstrdup(const char *s1, const char *file, const char *function, Ip_u32 line)
{
char *s2;
s2 = ipcom_dmalloc(ipcom_strlen(s1) + 1, file, function, line);
if (s2 == IP_NULL)
return IP_NULL;
ipcom_strcpy(s2, s1);
return s2;
}
/*
*===========================================================================
* ipcom_bufcheck
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC void
ipcom_bufcheck(void *ptr)
{
#ifdef IP_ASSERT
int i;
Ipcom_membuf *membuf;
membuf = (Ipcom_membuf *)((Ip_u8 *)ptr - sizeof(Ipcom_membuf));
ip_assert(membuf->magic == IPCOM_MEMBUF_MAGIC);
ip_assert(membuf->next);
ip_assert(membuf->prev);
ip_assert(membuf->size > 0);
for (i = 0; i < IPCOM_ALLOC_SPACE; i++)
{
ip_assert(((Ip_u8 *)ptr)[membuf->size + (Ip_size_t)i] == (Ip_u8)0xee);
}
#else
(void)ptr;
#endif /* IP_ASSERT */
}
/*
*===========================================================================
* ipcom_cmd_mem
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
#if IPCOM_USE_SHELL >= IPCOM_SHELL_IPCOM && !defined(IP_PORT_LKM)
IP_PUBLIC int
ipcom_cmd_mem(int argc, char **argv)
{
int i, c;
Ipcom_getopt opt;
Ipcom_membuf *membuf;
Ip_u32 msr;
char buf[128];
char filebuf[48];
char *inckey[10];
int incnum = 0;
char *exckey[10];
char *funckey;
char *nofunckey;
char *file;
char *function;
int excnum = 0;
int all = 0;
int show_addr = 0;
int show_time = 0;
int show_id = 0;
Ip_u32 minsize = 0;
Ip_u32 maxsize = 0xffffffff;
Ip_u32 mintime = 0;
Ip_u32 maxtime = 0xffffffff;
Ip_u32 minid;
Ip_u32 maxid;
static struct Ip_option long_options[] =
{
{"all", 0, 0, 0},
{"file", 1, 0, 0},
{"nofile", 1, 0, 0},
{"function", 1, 0, 0},
{"addr", 0, 0, 0},
{"minsize", 1, 0, 0},
{"maxsize", 1, 0, 0},
{"time", 0, 0, 0},
{"mintime", 1, 0, 0},
{"maxtime", 1, 0, 0},
{"id", 0, 0, 0},
{"nofunction", 1, 0, 0},
{0, 0, 0, 0}
};
if (ipcom_mem_initialized == IP_FALSE)
{
ipcom_printf(MEM ": List is empty"IP_LF);
return 0;
}
ipcom_memset(inckey, 0, sizeof(inckey));
ipcom_memset(exckey, 0, sizeof(exckey));
funckey = IP_NULL;
nofunckey = IP_NULL;
if (argc < 2)
{
usage:
ipcom_fprintf(ip_stderr,
"Interpeak " MEM " command, version 1.1"IP_LF
"usage: "IP_LF
" " MEM " list [-flags] - list buffers"IP_LF
" " MEM " summary - show memory summary"IP_LF
" " MEM " mark <val> - set id mark (val = 0 to clear)"IP_LF
#if !defined(IP_PORT_OSE) && !defined(IP_PORT_OSECK) && !defined(IP_PORT_OSE5)
" " MEM " max - print max size of buffer"IP_LF
#endif
#ifdef ZEBOS
" " MEM " zebos - show zebos memory summary"IP_LF
#endif
"list flags: "IP_LF);
ipcom_fprintf(ip_stderr,
" -all ignore mark when listing"IP_LF
" -file <file> list entries from file <file>"IP_LF
" -nofile <file> do not list entries from file <file>"IP_LF
" -function <func> list entries from function <func>"IP_LF
" -nofunction <func> do nost list entries from function <func>"IP_LF
" -minsize <val> list entries of size > <val>"IP_LF
" -maxsize <val> list entries of size < <val>"IP_LF);
ipcom_fprintf(ip_stderr,
" -mintime <val> list entries of time > <val>"IP_LF
" -maxtime <val> list entries of time < <val>"IP_LF
" -time show buffer allocation time"IP_LF
" -addr show buffer address"IP_LF
" -id show buffer id"IP_LF
IP_LF
" note: there may be up to 10 -file and -nofile options"IP_LF
IP_LF);
return 0;
}
/* Parse options. */
ipcom_getopt_clear_r(&opt);
opt.long_only = 1;
opt.long_options = long_options;
while ((c = ipcom_getopt_r(argc - 1, argv + 1, "h", &opt)) != -1)
{
switch (c)
{
case 'h' :
goto usage;
case 0 :
switch(opt.long_index)
{
case 0 : /* all */
all = 1;
break;
case 1 : /* file */
inckey[incnum++] = opt.optarg;
break;
case 2 : /* nofile */
exckey[excnum++] = opt.optarg;
break;
case 3 : /* function */
funckey = opt.optarg;
break;
case 4 : /* addr */
show_addr = 1;
break;
case 5 : /* minsize */
minsize = (Ip_u32)ipcom_atol(opt.optarg);
break;
case 6 : /* maxsize */
maxsize = (Ip_u32)ipcom_atol(opt.optarg);
break;
case 7 : /* time */
show_time = 1;
break;
case 8 : /* mintime */
mintime = (Ip_u32)ipcom_atol(opt.optarg);
break;
case 9 : /* maxtime */
maxtime = (Ip_u32)ipcom_atol(opt.optarg);
break;
case 10 : /* id */
show_id = 1;
break;
case 11 : /* nofunction */
nofunckey = opt.optarg;
break;
default:
ipcom_printf (MEM ": unknown long option %s", long_options[opt.long_index].name);
if (opt.optarg)
ipcom_printf(" with arg %s", opt.optarg);
ipcom_printf(IP_LF);
return -1;
}
break;
default:
ipcom_printf(MEM ": unknown option %c"IP_LF, (char)c);
return -1;
}
}
/* Set max and min id. */
msr = ipcom_interrupt_disable();
minid = all ? 0 : ipcom_mem.mark_id;
maxid = ipcom_mem.mem.id;
ipcom_interrupt_enable(msr);
/* list command. */
if (ipcom_strcmp(argv[1], "list") == 0)
{
int length;
int totbufs = 0, shownbufs = 0;
Ip_u32 totsize = 0, shownsize = 0;
Ip_bool have_function = IP_FALSE;
msr = ipcom_interrupt_disable();
for (membuf = ipcom_mem.mem.next; membuf != &ipcom_mem.mem; membuf = membuf->next)
if (IP_BIT_ISSET(membuf->flags, IPCOM_MEMBUF_FLAG_FUNCTION))
{
have_function = IP_TRUE;
break;
}
ipcom_interrupt_enable(msr);
if (have_function)
ipcom_printf("%-30s %-30s %-6s",
"File:line", "Function", "Size");
else
ipcom_printf("%-30s %-6s",
"File:line", "Size");
if (show_time)
ipcom_printf("%-10s", "Msec");
if (show_id)
ipcom_printf("%-8s", "Id");
if (show_addr)
ipcom_printf("%-8s", "Ptr");
ipcom_printf(IP_LF);
next:
msr = ipcom_interrupt_disable();
for (membuf = ipcom_mem.mem.next; membuf != &ipcom_mem.mem; membuf = membuf->next)
{
if (membuf->id > minid && membuf->id <= maxid)
{
ipcom_bufcheck((Ip_u8 *)membuf + sizeof(Ipcom_membuf));
totbufs++;
totsize += (Ip_u32)membuf->size;
minid = membuf->id;
file = (char *)((Ip_u8 *)membuf + sizeof(Ipcom_membuf) + membuf->size + IPCOM_ALLOC_SPACE);
ipcom_snprintf(filebuf, sizeof(filebuf), "%s:%ld", file, membuf->line);
if (IP_BIT_ISSET(membuf->flags, IPCOM_MEMBUF_FLAG_FUNCTION))
function = file + ipcom_strlen(file) + 1;
else
function = IP_NULL;
*buf = '\0';
/* Sizes. */
if (membuf->size < minsize || membuf->size > maxsize)
goto skip;
/* Time. */
if (membuf->msec < mintime || membuf->msec > maxtime)
goto skip;
/* Function. */
if (funckey && function && !ipcom_strstr(function, funckey))
goto skip;
/* Nofunction. */
if (nofunckey && function && ipcom_strstr(function, nofunckey))
goto skip;
/* Exclude these files: */
for (i = 0; i < excnum; i++)
if (ipcom_strstr(file, exckey[i]))
goto skip;
/* Include these files: */
for (i = 0; i < incnum; i++)
if (!ipcom_strstr(file, inckey[i]))
goto skip;
shownbufs++;
shownsize += (Ip_u32)membuf->size;
if (have_function)
length = ipcom_snprintf(buf, sizeof(buf),
"%-30s %-30s %-6lu",
filebuf,
function ? function : "",
(unsigned long) membuf->size);
else
length = ipcom_snprintf(buf, sizeof(buf),
"%-30s %-6lu",
filebuf,
(unsigned long) membuf->size);
if (show_time)
length += ipcom_snprintf(buf + length, sizeof(buf) - (Ip_size_t)length,
"%-10ld",
membuf->msec);
if (show_id)
length += ipcom_snprintf(buf + length, sizeof(buf) - (Ip_size_t)length,
"%-8ld",
membuf->id);
if (show_addr)
length += ipcom_snprintf(buf + length, sizeof(buf) - (Ip_size_t)length,
"%-8p",
membuf + 1);
skip:
ipcom_interrupt_enable(msr);
if (*buf)
{
ipcom_printf(buf);
ipcom_printf(IP_LF);
}
goto next;
}
}
ipcom_interrupt_enable(msr);
ipcom_printf(IP_LF);
if (totbufs != shownbufs)
ipcom_printf("Shown: %d buffers totalling %ld bytes.\n", shownbufs, shownsize);
ipcom_printf("Total: %d buffers totalling %ld bytes.\n", totbufs, totsize);
}
/* summary command. */
else if (ipcom_strcmp(argv[1], "summary") == 0)
{
Ipcom_mem_summary *sum;
Ip_size_t count;
for (count = 0; ipcom_dmalloc_product[count] != IP_NULL; count++)
{
}
sum = ipcom_malloc((count + 1) * sizeof(Ipcom_mem_summary));
if (sum == IP_NULL)
{
ipcom_printf(MEM ": out of memory"IP_LF);
return -1;
}
ipcom_memset(sum, 0, (count + 1) * sizeof(Ipcom_mem_summary));
msr = ipcom_interrupt_disable();
for (membuf = ipcom_mem.mem.next; membuf != &ipcom_mem.mem; membuf = membuf->next)
if (membuf->id > minid && membuf->id <= maxid)
{
file = (char *)((Ip_u8 *)membuf + sizeof(Ipcom_membuf) + membuf->size + IPCOM_ALLOC_SPACE);
for (i = 2; ipcom_dmalloc_product[i] != IP_NULL; i++)
if (ipcom_strncmp(file, ipcom_dmalloc_product[i], ipcom_strlen(ipcom_dmalloc_product[i])) == 0)
break;
sum[i].totbufs++;
sum[i].totsize += (Ip_u32)membuf->size;
sum[i].maxsize = IP_MAX(sum[i].maxsize, (Ip_u32)membuf->size);
if (ipcom_strncmp(file, "ipcom", 5) == 0)
{
sum[1].totbufs++;
sum[1].totsize += (Ip_u32)membuf->size;
sum[1].maxsize = IP_MAX(sum[0].maxsize, (Ip_u32)membuf->size);
}
sum[0].totbufs++;
sum[0].totsize += (Ip_u32)membuf->size;
sum[0].maxsize = IP_MAX(sum[0].maxsize, (Ip_u32)membuf->size);
}
ipcom_interrupt_enable(msr);
ipcom_printf("%-15s%-8s%-8s%-8s"IP_LF,
"Product", "NumBufs", "MaxSize", "TotSize");
ipcom_printf("=======================================\n");
for (i = 2; ipcom_dmalloc_product[i] != IP_NULL; i++)
if (sum[i].totbufs)
ipcom_printf("%-15s%-8d%-8ld%-8ld\n",
ipcom_dmalloc_product[i],
sum[i].totbufs,
sum[i].maxsize,
sum[i].totsize);
if (sum[i].totbufs)
ipcom_printf("%-15s%-8d%-8ld%-8ld\n",
"unknown",
sum[i].totbufs,
sum[i].maxsize,
sum[i].totsize);
ipcom_printf("=======================================\n");
ipcom_printf("%-15s%-8d%-8ld%-8ld\n",
"IPCOM total",
sum[1].totbufs,
sum[1].maxsize,
sum[1].totsize);
ipcom_printf("%-15s%-8d%-8ld%-8ld\n",
"TOTAL",
sum[0].totbufs,
sum[0].maxsize,
sum[0].totsize);
ipcom_free(sum);
}
/* mark command. */
else if (ipcom_strcmp(argv[1], "mark") == 0)
{
if (argc < opt.optind + 2)
ipcom_mem.mark_id = ipcom_mem.mem.id;
else
ipcom_mem.mark_id = (Ip_u32)ipcom_atol(argv[opt.optind+1]); /*lint !e679 */
ipcom_printf(MEM ": mark id set to %ld.\n", ipcom_mem.mark_id);
}
/* max command. */
#if !defined(IP_PORT_OSE) && !defined(IP_PORT_OSECK) && !defined(IP_PORT_OSE5)
else if (ipcom_strcmp(argv[1], "max") == 0)
{
void *arr[IPCOM_MEM_MAXBUF];
Ip_size_t tot = 0;
Ip_size_t sz;
int indx = 0;
/* Allocate as large a buffer as possible. */
for (sz = 0x1000000; sz != 0; sz >>= 1)
{
while (indx < IPCOM_MEM_MAXBUF &&
(arr[indx] = ipcom_malloc(sz)) != IP_NULL)
{
tot += sz;
indx++;
}
if (indx >= IPCOM_MEM_MAXBUF)
{
ipcom_printf(MEM ": overflow, increase IPCOM_MEM_MAXBUF in src/ipcom_dmalloc.c"IP_LF);
break;
}
}
/* Free in opposite order which hopefully is more heap friendly */
while (--indx >= 0)
ipcom_free(arr[indx]);
ipcom_printf("Max buffer size available: %ld bytes"IP_LF, (Ip_u32)tot);
}
#endif
#ifdef ZEBOS
else if (ipcom_strcmp(argv[1], "zebos") == 0)
{
Ipcom_mem_summary *sum;
#define ZEBOS_MAX 400
sum = ipcom_malloc(ZEBOS_MAX * sizeof(Ipcom_mem_summary));
if (sum == IP_NULL)
{
ipcom_printf(MEM ": out of memory"IP_LF);
return -1;
}
ipcom_memset(sum, 0, ZEBOS_MAX * sizeof(Ipcom_mem_summary));
msr = ipcom_interrupt_disable();
for (membuf = ipcom_mem.mem.next; membuf != &ipcom_mem.mem; membuf = membuf->next)
if (membuf->id > minid && membuf->id <= maxid)
{
file = (char *)((Ip_u8 *)membuf + sizeof(Ipcom_membuf) + membuf->size + IPCOM_ALLOC_SPACE);
if (IP_BIT_ISSET(membuf->flags, IPCOM_MEMBUF_FLAG_FUNCTION))
function = file + ipcom_strlen(file) + 1;
else
function = IP_NULL;
if (function && ipcom_strncmp(function, "zebos", 5) == 0)
{
i = ipcom_atoi(function + 5);
if (i < ZEBOS_MAX - 1)
{
sum[i].totbufs++;
sum[i].totsize += membuf->size;
sum[i].maxsize = IP_MAX(sum[i].maxsize, membuf->size);
sum[ZEBOS_MAX - 1].totbufs++;
sum[ZEBOS_MAX - 1].totsize += membuf->size;
sum[ZEBOS_MAX - 1].maxsize = IP_MAX(sum[ZEBOS_MAX - 1].maxsize, membuf->size);
}
}
}
ipcom_interrupt_enable(msr);
ipcom_printf("%-30s%-8s%-8s%-8s"IP_LF,
"Product", "NumBufs", "MaxSize", "TotSize");
ipcom_printf("======================================================\n");
for (i = 0; i < ZEBOS_MAX - 1; i++)
if (sum[i].totbufs)
ipcom_printf("%-30s%-8ld%-8ld%-8ld\n",
zebos_memory_name(i),
sum[i].totbufs,
sum[i].maxsize,
sum[i].totsize);
ipcom_printf("======================================================\n");
ipcom_printf("%-30s%-8ld%-8ld%-8ld\n",
"TOTAL",
sum[ZEBOS_MAX - 1].totbufs,
sum[ZEBOS_MAX - 1].maxsize,
sum[ZEBOS_MAX - 1].totsize);
ipcom_free(sum);
}
#endif /* ZEBOS */
/* unknown command. */
else
ipcom_printf (MEM ": unknown command '%s'"IP_LF, argv[1]);
return 0;
}
#endif /* #if IPCOM_USE_SHELL >= IPCOM_SHELL_IPCOM && !defined(IP_PORT_LKM) */
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/