forked from Imagelibrary/rtems
2007-12-18 Joel Sherrill <joel.sherrill@oarcorp.com>
* libcsupport/Makefile.am, libcsupport/preinstall.am, libcsupport/src/malloc.c, libcsupport/src/mallocinfo.c, libmisc/Makefile.am, libmisc/shell/main_mallocinfo.c, libmisc/shell/shellconfig.h: Split malloc.c into multiple files with one function per file. Also split out statistics into a separate file which can be plugged in dynamically. Right now, it is always in. I suspect that splitting the file removed more code than leaving statistics in. I tinkered with malloc information command in the shell. I resurrected the malloc arena code as malloc boundary. This code is now compiled all the time even though it does not appear to work. * libcsupport/include/rtems/malloc.h, libcsupport/src/_calloc_r.c, libcsupport/src/_free_r.c, libcsupport/src/_malloc_r.c, libcsupport/src/_realloc_r.c, libcsupport/src/calloc.c, libcsupport/src/free.c, libcsupport/src/malloc_boundary.c, libcsupport/src/malloc_get_statistics.c, libcsupport/src/malloc_initialize.c, libcsupport/src/malloc_p.h, libcsupport/src/malloc_report_statistics.c, libcsupport/src/malloc_report_statistics_plugin.c, libcsupport/src/malloc_statistics_helpers.c, libcsupport/src/malloc_walk.c, libcsupport/src/realloc.c, libmisc/shell/main_perioduse.c: New files.
This commit is contained in:
@@ -1,3 +1,28 @@
|
||||
2007-12-18 Joel Sherrill <joel.sherrill@oarcorp.com>
|
||||
|
||||
* libcsupport/Makefile.am, libcsupport/preinstall.am,
|
||||
libcsupport/src/malloc.c, libcsupport/src/mallocinfo.c,
|
||||
libmisc/Makefile.am, libmisc/shell/main_mallocinfo.c,
|
||||
libmisc/shell/shellconfig.h: Split malloc.c into multiple files with
|
||||
one function per file. Also split out statistics into a separate file
|
||||
which can be plugged in dynamically. Right now, it is always in. I
|
||||
suspect that splitting the file removed more code than leaving
|
||||
statistics in. I tinkered with malloc information command in the
|
||||
shell. I resurrected the malloc arena code as malloc boundary. This
|
||||
code is now compiled all the time even though it does not appear to
|
||||
work.
|
||||
* libcsupport/include/rtems/malloc.h, libcsupport/src/_calloc_r.c,
|
||||
libcsupport/src/_free_r.c, libcsupport/src/_malloc_r.c,
|
||||
libcsupport/src/_realloc_r.c, libcsupport/src/calloc.c,
|
||||
libcsupport/src/free.c, libcsupport/src/malloc_boundary.c,
|
||||
libcsupport/src/malloc_get_statistics.c,
|
||||
libcsupport/src/malloc_initialize.c, libcsupport/src/malloc_p.h,
|
||||
libcsupport/src/malloc_report_statistics.c,
|
||||
libcsupport/src/malloc_report_statistics_plugin.c,
|
||||
libcsupport/src/malloc_statistics_helpers.c,
|
||||
libcsupport/src/malloc_walk.c, libcsupport/src/realloc.c,
|
||||
libmisc/shell/main_perioduse.c: New files.
|
||||
|
||||
2007-12-17 Joel Sherrill <joel.sherrill@oarcorp.com>
|
||||
|
||||
* libmisc/shell/main_alias.c, libmisc/shell/main_blksync.c,
|
||||
|
||||
@@ -24,7 +24,7 @@ include_rtems_motorola_HEADERS = include/motorola/mc68230.h \
|
||||
## rtems
|
||||
include_rtems_HEADERS += include/rtems/assoc.h include/rtems/error.h \
|
||||
include/rtems/libcsupport.h include/rtems/libio.h include/rtems/libio_.h \
|
||||
include/rtems/termiostypes.h
|
||||
include/rtems/malloc.h include/rtems/termiostypes.h
|
||||
|
||||
## zilog
|
||||
|
||||
@@ -78,8 +78,12 @@ ID_C_FILES = src/getegid.c src/geteuid.c src/getgid.c src/getgroups.c \
|
||||
src/getlogin.c src/getpgrp.c src/getpid.c src/getppid.c src/getuid.c \
|
||||
src/setpgid.c src/setsid.c
|
||||
|
||||
MALLOC_C_FILES = src/malloc.c src/mallocfreespace.c src/mallocinfo.c \
|
||||
src/__brk.c src/__sbrk.c
|
||||
MALLOC_C_FILES = src/malloc_initialize.c src/calloc.c src/malloc.c \
|
||||
src/realloc.c src/_calloc_r.c src/free.c src/_free_r.c src/_malloc_r.c \
|
||||
src/_realloc_r.c src/__brk.c src/__sbrk.c src/mallocfreespace.c \
|
||||
src/mallocinfo.c src/malloc_walk.c src/malloc_get_statistics.c \
|
||||
src/malloc_report_statistics.c src/malloc_report_statistics_plugin.c \
|
||||
src/malloc_statistics_helpers.c src/malloc_boundary.c
|
||||
|
||||
PASSWORD_GROUP_C_FILES = src/getpwent.c
|
||||
|
||||
@@ -104,7 +108,7 @@ libcsupport_a_SOURCES += $(LIBC_GLUE_C_FILES) $(PASSWORD_GROUP_C_FILES) \
|
||||
$(TERMIOS_C_FILES) src/getpagesize.c
|
||||
endif
|
||||
|
||||
EXTRA_DIST = src/TODO src/CASES src/README
|
||||
EXTRA_DIST = src/TODO src/CASES src/README src/malloc_p.h
|
||||
|
||||
include $(srcdir)/preinstall.am
|
||||
include $(top_srcdir)/automake/local.am
|
||||
|
||||
101
cpukit/libcsupport/include/rtems/malloc.h
Normal file
101
cpukit/libcsupport/include/rtems/malloc.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* @file rtems/malloc.h
|
||||
*/
|
||||
|
||||
/*
|
||||
* RTEMS Malloc Extensions
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1997.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may in
|
||||
* the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $ld:
|
||||
*/
|
||||
|
||||
#ifndef _RTEMS_MALLOC_H
|
||||
#define _RTEMS_MALLOC_H
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Malloc Statistics Structure
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t space_available; /* current size of malloc area */
|
||||
uint32_t malloc_calls; /* # calls to malloc */
|
||||
uint32_t free_calls;
|
||||
uint32_t realloc_calls;
|
||||
uint32_t calloc_calls;
|
||||
uint32_t max_depth; /* most ever malloc'd at 1 time */
|
||||
uintmax_t lifetime_allocated;
|
||||
uintmax_t lifetime_freed;
|
||||
} rtems_malloc_statistics_t;
|
||||
|
||||
/*
|
||||
* Malloc statistics plugin
|
||||
*/
|
||||
typedef struct {
|
||||
void (*initialize)(void);
|
||||
void (*at_malloc)(void *);
|
||||
void (*at_free)(void *);
|
||||
} rtems_malloc_statististics_functions_t;
|
||||
|
||||
extern rtems_malloc_statististics_functions_t
|
||||
rtems_malloc_statistics_helpers_table;
|
||||
extern rtems_malloc_statististics_functions_t *rtems_malloc_statistics_helpers;
|
||||
|
||||
/*
|
||||
* Malloc boundary support plugin
|
||||
*/
|
||||
typedef struct {
|
||||
void (*initialize)(void);
|
||||
uint32_t (*overhead)(void);
|
||||
void (*at_malloc)(void *, size_t);
|
||||
void (*at_free)(void *);
|
||||
void (*at_realloc)(void *, size_t);
|
||||
} rtems_malloc_boundary_functions_t;
|
||||
|
||||
extern rtems_malloc_boundary_functions_t rtems_malloc_boundary_helpers_table;
|
||||
extern rtems_malloc_boundary_functions_t *rtems_malloc_boundary_helpers;
|
||||
|
||||
|
||||
|
||||
/** @brief Print Malloc Statistic Usage Report
|
||||
*
|
||||
* This method fills in the called provided malloc statistics area.
|
||||
*
|
||||
* @return This method returns 0 if successful and -1 on error.
|
||||
*/
|
||||
int malloc_get_statistics(
|
||||
rtems_malloc_statistics_t *stats
|
||||
);
|
||||
|
||||
/** @brief Print Malloc Statistic Usage Report
|
||||
*
|
||||
* This method prints a malloc statistics report.
|
||||
*
|
||||
* @note It uses printk to print the report.
|
||||
*/
|
||||
void malloc_report_statistics(void);
|
||||
|
||||
/** @brief Print Malloc Statistic Usage Report
|
||||
*
|
||||
* This method prints a malloc statistics report.
|
||||
*
|
||||
* @param[in] context is the context to pass to the print handler
|
||||
* @param[in] print is the print handler
|
||||
*
|
||||
* @note It uses the CALLER's routine to print the report.
|
||||
*/
|
||||
void malloc_report_statistics_with_plugin(
|
||||
void *context,
|
||||
rtems_printk_plugin_t print
|
||||
);
|
||||
|
||||
#endif
|
||||
@@ -8,10 +8,24 @@ endif
|
||||
PREINSTALL_DIRS =
|
||||
DISTCLEANFILES = $(PREINSTALL_DIRS)
|
||||
|
||||
all-local: $(TMPINSTALL_FILES)
|
||||
|
||||
TMPINSTALL_FILES =
|
||||
CLEANFILES = $(TMPINSTALL_FILES)
|
||||
|
||||
all-am: $(PREINSTALL_FILES)
|
||||
|
||||
PREINSTALL_FILES =
|
||||
CLEANFILES = $(PREINSTALL_FILES)
|
||||
CLEANFILES += $(PREINSTALL_FILES)
|
||||
|
||||
$(PROJECT_LIB)/$(dirstamp):
|
||||
@$(MKDIR_P) $(PROJECT_LIB)
|
||||
@: > $(PROJECT_LIB)/$(dirstamp)
|
||||
PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp)
|
||||
|
||||
$(PROJECT_LIB)/libcsupport.a: libcsupport.a $(PROJECT_LIB)/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_LIB)/libcsupport.a
|
||||
TMPINSTALL_FILES += $(PROJECT_LIB)/libcsupport.a
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/$(dirstamp):
|
||||
@$(MKDIR_P) $(PROJECT_INCLUDE)/rtems
|
||||
@@ -87,6 +101,10 @@ $(PROJECT_INCLUDE)/rtems/libio_.h: include/rtems/libio_.h $(PROJECT_INCLUDE)/rte
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/libio_.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/libio_.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/malloc.h: include/rtems/malloc.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/malloc.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/malloc.h
|
||||
|
||||
$(PROJECT_INCLUDE)/rtems/termiostypes.h: include/rtems/termiostypes.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/termiostypes.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/termiostypes.h
|
||||
|
||||
30
cpukit/libcsupport/src/_calloc_r.c
Normal file
30
cpukit/libcsupport/src/_calloc_r.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* _calloc_r Implementation
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2007.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef RTEMS_NEWLIB
|
||||
#include <sys/reent.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void *_calloc_r(
|
||||
struct _reent *ignored,
|
||||
size_t elements,
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
return calloc( elements, size );
|
||||
}
|
||||
#endif
|
||||
29
cpukit/libcsupport/src/_free_r.c
Normal file
29
cpukit/libcsupport/src/_free_r.c
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* _free_r Implementation
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2007.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef RTEMS_NEWLIB
|
||||
#include <sys/reent.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void _free_r(
|
||||
struct _reent *ignored,
|
||||
void *ptr
|
||||
)
|
||||
{
|
||||
free( ptr );
|
||||
}
|
||||
#endif
|
||||
29
cpukit/libcsupport/src/_malloc_r.c
Normal file
29
cpukit/libcsupport/src/_malloc_r.c
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* _malloc_r Implementation
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2007.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef RTEMS_NEWLIB
|
||||
#include <sys/reent.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void *_malloc_r(
|
||||
struct _reent *ignored,
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
return malloc( size );
|
||||
}
|
||||
#endif
|
||||
30
cpukit/libcsupport/src/_realloc_r.c
Normal file
30
cpukit/libcsupport/src/_realloc_r.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* _realloc_r Implementation
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2007.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef RTEMS_NEWLIB
|
||||
#include <sys/reent.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void *_realloc_r(
|
||||
struct _reent *ignored,
|
||||
void *ptr,
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
return realloc( ptr, size );
|
||||
}
|
||||
#endif
|
||||
41
cpukit/libcsupport/src/calloc.c
Normal file
41
cpukit/libcsupport/src/calloc.c
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* calloc()
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2007.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef RTEMS_NEWLIB
|
||||
#include "malloc_p.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void *calloc(
|
||||
size_t nelem,
|
||||
size_t elsize
|
||||
)
|
||||
{
|
||||
register char *cptr;
|
||||
int length;
|
||||
|
||||
MSBUMP(calloc_calls, 1);
|
||||
|
||||
length = nelem * elsize;
|
||||
cptr = malloc( length );
|
||||
if ( cptr )
|
||||
memset( cptr, '\0', length );
|
||||
|
||||
MSBUMP(malloc_calls, -1); /* subtract off the malloc */
|
||||
|
||||
return cptr;
|
||||
}
|
||||
#endif
|
||||
69
cpukit/libcsupport/src/free.c
Normal file
69
cpukit/libcsupport/src/free.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* calloc()
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2007.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef RTEMS_NEWLIB
|
||||
#include "malloc_p.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void free(
|
||||
void *ptr
|
||||
)
|
||||
{
|
||||
MSBUMP(free_calls, 1);
|
||||
|
||||
if ( !ptr )
|
||||
return;
|
||||
|
||||
#if defined(RTEMS_HEAP_DEBUG)
|
||||
_Protected_heap_Walk( &RTEMS_Malloc_Heap, 0, FALSE );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Do not attempt to free memory if in a critical section or ISR.
|
||||
*/
|
||||
|
||||
if (_System_state_Is_up(_System_state_Get())) {
|
||||
if ((_Thread_Dispatch_disable_level > 0) || (_ISR_Nest_level > 0)) {
|
||||
Chain_Append(&RTEMS_Malloc_GC_list, (Chain_Node *)ptr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(RTEMS_MALLOC_BOUNDARY_HELPERS)
|
||||
/*
|
||||
* If configured, check the boundary area
|
||||
*/
|
||||
if ( rtems_malloc_boundary_helpers )
|
||||
(*rtems_malloc_boundary_helpers->at_free)(ptr);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If configured, update the statistics
|
||||
*/
|
||||
if ( rtems_malloc_statistics_helpers )
|
||||
(*rtems_malloc_statistics_helpers->at_free)(ptr);
|
||||
|
||||
if ( !_Protected_heap_Free( &RTEMS_Malloc_Heap, ptr ) ) {
|
||||
printk( "Program heap: free of bad pointer %p -- range %p - %p \n",
|
||||
ptr,
|
||||
RTEMS_Malloc_Heap.start,
|
||||
RTEMS_Malloc_Heap.end
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -2,7 +2,7 @@
|
||||
* RTEMS Malloc Family Implementation
|
||||
*
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1999.
|
||||
* COPYRIGHT (c) 1989-2007.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
@@ -16,201 +16,12 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
|
||||
#include <rtems.h>
|
||||
#include <rtems/libcsupport.h>
|
||||
#include <rtems/score/protectedheap.h>
|
||||
#ifdef RTEMS_NEWLIB
|
||||
#include <sys/reent.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <unistd.h> /* sbrk(2) */
|
||||
#include <inttypes.h>
|
||||
#include "malloc_p.h"
|
||||
|
||||
#include <rtems/chain.h>
|
||||
|
||||
#ifndef HAVE_UINTMAX_T
|
||||
/* Fall back to unsigned long if uintmax_t is not available */
|
||||
#define unsigned long uintmax_t
|
||||
|
||||
#ifndef PRIuMAX
|
||||
#define PRIuMAX "lu"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
Heap_Control RTEMS_Malloc_Heap;
|
||||
Chain_Control RTEMS_Malloc_GC_list;
|
||||
|
||||
/* rtems_id RTEMS_Malloc_Heap; */
|
||||
size_t RTEMS_Malloc_Sbrk_amount;
|
||||
|
||||
#ifdef RTEMS_DEBUG
|
||||
#define MALLOC_STATS
|
||||
#define MALLOC_DIRTY
|
||||
/*#define MALLOC_ARENA_CHECK
|
||||
void checkMallocArena(void); */
|
||||
#endif
|
||||
|
||||
#ifdef MALLOC_STATS
|
||||
#define MSBUMP(f,n) rtems_malloc_stats.f += (n)
|
||||
|
||||
struct {
|
||||
uint32_t space_available; /* current size of malloc area */
|
||||
uint32_t malloc_calls; /* # calls to malloc */
|
||||
uint32_t free_calls;
|
||||
uint32_t realloc_calls;
|
||||
uint32_t calloc_calls;
|
||||
uint32_t max_depth; /* most ever malloc'd at 1 time */
|
||||
uintmax_t lifetime_allocated;
|
||||
uintmax_t lifetime_freed;
|
||||
} rtems_malloc_stats;
|
||||
|
||||
#else /* No rtems_malloc_stats */
|
||||
#define MSBUMP(f,n)
|
||||
#endif
|
||||
|
||||
void RTEMS_Malloc_Initialize(
|
||||
void *start,
|
||||
size_t length,
|
||||
size_t sbrk_amount
|
||||
)
|
||||
{
|
||||
uint32_t status;
|
||||
void *starting_address;
|
||||
uintptr_t old_address;
|
||||
uintptr_t uaddress;
|
||||
|
||||
/*
|
||||
* Initialize the garbage collection list to start with nothing on it.
|
||||
*/
|
||||
Chain_Initialize_empty(&RTEMS_Malloc_GC_list);
|
||||
|
||||
/*
|
||||
* If the starting address is 0 then we are to attempt to
|
||||
* get length worth of memory using sbrk. Make sure we
|
||||
* align the address that we get back.
|
||||
*/
|
||||
|
||||
starting_address = start;
|
||||
RTEMS_Malloc_Sbrk_amount = sbrk_amount;
|
||||
|
||||
if (!starting_address) {
|
||||
uaddress = (uintptr_t)sbrk(length);
|
||||
|
||||
if (uaddress == (uintptr_t) -1) {
|
||||
rtems_fatal_error_occurred( RTEMS_NO_MEMORY );
|
||||
/* DOES NOT RETURN!!! */
|
||||
}
|
||||
|
||||
if (uaddress & (CPU_HEAP_ALIGNMENT-1)) {
|
||||
old_address = uaddress;
|
||||
uaddress = (uaddress + CPU_HEAP_ALIGNMENT) & ~(CPU_HEAP_ALIGNMENT-1);
|
||||
|
||||
/*
|
||||
* adjust the length by whatever we aligned by
|
||||
*/
|
||||
|
||||
length -= uaddress - old_address;
|
||||
}
|
||||
|
||||
starting_address = (void *)uaddress;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the BSP is not clearing out the workspace, then it is most likely
|
||||
* not clearing out the initial memory for the heap. There is no
|
||||
* standard supporting zeroing out the heap memory. But much code
|
||||
* with UNIX history seems to assume that memory malloc'ed during
|
||||
* initialization (before any free's) is zero'ed. This is true most
|
||||
* of the time under UNIX because zero'ing memory when it is first
|
||||
* given to a process eliminates the chance of a process seeing data
|
||||
* left over from another process. This would be a security violation.
|
||||
*/
|
||||
|
||||
if ( rtems_configuration_get_do_zero_of_workspace() )
|
||||
memset( starting_address, 0, length );
|
||||
|
||||
/*
|
||||
* Unfortunately we cannot use assert if this fails because if this
|
||||
* has failed we do not have a heap and if we do not have a heap
|
||||
* STDIO cannot work because there will be no buffers.
|
||||
*/
|
||||
|
||||
status = _Protected_heap_Initialize(
|
||||
&RTEMS_Malloc_Heap,
|
||||
starting_address,
|
||||
length,
|
||||
CPU_HEAP_ALIGNMENT
|
||||
);
|
||||
if ( !status )
|
||||
rtems_fatal_error_occurred( status );
|
||||
|
||||
#if defined(RTEMS_HEAP_DEBUG)
|
||||
if ( _Protected_heap_Walk( &RTEMS_Malloc_Heap, 0, FALSE ) ) {
|
||||
printk( "Malloc heap not initialized correctly\n" );
|
||||
rtems_print_buffer( start, 32 );
|
||||
printk( "\n" );
|
||||
rtems_print_buffer( (start + length) - 48, 48 );
|
||||
rtems_fatal_error_occurred( RTEMS_NO_MEMORY );
|
||||
}
|
||||
#endif
|
||||
#ifdef MALLOC_STATS
|
||||
/* zero all the stats */
|
||||
(void) memset( &rtems_malloc_stats, 0, sizeof(rtems_malloc_stats) );
|
||||
#endif
|
||||
|
||||
MSBUMP(space_available, length);
|
||||
}
|
||||
|
||||
#ifdef RTEMS_NEWLIB
|
||||
void *malloc(
|
||||
size_t size
|
||||
)
|
||||
@@ -248,15 +59,21 @@ void *malloc(
|
||||
while ((to_be_freed = Chain_Get(&RTEMS_Malloc_GC_list)) != NULL)
|
||||
free(to_be_freed);
|
||||
|
||||
#if defined(RTEMS_MALLOC_BOUNDARY_HELPERS)
|
||||
/*
|
||||
* If the support for a boundary area at the end of the heap
|
||||
* block allocated is turned on, then adjust the size.
|
||||
*/
|
||||
if (rtems_malloc_boundary_helpers)
|
||||
size += (*rtems_malloc_boundary_helpers->overhead)();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Try to give a segment in the current heap if there is not
|
||||
* enough space then try to grow the heap.
|
||||
* If this fails then return a NULL pointer.
|
||||
*/
|
||||
|
||||
#ifdef MALLOC_ARENA_CHECK
|
||||
size += sizeof(struct mallocNode) + SENTINELSIZE;
|
||||
#endif
|
||||
return_this = _Protected_heap_Allocate( &RTEMS_Malloc_Heap, size );
|
||||
|
||||
if ( !return_this ) {
|
||||
@@ -293,324 +110,28 @@ void *malloc(
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MALLOC_STATS
|
||||
if (return_this)
|
||||
{
|
||||
size_t actual_size = 0;
|
||||
uint32_t current_depth;
|
||||
void *ptr = return_this;
|
||||
_Protected_heap_Get_block_size(&RTEMS_Malloc_Heap, ptr, &actual_size);
|
||||
MSBUMP(lifetime_allocated, actual_size);
|
||||
current_depth = rtems_malloc_stats.lifetime_allocated -
|
||||
rtems_malloc_stats.lifetime_freed;
|
||||
if (current_depth > rtems_malloc_stats.max_depth)
|
||||
rtems_malloc_stats.max_depth = current_depth;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MALLOC_DIRTY
|
||||
(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;
|
||||
}
|
||||
|
||||
void *calloc(
|
||||
size_t nelem,
|
||||
size_t elsize
|
||||
)
|
||||
{
|
||||
register char *cptr;
|
||||
int length;
|
||||
|
||||
MSBUMP(calloc_calls, 1);
|
||||
|
||||
length = nelem * elsize;
|
||||
cptr = malloc( length );
|
||||
if ( cptr )
|
||||
memset( cptr, '\0', length );
|
||||
|
||||
MSBUMP(malloc_calls, -1); /* subtract off the malloc */
|
||||
|
||||
return cptr;
|
||||
}
|
||||
|
||||
void *realloc(
|
||||
void *ptr,
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
size_t old_size;
|
||||
char *new_area;
|
||||
|
||||
MSBUMP(realloc_calls, 1);
|
||||
|
||||
/*
|
||||
* Do not attempt to allocate memory if in a critical section or ISR.
|
||||
* If the user wants us to dirty the allocated memory, then do it.
|
||||
*/
|
||||
|
||||
if (_System_state_Is_up(_System_state_Get())) {
|
||||
if (_Thread_Dispatch_disable_level > 0)
|
||||
return (void *) 0;
|
||||
|
||||
if (_ISR_Nest_level > 0)
|
||||
return (void *) 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Continue with realloc().
|
||||
*/
|
||||
if ( !ptr )
|
||||
return malloc( size );
|
||||
|
||||
if ( !size ) {
|
||||
free( ptr );
|
||||
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
|
||||
if ( _Protected_heap_Resize_block( &RTEMS_Malloc_Heap, ptr, size ) ) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
new_area = malloc( size );
|
||||
|
||||
MSBUMP(malloc_calls, -1); /* subtract off the malloc */
|
||||
|
||||
/*
|
||||
* There used to be a free on this error case but it is wrong to
|
||||
* free the memory per OpenGroup Single UNIX Specification V2
|
||||
* and the C Standard.
|
||||
*/
|
||||
|
||||
if ( !new_area ) {
|
||||
return (void *) 0;
|
||||
}
|
||||
|
||||
if ( !_Protected_heap_Get_block_size(&RTEMS_Malloc_Heap, ptr, &old_size) ) {
|
||||
errno = EINVAL;
|
||||
return (void *) 0;
|
||||
}
|
||||
|
||||
memcpy( new_area, ptr, (size < old_size) ? size : old_size );
|
||||
free( ptr );
|
||||
|
||||
return new_area;
|
||||
|
||||
}
|
||||
|
||||
void free(
|
||||
void *ptr
|
||||
)
|
||||
{
|
||||
MSBUMP(free_calls, 1);
|
||||
|
||||
if ( !ptr )
|
||||
return;
|
||||
|
||||
#if defined(RTEMS_HEAP_DEBUG)
|
||||
_Protected_heap_Walk( &RTEMS_Malloc_Heap, 0, FALSE );
|
||||
#ifdef MALLOC_DIRTY
|
||||
(void) memset(return_this, 0xCF, size);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Do not attempt to free memory if in a critical section or ISR.
|
||||
* If configured, update the statistics
|
||||
*/
|
||||
if ( rtems_malloc_statistics_helpers )
|
||||
(*rtems_malloc_statistics_helpers->at_malloc)(return_this);
|
||||
|
||||
if (_System_state_Is_up(_System_state_Get())) {
|
||||
if ((_Thread_Dispatch_disable_level > 0) || (_ISR_Nest_level > 0)) {
|
||||
Chain_Append(&RTEMS_Malloc_GC_list, (Chain_Node *)ptr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#if defined(RTEMS_MALLOC_BOUNDARY_HELPERS)
|
||||
/*
|
||||
* If configured, set the boundary area
|
||||
*/
|
||||
if (rtems_malloc_boundary_helpers)
|
||||
(*rtems_malloc_boundary_helpers->at_malloc)(return_this, size);
|
||||
#endif
|
||||
|
||||
#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;
|
||||
if (_Protected_heap_Get_block_size(&RTEMS_Malloc_Heap, ptr, &size) ) {
|
||||
MSBUMP(lifetime_freed, size);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( !_Protected_heap_Free( &RTEMS_Malloc_Heap, ptr ) ) {
|
||||
printk( "Program heap: free of bad pointer %p -- range %p - %p \n",
|
||||
ptr,
|
||||
RTEMS_Malloc_Heap.start,
|
||||
RTEMS_Malloc_Heap.end
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
#ifdef MALLOC_STATS
|
||||
/*
|
||||
* Dump the malloc statistics
|
||||
* May be called via atexit() (installable by our bsp) or
|
||||
* at any time by user
|
||||
*/
|
||||
|
||||
void malloc_dump(void)
|
||||
{
|
||||
uint32_t allocated = rtems_malloc_stats.lifetime_allocated -
|
||||
rtems_malloc_stats.lifetime_freed;
|
||||
|
||||
printf("Malloc stats\n");
|
||||
printf(" avail:%"PRIu32"k allocated:%"PRIu32"k (%"PRId32"%%) "
|
||||
"max:%"PRIu32"k (%"PRIu32"%%)"
|
||||
" lifetime:%"PRIuMAX"k freed:%"PRIuMAX"k\n",
|
||||
rtems_malloc_stats.space_available / 1024,
|
||||
allocated / 1024,
|
||||
/* avoid float! */
|
||||
(allocated * 100) / rtems_malloc_stats.space_available,
|
||||
rtems_malloc_stats.max_depth / 1024,
|
||||
(rtems_malloc_stats.max_depth * 100) / rtems_malloc_stats.space_available,
|
||||
rtems_malloc_stats.lifetime_allocated / 1024,
|
||||
rtems_malloc_stats.lifetime_freed / 1024
|
||||
);
|
||||
printf(" Call counts: malloc:%"PRIu32" free:%"PRIu32" realloc:%"PRIu32" calloc:%"PRIu32"\n",
|
||||
rtems_malloc_stats.malloc_calls,
|
||||
rtems_malloc_stats.free_calls,
|
||||
rtems_malloc_stats.realloc_calls,
|
||||
rtems_malloc_stats.calloc_calls);
|
||||
}
|
||||
|
||||
|
||||
void malloc_walk(size_t source, size_t printf_enabled)
|
||||
{
|
||||
_Protected_heap_Walk( &RTEMS_Malloc_Heap, source, printf_enabled );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void malloc_dump(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void malloc_walk(size_t source, size_t printf_enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* "Reentrant" versions of the above routines implemented above.
|
||||
*/
|
||||
|
||||
#ifdef RTEMS_NEWLIB
|
||||
void *_malloc_r(
|
||||
struct _reent *ignored,
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
return malloc( size );
|
||||
}
|
||||
|
||||
void *_calloc_r(
|
||||
struct _reent *ignored,
|
||||
size_t nelem,
|
||||
size_t elsize
|
||||
)
|
||||
{
|
||||
return calloc( nelem, elsize );
|
||||
}
|
||||
|
||||
void *_realloc_r(
|
||||
struct _reent *ignored,
|
||||
void *ptr,
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
return realloc( ptr, size );
|
||||
}
|
||||
|
||||
void _free_r(
|
||||
struct _reent *ignored,
|
||||
void *ptr
|
||||
)
|
||||
{
|
||||
free( ptr );
|
||||
return return_this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
194
cpukit/libcsupport/src/malloc_boundary.c
Normal file
194
cpukit/libcsupport/src/malloc_boundary.c
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* RTEMS Malloc Block Boundary Integrity Checker
|
||||
*
|
||||
* WARNING!!! WARNING!!! WARNING!!! WARNING!!!
|
||||
* WARNING!!! WARNING!!! WARNING!!! WARNING!!!
|
||||
*
|
||||
* This file is built but never called. It is a first
|
||||
* step in reintegrating this functionality.
|
||||
* This code was disabled for a LONG time in malloc.c.
|
||||
* This is a restructured and slightly modified version
|
||||
* that should be able to be configured as a plugin BUT
|
||||
* it has not been tested recently. When it has been
|
||||
* tested again, please remove this comment.
|
||||
*
|
||||
* JOEL: I have not analyzed this code in terms of
|
||||
* the heap changes post 4.6. It is possible
|
||||
* that that way the boundary area is carved
|
||||
* off breaks the alignment.
|
||||
*
|
||||
* WARNING!!! WARNING!!! WARNING!!! WARNING!!!
|
||||
* WARNING!!! WARNING!!! WARNING!!! WARNING!!!
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2007.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "malloc_p.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef RTEMS_NEWLIB
|
||||
|
||||
#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;
|
||||
};
|
||||
|
||||
struct mallocNode mallocNodeHead;
|
||||
|
||||
void rtems_malloc_boundary_initialize(void)
|
||||
{
|
||||
mallocNodeHead.back = &mallocNodeHead;
|
||||
mallocNodeHead.forw = &mallocNodeHead;
|
||||
}
|
||||
|
||||
uint32_t rtems_malloc_boundary_overhead(void)
|
||||
{
|
||||
return sizeof(struct mallocNode) + SENTINELSIZE;
|
||||
}
|
||||
|
||||
void rtems_malloc_boundary_at_malloc(
|
||||
void *pointer,
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
void *return_this;
|
||||
struct mallocNode *mp = (struct mallocNode *)pointer;
|
||||
int *fp, *nfp, i;
|
||||
|
||||
_RTEMS_Lock_allocator();
|
||||
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_Unlock_allocator();
|
||||
}
|
||||
|
||||
void reportMallocError(const char *msg, struct mallocNode *mp);
|
||||
|
||||
void rtems_malloc_boundary_at_free(
|
||||
void *pointer
|
||||
)
|
||||
{
|
||||
struct mallocNode *mp = (struct mallocNode *)pointer - 1;
|
||||
struct mallocNode *mp1;
|
||||
|
||||
_RTEMS_Lock_allocator();
|
||||
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;
|
||||
pointer = mp;
|
||||
_RTEMS_Unlock_allocator();
|
||||
}
|
||||
|
||||
void rtems_malloc_boundary_at_realloc(
|
||||
void *pointer,
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
/* this needs to be implemented */
|
||||
}
|
||||
|
||||
/*
|
||||
* Malloc boundary support plugin
|
||||
*/
|
||||
rtems_malloc_boundary_functions_t rtems_malloc_boundary_functions_table = {
|
||||
rtems_malloc_boundary_initialize,
|
||||
rtems_malloc_boundary_overhead,
|
||||
rtems_malloc_boundary_at_malloc,
|
||||
rtems_malloc_boundary_at_free,
|
||||
rtems_malloc_boundary_at_realloc,
|
||||
};
|
||||
|
||||
rtems_malloc_boundary_functions_t *rtems_malloc_boundary_helpers = NULL;
|
||||
/* &rtems_malloc_boundary_functions_table; */
|
||||
|
||||
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:%p mp->forw:%p mp->forw->back:%p "
|
||||
"mp->back:%p mp->back->forw:%p\n",
|
||||
mp, mp->forw, mp->forw->back, mp->back, mp->back->forw);
|
||||
if (mp->memory != (mp + 1))
|
||||
ind += sprintf(cbuf+ind, "mp+1:%p ", mp + 1);
|
||||
ind += sprintf(cbuf+ind, "mp->memory:%p 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);
|
||||
}
|
||||
|
||||
void checkMallocArena(void)
|
||||
{
|
||||
struct mallocNode *mp;
|
||||
|
||||
_RTEMS_Lock_allocator();
|
||||
for ( mp = mallocNodeHead.forw; mp != &mallocNodeHead ; mp = mp->forw ) {
|
||||
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);
|
||||
}
|
||||
_RTEMS_Unlock_allocator();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
31
cpukit/libcsupport/src/malloc_get_statistics.c
Normal file
31
cpukit/libcsupport/src/malloc_get_statistics.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* malloc_get_statistics Implementation
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2007.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef RTEMS_NEWLIB
|
||||
#include "malloc_p.h"
|
||||
|
||||
int malloc_get_statistics(
|
||||
rtems_malloc_statistics_t *stats
|
||||
)
|
||||
{
|
||||
if ( !stats )
|
||||
return -1;
|
||||
*stats = rtems_malloc_statistics;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
128
cpukit/libcsupport/src/malloc_initialize.c
Normal file
128
cpukit/libcsupport/src/malloc_initialize.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* RTEMS Malloc Family Implementation --Initialization
|
||||
*
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2007.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/malloc.h>
|
||||
#include "malloc_p.h"
|
||||
|
||||
Heap_Control RTEMS_Malloc_Heap;
|
||||
Chain_Control RTEMS_Malloc_GC_list;
|
||||
size_t RTEMS_Malloc_Sbrk_amount;
|
||||
rtems_malloc_statistics_t rtems_malloc_statistics;
|
||||
|
||||
void RTEMS_Malloc_Initialize(
|
||||
void *start,
|
||||
size_t length,
|
||||
size_t sbrk_amount
|
||||
)
|
||||
{
|
||||
uint32_t status;
|
||||
void *starting_address;
|
||||
uintptr_t old_address;
|
||||
uintptr_t uaddress;
|
||||
|
||||
#if defined(RTEMS_MALLOC_BOUNDARY_HELPERS)
|
||||
/*
|
||||
* If configured, initialize the boundary support
|
||||
*/
|
||||
if (rtems_malloc_boundary_helpers)
|
||||
(*rtems_malloc_boundary_helpers->initialize)();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If configured, initialize the statistics support
|
||||
*/
|
||||
if ( rtems_malloc_statistics_helpers )
|
||||
(*rtems_malloc_statistics_helpers->initialize)();
|
||||
|
||||
/*
|
||||
* Initialize the garbage collection list to start with nothing on it.
|
||||
*/
|
||||
Chain_Initialize_empty(&RTEMS_Malloc_GC_list);
|
||||
|
||||
/*
|
||||
* If the starting address is 0 then we are to attempt to
|
||||
* get length worth of memory using sbrk. Make sure we
|
||||
* align the address that we get back.
|
||||
*/
|
||||
|
||||
starting_address = start;
|
||||
RTEMS_Malloc_Sbrk_amount = sbrk_amount;
|
||||
|
||||
if (!starting_address) {
|
||||
uaddress = (uintptr_t)sbrk(length);
|
||||
|
||||
if (uaddress == (uintptr_t) -1) {
|
||||
rtems_fatal_error_occurred( RTEMS_NO_MEMORY );
|
||||
/* DOES NOT RETURN!!! */
|
||||
}
|
||||
|
||||
if (uaddress & (CPU_HEAP_ALIGNMENT-1)) {
|
||||
old_address = uaddress;
|
||||
uaddress = (uaddress + CPU_HEAP_ALIGNMENT) & ~(CPU_HEAP_ALIGNMENT-1);
|
||||
|
||||
/*
|
||||
* adjust the length by whatever we aligned by
|
||||
*/
|
||||
length -= uaddress - old_address;
|
||||
}
|
||||
|
||||
starting_address = (void *)uaddress;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the BSP is not clearing out the workspace, then it is most likely
|
||||
* not clearing out the initial memory for the heap. There is no
|
||||
* standard supporting zeroing out the heap memory. But much code
|
||||
* with UNIX history seems to assume that memory malloc'ed during
|
||||
* initialization (before any free's) is zero'ed. This is true most
|
||||
* of the time under UNIX because zero'ing memory when it is first
|
||||
* given to a process eliminates the chance of a process seeing data
|
||||
* left over from another process. This would be a security violation.
|
||||
*/
|
||||
|
||||
if ( rtems_configuration_get_do_zero_of_workspace() )
|
||||
memset( starting_address, 0, length );
|
||||
|
||||
/*
|
||||
* Unfortunately we cannot use assert if this fails because if this
|
||||
* has failed we do not have a heap and if we do not have a heap
|
||||
* STDIO cannot work because there will be no buffers.
|
||||
*/
|
||||
|
||||
status = _Protected_heap_Initialize(
|
||||
&RTEMS_Malloc_Heap,
|
||||
starting_address,
|
||||
length,
|
||||
CPU_HEAP_ALIGNMENT
|
||||
);
|
||||
if ( !status )
|
||||
rtems_fatal_error_occurred( status );
|
||||
|
||||
#if defined(RTEMS_HEAP_DEBUG)
|
||||
if ( _Protected_heap_Walk( &RTEMS_Malloc_Heap, 0, FALSE ) ) {
|
||||
printk( "Malloc heap not initialized correctly\n" );
|
||||
rtems_print_buffer( start, 32 );
|
||||
printk( "\n" );
|
||||
rtems_print_buffer( (start + length) - 48, 48 );
|
||||
rtems_fatal_error_occurred( RTEMS_NO_MEMORY );
|
||||
}
|
||||
#endif
|
||||
|
||||
MSBUMP(space_available, length);
|
||||
}
|
||||
55
cpukit/libcsupport/src/malloc_p.h
Normal file
55
cpukit/libcsupport/src/malloc_p.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* RTEMS Malloc Family Internal Header
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2007.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
|
||||
#include <rtems.h>
|
||||
#include <rtems/libcsupport.h>
|
||||
#include <rtems/score/protectedheap.h>
|
||||
#include <rtems/malloc.h>
|
||||
|
||||
#ifdef RTEMS_NEWLIB
|
||||
#include <sys/reent.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <rtems/chain.h>
|
||||
|
||||
#ifndef HAVE_UINTMAX_T
|
||||
/* Fall back to unsigned long if uintmax_t is not available */
|
||||
#define unsigned long uintmax_t
|
||||
|
||||
#ifndef PRIuMAX
|
||||
#define PRIuMAX "lu"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Basic management data
|
||||
*/
|
||||
extern Heap_Control RTEMS_Malloc_Heap;
|
||||
extern Chain_Control RTEMS_Malloc_GC_list;
|
||||
extern size_t RTEMS_Malloc_Sbrk_amount;
|
||||
|
||||
/*
|
||||
* Malloc Statistics Structure
|
||||
*/
|
||||
extern rtems_malloc_statistics_t rtems_malloc_statistics;
|
||||
|
||||
#define MSBUMP(_f,_n) rtems_malloc_statistics._f += (_n)
|
||||
|
||||
/*
|
||||
* Dirty memory plugin
|
||||
*/
|
||||
#define MALLOC_DIRTY
|
||||
|
||||
26
cpukit/libcsupport/src/malloc_report_statistics.c
Normal file
26
cpukit/libcsupport/src/malloc_report_statistics.c
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* malloc_report_statistics Implementation
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2007.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef RTEMS_NEWLIB
|
||||
#include "malloc_p.h"
|
||||
|
||||
void malloc_report_statistics(void)
|
||||
{
|
||||
malloc_report_statistics_with_plugin( NULL, printk_plugin );
|
||||
}
|
||||
|
||||
#endif
|
||||
60
cpukit/libcsupport/src/malloc_report_statistics_plugin.c
Normal file
60
cpukit/libcsupport/src/malloc_report_statistics_plugin.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* malloc_report_statistics with plugin Implementation
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2007.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef RTEMS_NEWLIB
|
||||
#include "malloc_p.h"
|
||||
#include "inttypes.h"
|
||||
|
||||
void malloc_report_statistics_with_plugin(
|
||||
void *context,
|
||||
rtems_printk_plugin_t print
|
||||
)
|
||||
{
|
||||
rtems_malloc_statistics_t *s;
|
||||
uint32_t allocated;
|
||||
|
||||
s = &rtems_malloc_statistics;
|
||||
|
||||
allocated = s->lifetime_allocated - s->lifetime_freed;
|
||||
|
||||
(*print)(
|
||||
context,
|
||||
"Malloc statistics\n"
|
||||
" avail:%"PRIu32"k allocated:%"PRIu32"k (%"PRId32"%%) "
|
||||
"max:%"PRIu32"k (%"PRIu32"%%)"
|
||||
" lifetime:%"PRIuMAX"k freed:%"PRIuMAX"k\n",
|
||||
s->space_available / 1024,
|
||||
allocated / 1024,
|
||||
/* avoid float! */
|
||||
(allocated * 100) / s->space_available,
|
||||
s->max_depth / 1024,
|
||||
(s->max_depth * 100) / s->space_available,
|
||||
s->lifetime_allocated / 1024,
|
||||
s->lifetime_freed / 1024
|
||||
);
|
||||
(*print)(
|
||||
context,
|
||||
" Call counts: malloc:%"PRIu32" free:%"PRIu32
|
||||
" realloc:%"PRIu32" calloc:%"PRIu32"\n",
|
||||
s->malloc_calls,
|
||||
s->free_calls,
|
||||
s->realloc_calls,
|
||||
s->calloc_calls
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
79
cpukit/libcsupport/src/malloc_statistics_helpers.c
Normal file
79
cpukit/libcsupport/src/malloc_statistics_helpers.c
Normal file
@@ -0,0 +1,79 @@
|
||||
|
||||
/*
|
||||
* _calloc_r Implementation
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2007.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef RTEMS_NEWLIB
|
||||
#include "malloc_p.h"
|
||||
|
||||
#include <sys/reent.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
void rtems_malloc_statistics_initialize()
|
||||
{
|
||||
/*
|
||||
* Zero all the statistics
|
||||
*/
|
||||
(void) memset(&rtems_malloc_statistics, 0, sizeof(rtems_malloc_statistics));
|
||||
}
|
||||
|
||||
void rtems_malloc_statistics_at_malloc(
|
||||
void *pointer
|
||||
)
|
||||
{
|
||||
size_t actual_size = 0;
|
||||
uint32_t current_depth;
|
||||
rtems_malloc_statistics_t *s = &rtems_malloc_statistics;
|
||||
|
||||
if ( !pointer )
|
||||
return;
|
||||
|
||||
_Protected_heap_Get_block_size(&RTEMS_Malloc_Heap, pointer, &actual_size);
|
||||
|
||||
MSBUMP(lifetime_allocated, actual_size);
|
||||
|
||||
current_depth = s->lifetime_allocated - s->lifetime_freed;
|
||||
if (current_depth > s->max_depth)
|
||||
s->max_depth = current_depth;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the pointer is not in the heap, then we won't be able to get its
|
||||
* size and thus we skip updating the statistics.
|
||||
*/
|
||||
void rtems_malloc_statistics_at_free(
|
||||
void *pointer
|
||||
)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
if (_Protected_heap_Get_block_size(&RTEMS_Malloc_Heap, pointer, &size) ) {
|
||||
MSBUMP(lifetime_freed, size);
|
||||
}
|
||||
}
|
||||
|
||||
rtems_malloc_statististics_functions_t rtems_malloc_statistics_helpers_table = {
|
||||
rtems_malloc_statistics_initialize,
|
||||
rtems_malloc_statistics_at_malloc,
|
||||
rtems_malloc_statistics_at_free,
|
||||
};
|
||||
|
||||
rtems_malloc_statististics_functions_t *rtems_malloc_statistics_helpers =
|
||||
&rtems_malloc_statistics_helpers_table;
|
||||
|
||||
#endif
|
||||
|
||||
29
cpukit/libcsupport/src/malloc_walk.c
Normal file
29
cpukit/libcsupport/src/malloc_walk.c
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* malloc_walk Implementation
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2007.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef RTEMS_NEWLIB
|
||||
#include <sys/reent.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void malloc_walk(size_t source, size_t printf_enabled)
|
||||
{
|
||||
#if defined(RTEMS_DEBUG)
|
||||
_Protected_heap_Walk( &RTEMS_Malloc_Heap, source, printf_enabled );
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -31,8 +31,6 @@ int malloc_info(
|
||||
Heap_Information_block *the_info
|
||||
)
|
||||
{
|
||||
Heap_Information info;
|
||||
|
||||
if ( !the_info )
|
||||
return -1;
|
||||
|
||||
|
||||
103
cpukit/libcsupport/src/realloc.c
Normal file
103
cpukit/libcsupport/src/realloc.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* calloc()
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2007.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef RTEMS_NEWLIB
|
||||
#include "malloc_p.h"
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
void *realloc(
|
||||
void *ptr,
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
size_t old_size;
|
||||
char *new_area;
|
||||
size_t resize;
|
||||
|
||||
MSBUMP(realloc_calls, 1);
|
||||
|
||||
/*
|
||||
* Do not attempt to allocate memory if in a critical section or ISR.
|
||||
*/
|
||||
|
||||
if (_System_state_Is_up(_System_state_Get())) {
|
||||
if (_Thread_Dispatch_disable_level > 0)
|
||||
return (void *) 0;
|
||||
|
||||
if (_ISR_Nest_level > 0)
|
||||
return (void *) 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Continue with realloc().
|
||||
*/
|
||||
if ( !ptr )
|
||||
return malloc( size );
|
||||
|
||||
if ( !size ) {
|
||||
free( ptr );
|
||||
return (void *) 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If block boundary integrity checking is enabled, then
|
||||
* we need to account for the boundary memory again.
|
||||
*/
|
||||
resize = size;
|
||||
#if defined(RTEMS_MALLOC_BOUNDARY_HELPERS)
|
||||
if (rtems_malloc_boundary_helpers)
|
||||
resize += (*rtems_malloc_boundary_helpers->overhead)();
|
||||
#endif
|
||||
|
||||
if ( _Protected_heap_Resize_block( &RTEMS_Malloc_Heap, ptr, resize ) ) {
|
||||
#if defined(RTEMS_MALLOC_BOUNDARY_HELPERS)
|
||||
/*
|
||||
* Successful resize. Update the boundary on the same block.
|
||||
*/
|
||||
if (rtems_malloc_boundary_helpers)
|
||||
(*rtems_malloc_boundary_helpers->at_realloc)(ptr, resize);
|
||||
#endif
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* There used to be a free on this error case but it is wrong to
|
||||
* free the memory per OpenGroup Single UNIX Specification V2
|
||||
* and the C Standard.
|
||||
*/
|
||||
|
||||
new_area = malloc( size );
|
||||
|
||||
MSBUMP(malloc_calls, -1); /* subtract off the malloc */
|
||||
|
||||
if ( !new_area ) {
|
||||
return (void *) 0;
|
||||
}
|
||||
|
||||
if ( !_Protected_heap_Get_block_size(&RTEMS_Malloc_Heap, ptr, &old_size) ) {
|
||||
errno = EINVAL;
|
||||
return (void *) 0;
|
||||
}
|
||||
|
||||
memcpy( new_area, ptr, (size < old_size) ? size : old_size );
|
||||
free( ptr );
|
||||
|
||||
return new_area;
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -77,12 +77,12 @@ libshell_a_SOURCES = shell/cat_file.c shell/cmds.c shell/internal.h \
|
||||
shell/main_mdump.c shell/main_medit.c shell/main_mfill.c \
|
||||
shell/main_mkdir.c shell/main_mount.c $(shell_mount_fs) \
|
||||
shell/main_mount_msdos.c shell/main_mmove.c shell/main_msdosfmt.c \
|
||||
shell/main_mwdump.c shell/main_pwd.c shell/main_rm.c shell/main_rmdir.c \
|
||||
shell/main_stackuse.c shell/main_tty.c shell/main_umask.c \
|
||||
shell/main_unmount.c shell/main_blksync.c shell/main_whoami.c \
|
||||
shell/shell.c shell/shell_cmdset.c shell/shellconfig.c \
|
||||
shell/shellconfig.h shell/shell.h shell/shell_makeargs.c \
|
||||
shell/str2int.c shell/write_file.c
|
||||
shell/main_mwdump.c shell/main_perioduse.c shell/main_pwd.c \
|
||||
shell/main_rm.c shell/main_rmdir.c shell/main_stackuse.c \
|
||||
shell/main_tty.c shell/main_umask.c shell/main_unmount.c \
|
||||
shell/main_blksync.c shell/main_whoami.c shell/shell.c \
|
||||
shell/shell_cmdset.c shell/shellconfig.c shell/shellconfig.h \
|
||||
shell/shell.h shell/shell_makeargs.c shell/str2int.c shell/write_file.c
|
||||
endif
|
||||
|
||||
EXTRA_DIST += shell/README
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/malloc.h>
|
||||
#include <rtems/shell.h>
|
||||
#include "internal.h"
|
||||
|
||||
@@ -39,8 +40,8 @@ static void printit(
|
||||
}
|
||||
|
||||
int rtems_shell_main_malloc_info(
|
||||
int argc,
|
||||
char * argv[]
|
||||
int argc,
|
||||
char *argv[]
|
||||
)
|
||||
{
|
||||
if ( argc == 2 ) {
|
||||
@@ -51,19 +52,21 @@ int rtems_shell_main_malloc_info(
|
||||
printit( "free", &info.Free );
|
||||
printit( "used", &info.Used );
|
||||
return 0;
|
||||
} else if ( !strcmp( argv[1], "dump" ) ) {
|
||||
extern void malloc_dump();
|
||||
malloc_dump();
|
||||
} else if ( !strcmp( argv[1], "stats" ) ) {
|
||||
malloc_report_statistics_with_plugin(
|
||||
stdout,
|
||||
(rtems_printk_plugin_t) fprintf
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fprintf( stderr, "subcommands info or dump\n" );
|
||||
fprintf( stderr, "subcommands info or stats\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
rtems_shell_cmd_t rtems_shell_MALLOC_INFO_Command = {
|
||||
"malloc", /* name */
|
||||
"[info|dump]", /* usage */
|
||||
"[info|stats]", /* usage */
|
||||
"mem", /* topic */
|
||||
rtems_shell_main_malloc_info, /* command */
|
||||
NULL, /* alias */
|
||||
|
||||
45
cpukit/libmisc/shell/main_perioduse.c
Normal file
45
cpukit/libmisc/shell/main_perioduse.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* perioduse Command Implementation
|
||||
*
|
||||
* COPYRIGHT (c) 1989-2007.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/shell.h>
|
||||
#include "internal.h"
|
||||
|
||||
int rtems_shell_main_perioduse(int argc,char *argv[])
|
||||
{
|
||||
if ( argc >= 1 && !strcmp( argv[1], "-r" ) ) {
|
||||
printf( "Resetting Period Usage information\n" );
|
||||
rtems_rate_monotonic_reset_all_statistics();
|
||||
} else {
|
||||
rtems_rate_monotonic_report_statistics_with_plugin(
|
||||
stdout,
|
||||
(rtems_printk_plugin_t)fprintf
|
||||
);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
rtems_shell_cmd_t rtems_shell_PERIODUSE_Command = {
|
||||
"perioduse", /* name */
|
||||
"[-r] print or reset per period usage", /* usage */
|
||||
"rtems", /* topic */
|
||||
rtems_shell_main_perioduse, /* command */
|
||||
NULL, /* alias */
|
||||
NULL /* next */
|
||||
};
|
||||
@@ -51,6 +51,7 @@ extern rtems_shell_cmd_t rtems_shell_BLKSYNC_Command;
|
||||
|
||||
extern rtems_shell_cmd_t rtems_shell_CPUUSE_Command;
|
||||
extern rtems_shell_cmd_t rtems_shell_STACKUSE_Command;
|
||||
extern rtems_shell_cmd_t rtems_shell_PERIODUSE_Command;
|
||||
extern rtems_shell_cmd_t rtems_shell_MALLOC_INFO_Command;
|
||||
|
||||
extern rtems_shell_cmd_t *rtems_shell_Initial_commands[];
|
||||
@@ -275,6 +276,11 @@ extern rtems_shell_filesystems_t *rtems_shell_Mount_filesystems[];
|
||||
defined(CONFIGURE_SHELL_COMMAND_STACKUSE)
|
||||
&rtems_shell_STACKUSE_Command,
|
||||
#endif
|
||||
#if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
|
||||
!defined(CONFIGURE_SHELL_NO_COMMAND_PERIODUSE)) || \
|
||||
defined(CONFIGURE_SHELL_COMMAND_PERIODUSE)
|
||||
&rtems_shell_PERIODUSE_Command,
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Malloc family commands
|
||||
|
||||
Reference in New Issue
Block a user