Move all memory manager globals to a structure. Pass structure pointer as a handler because MM APIs
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5719 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
8a774a1712
commit
45ce321f51
@ -4281,3 +4281,7 @@
|
||||
* net/net_poll.c: Handle the missing case. Now tests for not connected
|
||||
AND not listening. I think that now covers all of the cases including
|
||||
the missing case noted above. (2013-03-07)
|
||||
* mm/: Move all memory manager globals into a structure. A reference
|
||||
to this structure is now passed internally between mm APIs. This
|
||||
change will (eventually) support multiple heaps and heap allocators.
|
||||
|
||||
|
67
TODO
67
TODO
@ -1,4 +1,4 @@
|
||||
NuttX TODO List (Last updated March 6, 2013)
|
||||
NuttX TODO List (Last updated March 8, 2013)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This file summarizes known NuttX bugs, limitations, inconsistencies with
|
||||
@ -7,8 +7,8 @@ standards, things that could be improved, and ideas for enhancements.
|
||||
nuttx/
|
||||
|
||||
(10) Task/Scheduler (sched/)
|
||||
(1) Memory Managment (mm/)
|
||||
(3) Signals (sched/, arch/)
|
||||
(2) Memory Managment (mm/)
|
||||
(4) Signals (sched/, arch/)
|
||||
(2) pthreads (sched/)
|
||||
(2) C++ Support
|
||||
(6) Binary loaders (binfmt/)
|
||||
@ -99,7 +99,7 @@ o Task/Scheduler (sched/)
|
||||
Status: Open.
|
||||
Priority: Medium Low.
|
||||
|
||||
Title: ON-DEMAND PAGE INCOMPLETE
|
||||
Title: ON-DEMAND PAGING INCOMPLETE
|
||||
Description: On-demand paging has recently been incorporated into the RTOS.
|
||||
The design of this feature is described here:
|
||||
http://www.nuttx.org/NuttXDemandPaging.html.
|
||||
@ -253,6 +253,53 @@ o Memory Managment (mm/)
|
||||
Priority: Medium/Low, a good feature to prevent memory leaks but would
|
||||
have negative impact on memory usage and code size.
|
||||
|
||||
Title: MEMORY MANAGEMENT IN THE KERNEL BUILD
|
||||
Description: If the option CONFIG_NUTTX_KERNEL is selected, then NuttX will
|
||||
built as two separate blobs: (1) a monolithic, NuttX kernel,
|
||||
and (2) a user-space application blob. Communication between
|
||||
the two is via traps in order to get from user-mode to kernel-
|
||||
mode.
|
||||
|
||||
At present, the final link of the kernel build fails because
|
||||
of undefined memory allocation logic: kmm_initialize, kmm_addregion,
|
||||
kmalloc, etc. In the flat build, these map to mm_initialize,
|
||||
mm_addregion, malloc, etc. but they are undefined in the kernel
|
||||
build.
|
||||
|
||||
It has not been fully decided how to handle kernel- and user-
|
||||
memory allocations. Here are some ideas:
|
||||
|
||||
1) Have only a single user-space heap and heap allocator that
|
||||
is shared by both kernel- and user-modes. PROs: Simpler,
|
||||
CONs: Awkward architecture and no security for kernel-mode
|
||||
allocations.
|
||||
|
||||
2) Have two separate heap partitions and two copies of the
|
||||
memory allocators. PROs: Not two difficult, CONs: Partitioning
|
||||
the heap will not make the best use of heap memory.
|
||||
|
||||
A complication is that the kernel needs to allocate both
|
||||
protected, kernel private as well as user accessible memory
|
||||
(such as for stacks). Perhaps this approach would require
|
||||
three heap partitions.
|
||||
|
||||
3) Have a classes of two allocators: (1) one that allocates large
|
||||
regions/pages of memory that can be protected or not, and
|
||||
(2) the current memory allocator extended to support sbrk().
|
||||
The would still be kernel- and user-mode instances of the
|
||||
memory allocators. Each would sbrk() as necessary to extend
|
||||
their heap; the pages allocated for the kerne-mode allocator
|
||||
would be protected but the pages allocated for the user-mode
|
||||
allocator would not. PROs: Meets all of the needs. CONs:
|
||||
would limit the size of allocations due to the physical
|
||||
pages. Complex. There would likely be some small memory
|
||||
inefficiencies due to quantization to pages. This really
|
||||
feels like overkill for this class of processor.
|
||||
|
||||
See other kernel build issues under "Build system"
|
||||
Status: Open
|
||||
Priority: Low, unless you need a working kernel build now.
|
||||
|
||||
o Signals (sched/, arch/)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@ -281,6 +328,14 @@ o Signals (sched/, arch/)
|
||||
Status: Open
|
||||
Priority: Low. Even if there are only 31 usable signals, that is still a lot.
|
||||
|
||||
Title: USER-MODE SIGNALS
|
||||
Description: In a kernel build (CONFIG_NUTTX_KERNEL). Signal handlers should
|
||||
execute in user mode. This is to prevent a security hole where
|
||||
user code can get control of the system in kernel mode if the signal
|
||||
executes in kernel mode.
|
||||
Status: Open
|
||||
Priority: Low
|
||||
|
||||
o pthreads (sched/)
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
@ -1054,6 +1109,8 @@ o Build system
|
||||
A similar issue exists in NSH that uses some internal OS
|
||||
interfaces that would not be available in a kernel build
|
||||
(such as foreach_task, foreach_mountpoint, etc.).
|
||||
|
||||
See also "Memory Management" for another kernel build issue.
|
||||
Status: Open
|
||||
Priority: Low -- the kernel build configuration is not fully fielded
|
||||
yet.
|
||||
@ -1772,7 +1829,7 @@ o z80/z8/ez80/z180 (arch/z80)
|
||||
|
||||
Title: ZDS-II COMPILER PROBLEMS
|
||||
Description: The ZDS-II compiler (version 4.10.1) fails with an internal error
|
||||
while compiler mm/mm_initialize. This has been reported as
|
||||
while compiling mm/mm_initialize.c. This has been reported as
|
||||
incident 81509.
|
||||
|
||||
I have found the following workaround that I use to build for the
|
||||
|
@ -416,8 +416,8 @@
|
||||
#define SYSCON_RCC_OSCSRC_SHIFT 4 /* Bits 5-4: Oscillator Source */
|
||||
#define SYSCON_RCC_OSCSRC_MASK (0x03 << SYSCON_RCC_OSCSRC_SHIFT)
|
||||
# define SYSCON_RCC_OSCSRC_MOSC (0 << SYSCON_RCC_OSCSRC_SHIFT) /* Main oscillator */
|
||||
# define SYSCON_RCC_OSCSRC_IOSC (1 << SYSCON_RCC_OSCSRC_SHIFT) /* Precision internal oscillator (reset) */
|
||||
# define SYSCON_RCC_OSCSRC_IOSC4 (2 << SYSCON_RCC_OSCSRC_SHIFT) /* Precision internal oscillator / 4 */
|
||||
# define SYSCON_RCC_OSCSRC_PIOSC (1 << SYSCON_RCC_OSCSRC_SHIFT) /* Precision internal oscillator (reset) */
|
||||
# define SYSCON_RCC_OSCSRC_PIOSC4 (2 << SYSCON_RCC_OSCSRC_SHIFT) /* Precision internal oscillator / 4 */
|
||||
# define SYSCON_RCC_OSCSRC_LFIOSC (3 << SYSCON_RCC_OSCSRC_SHIFT) /* Low-frequency internal oscillator */
|
||||
#define SYSCON_RCC_XTAL_SHIFT 6 /* Bits 10-6: Crystal Value */
|
||||
#define SYSCON_RCC_XTAL_MASK (31 << SYSCON_RCC_XTAL_SHIFT)
|
||||
@ -425,23 +425,23 @@
|
||||
# define SYSCON_RCC_XTAL4096KHZ (7 << SYSCON_RCC_XTAL_SHIFT) /* 4.096 MHz (NO PLL) */
|
||||
# define SYSCON_RCC_XTAL4915p2KHZ (8 << SYSCON_RCC_XTAL_SHIFT) /* 4.9152 MHz (NO PLL) */
|
||||
# define SYSCON_RCC_XTAL5000KHZ (9 << SYSCON_RCC_XTAL_SHIFT) /* 5 MHz (USB) */
|
||||
# define SYSCON_RCC_XTAL5120KHZ (10 << SYSCON_RCC_XTAL_SHIFT) /* 5.12 MHz */
|
||||
# define SYSCON_RCC_XTAL6000KHZ (11 << SYSCON_RCC_XTAL_SHIFT) /* 6 MHz (USB) */
|
||||
# define SYSCON_RCC_XTAL6144KHZ (12 << SYSCON_RCC_XTAL_SHIFT) /* 6.144 MHz */
|
||||
# define SYSCON_RCC_XTAL7372p8KHZ (13 << SYSCON_RCC_XTAL_SHIFT) /* 7.3728 MHz */
|
||||
# define SYSCON_RCC_XTAL8000KHZ (14 << SYSCON_RCC_XTAL_SHIFT) /* 8 MHz (USB) */
|
||||
# define SYSCON_RCC_XTAL8192KHZ (15 << SYSCON_RCC_XTAL_SHIFT) /* 8.192 MHz */
|
||||
# define SYSCON_RCC_XTAL10000KHZ (16 << SYSCON_RCC_XTAL_SHIFT) /* 10.0 MHz (USB) */
|
||||
# define SYSCON_RCC_XTAL12000KHZ (17 << SYSCON_RCC_XTAL_SHIFT) /* 12.0 MHz (USB) */
|
||||
# define SYSCON_RCC_XTAL12288KHZ (18 << SYSCON_RCC_XTAL_SHIFT) /* 12.288 MHz */
|
||||
# define SYSCON_RCC_XTAL13560KHZ (19 << SYSCON_RCC_XTAL_SHIFT) /* 13.56 MHz */
|
||||
# define SYSCON_RCC_XTAL14318p18KHZ (20 << SYSCON_RCC_XTAL_SHIFT) /* 14.31818 MHz */
|
||||
# define SYSCON_RCC_XTAL16000KHZ (21 << SYSCON_RCC_XTAL_SHIFT) /* 16.0 MHz (USB) */
|
||||
# define SYSCON_RCC_XTAL16384KHZ (22 << SYSCON_RCC_XTAL_SHIFT) /* 16.384 MHz */
|
||||
# define SYSCON_RCC_XTAL18000KHZ (23 << SYSCON_RCC_XTAL_SHIFT) /* 18.0 MHz (USB) */
|
||||
# define SYSCON_RCC_XTAL20000KHZ (24 << SYSCON_RCC_XTAL_SHIFT) /* 20.0 MHz (USB) */
|
||||
# define SYSCON_RCC_XTAL24000KHZ (25 << SYSCON_RCC_XTAL_SHIFT) /* 24.0 MHz (USB) */
|
||||
# define SYSCON_RCC_XTAL25000KHZ (26 << SYSCON_RCC_XTAL_SHIFT) /* 25.0 MHz (USB) */
|
||||
# define SYSCON_RCC_XTAL5120KHZ (10 << SYSCON_RCC_XTAL_SHIFT) /* 5.12 MHz */
|
||||
# define SYSCON_RCC_XTAL6000KHZ (11 << SYSCON_RCC_XTAL_SHIFT) /* 6 MHz (USB) */
|
||||
# define SYSCON_RCC_XTAL6144KHZ (12 << SYSCON_RCC_XTAL_SHIFT) /* 6.144 MHz */
|
||||
# define SYSCON_RCC_XTAL7372p8KHZ (13 << SYSCON_RCC_XTAL_SHIFT) /* 7.3728 MHz */
|
||||
# define SYSCON_RCC_XTAL8000KHZ (14 << SYSCON_RCC_XTAL_SHIFT) /* 8 MHz (USB) */
|
||||
# define SYSCON_RCC_XTAL8192KHZ (15 << SYSCON_RCC_XTAL_SHIFT) /* 8.192 MHz */
|
||||
# define SYSCON_RCC_XTAL10000KHZ (16 << SYSCON_RCC_XTAL_SHIFT) /* 10.0 MHz (USB) */
|
||||
# define SYSCON_RCC_XTAL12000KHZ (17 << SYSCON_RCC_XTAL_SHIFT) /* 12.0 MHz (USB) */
|
||||
# define SYSCON_RCC_XTAL12288KHZ (18 << SYSCON_RCC_XTAL_SHIFT) /* 12.288 MHz */
|
||||
# define SYSCON_RCC_XTAL13560KHZ (19 << SYSCON_RCC_XTAL_SHIFT) /* 13.56 MHz */
|
||||
# define SYSCON_RCC_XTAL14318p18KHZ (20 << SYSCON_RCC_XTAL_SHIFT) /* 14.31818 MHz */
|
||||
# define SYSCON_RCC_XTAL16000KHZ (21 << SYSCON_RCC_XTAL_SHIFT) /* 16.0 MHz (USB) */
|
||||
# define SYSCON_RCC_XTAL16384KHZ (22 << SYSCON_RCC_XTAL_SHIFT) /* 16.384 MHz */
|
||||
# define SYSCON_RCC_XTAL18000KHZ (23 << SYSCON_RCC_XTAL_SHIFT) /* 18.0 MHz (USB) */
|
||||
# define SYSCON_RCC_XTAL20000KHZ (24 << SYSCON_RCC_XTAL_SHIFT) /* 20.0 MHz (USB) */
|
||||
# define SYSCON_RCC_XTAL24000KHZ (25 << SYSCON_RCC_XTAL_SHIFT) /* 24.0 MHz (USB) */
|
||||
# define SYSCON_RCC_XTAL25000KHZ (26 << SYSCON_RCC_XTAL_SHIFT) /* 25.0 MHz (USB) */
|
||||
#define SYSCON_RCC_BYPASS (1 << 11) /* Bit 11: PLL Bypass */
|
||||
#define SYSCON_RCC_PWRDN (1 << 13) /* Bit 13: PLL Power Down */
|
||||
#define SYSCON_RCC_USESYSDIV (1 << 22) /* Bit 22: Enable System Clock Divider */
|
||||
|
@ -60,7 +60,8 @@
|
||||
#undef KMALLOC_EXTERN
|
||||
#if defined(__cplusplus)
|
||||
# define KMALLOC_EXTERN extern "C"
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
# define KMALLOC_EXTERN extern
|
||||
#endif
|
||||
@ -76,10 +77,13 @@ extern "C" {
|
||||
|
||||
#ifndef CONFIG_NUTTX_KERNEL
|
||||
|
||||
struct mm_heap_s;
|
||||
extern struct mm_heap_s g_mmheap;
|
||||
|
||||
# define kmm_initialize(h,s) mm_initialize(h,s)
|
||||
# define kmm_addregion(h,s) mm_addregion(h,s)
|
||||
# define kmm_trysemaphore() mm_trysemaphore()
|
||||
# define kmm_givesemaphore() mm_givesemaphore()
|
||||
# define kmm_trysemaphore() mm_trysemaphore(&g_mmheap)
|
||||
# define kmm_givesemaphore() mm_givesemaphore(&g_mmheap)
|
||||
|
||||
# define kmalloc(s) malloc(s)
|
||||
# define kzalloc(s) zalloc(s)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* include/nuttx/mm.h
|
||||
*
|
||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -61,20 +61,22 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/* Functions contained in mm_initialize.c ***********************************/
|
||||
|
||||
EXTERN void mm_initialize(FAR void *heap_start, size_t heap_size);
|
||||
EXTERN void mm_addregion(FAR void *heapstart, size_t heapsize);
|
||||
void mm_initialize(FAR void *heap_start, size_t heap_size);
|
||||
void mm_addregion(FAR void *heapstart, size_t heapsize);
|
||||
|
||||
/* Functions contained in mm_sem.c ******************************************/
|
||||
|
||||
EXTERN int mm_trysemaphore(void);
|
||||
EXTERN void mm_givesemaphore(void);
|
||||
struct mm_heap_s;
|
||||
int mm_trysemaphore(FAR struct mm_heap_s *heap);
|
||||
void mm_givesemaphore(FAR struct mm_heap_s *heap);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
|
@ -35,34 +35,33 @@
|
||||
|
||||
-include $(TOPDIR)/Make.defs
|
||||
|
||||
SRCS = mm_test.c mm_initialize.c mm_sem.c mm_addfreechunk.c mm_size2ndx.c mm_shrinkchunk.c \
|
||||
mm_malloc.c mm_zalloc.c mm_calloc.c mm_realloc.c \
|
||||
mm_memalign.c mm_free.c mm_mallinfo.c
|
||||
OBJS = $(SRCS:.c=.o1)
|
||||
SRCS = mm_test.c mm_initialize.c mm_sem.c mm_addfreechunk.c mm_size2ndx.c
|
||||
SRCS += mm_shrinkchunk.c mm_malloc.c mm_zalloc.c mm_calloc.c mm_realloc.c
|
||||
SRCS += mm_memalign.c mm_free.c mm_mallinfo.c
|
||||
OBJS = $(SRCS:.c=.o1)
|
||||
|
||||
LIBS = -lpthread -lc
|
||||
LIBS = -lpthread -lc
|
||||
|
||||
CC = gcc
|
||||
LD = gcc
|
||||
CC = gcc
|
||||
LD = gcc
|
||||
|
||||
DEFINES = -DMM_TEST=1
|
||||
WARNIGNS = -Wall -Wstrict-prototypes -Wshadow
|
||||
CFLAGS = -g $(DEFINES)
|
||||
LDFLAGS =
|
||||
DEFINES = -DMM_TEST=1
|
||||
WARNIGNS = -Wall -Wstrict-prototypes -Wshadow
|
||||
CFLAGS = -g $(DEFINES)
|
||||
LDFLAGS =
|
||||
|
||||
BIN = ..$(DELIM)mm_test
|
||||
BIN = mm_test
|
||||
|
||||
all: $(BIN)
|
||||
all: $(BIN)
|
||||
|
||||
$(OBJS): %.o1: %.c
|
||||
@echo "Compiling $<"
|
||||
$(Q) $(CC) -c $(CFLAGS) $< -o $@
|
||||
@$(CC) -c $(CFLAGS) $< -o $@
|
||||
|
||||
$(BIN): $(OBJS)
|
||||
$(BIN): $(OBJS)
|
||||
@echo "Linking {$(OBJS)} to produce $@"
|
||||
$(Q) $(LD) $(LDFLAGS) $(OBJS) $(LIBS) -o $@
|
||||
@$(LD) $(LDFLAGS) $(OBJS) $(LIBS) -o $@
|
||||
|
||||
clean:
|
||||
$(call DELFILE, $(BIN))
|
||||
$(call DELFILE, *.o1)
|
||||
$(call CLEAN)
|
||||
rm -f $(BIN)
|
||||
rm -f *.o1
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* mm/mm_addfreechunk.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -61,7 +61,7 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mm_addfreechunk(FAR struct mm_freenode_s *node)
|
||||
void mm_addfreechunk(FAR struct mm_heap_s *heap, FAR struct mm_freenode_s *node)
|
||||
{
|
||||
FAR struct mm_freenode_s *next;
|
||||
FAR struct mm_freenode_s *prev;
|
||||
@ -72,7 +72,7 @@ void mm_addfreechunk(FAR struct mm_freenode_s *node)
|
||||
|
||||
/* Now put the new node int the next */
|
||||
|
||||
for (prev = &g_nodelist[ndx], next = g_nodelist[ndx].flink;
|
||||
for (prev = &heap->mm_nodelist[ndx], next = heap->mm_nodelist[ndx].flink;
|
||||
next && next->size && next->size < node->size;
|
||||
prev = next, next = next->flink);
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
/* The platform configuratioin file will not be included when the memory
|
||||
/* The platform configuration file will not be included when the memory
|
||||
* manager is built for the host-based test harness.
|
||||
*/
|
||||
|
||||
@ -50,13 +50,17 @@
|
||||
# include <sys/types.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <debug.h>
|
||||
# include <semaphore.h>
|
||||
# include <errno.h>
|
||||
# include <assert.h>
|
||||
# include <nuttx/mm.h>
|
||||
# include <debug.h>
|
||||
#else
|
||||
# include <sys/types.h>
|
||||
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
# include <semaphore.h>
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
@ -79,7 +83,7 @@
|
||||
# define CONFIG_CAN_PASS_STRUCTS 1 /* Normally in config.h */
|
||||
# undef CONFIG_SMALL_MEMORY /* Normally in config.h */
|
||||
|
||||
extern void mm_addregion(FAR void *heapstart, size_t heapsize);
|
||||
void mm_addregion(FAR void *heapstart, size_t heapsize);
|
||||
|
||||
/* Use the real system errno */
|
||||
|
||||
@ -103,6 +107,10 @@ extern void mm_addregion(FAR void *heapstart, size_t heapsize);
|
||||
# undef DEBUGASSERT
|
||||
# define DEBUGASSERT(e) assert(e)
|
||||
|
||||
/* Misc. NuttX-isms */
|
||||
|
||||
#define OK 0
|
||||
|
||||
/* Debug macros are always on */
|
||||
|
||||
# define CONFIG_DEBUG 1
|
||||
|
38
mm/mm_free.c
38
mm/mm_free.c
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* mm/mm_free.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -51,19 +51,15 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: free
|
||||
* Name: _mm_free
|
||||
*
|
||||
* Description:
|
||||
* Returns a chunk of memory into the list of free nodes, merging with
|
||||
* Returns a chunk of memory to the list of free nodes, merging with
|
||||
* adjacent free chunks if possible.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void free(FAR void *mem)
|
||||
static inline void _mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
|
||||
{
|
||||
FAR struct mm_freenode_s *node;
|
||||
FAR struct mm_freenode_s *prev;
|
||||
@ -82,7 +78,7 @@ void free(FAR void *mem)
|
||||
* nodelist.
|
||||
*/
|
||||
|
||||
mm_takesemaphore();
|
||||
mm_takesemaphore(heap);
|
||||
|
||||
/* Map the memory chunk into a free node */
|
||||
|
||||
@ -148,6 +144,26 @@ void free(FAR void *mem)
|
||||
|
||||
/* Add the merged node to the nodelist */
|
||||
|
||||
mm_addfreechunk(node);
|
||||
mm_givesemaphore();
|
||||
mm_addfreechunk(heap, node);
|
||||
mm_givesemaphore(heap);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: free
|
||||
*
|
||||
* Description:
|
||||
* Returns a chunk of memory to the list of free nodes, merging with
|
||||
* adjacent free chunks if possible.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_NUTTX_KERNEL) || !defined(__KERNEL__)
|
||||
void free(FAR void *mem)
|
||||
{
|
||||
_mm_free(&g_mmheap, mem);
|
||||
}
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* mm/mm_initialize.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 2011, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -48,98 +48,25 @@
|
||||
* Public Variables
|
||||
****************************************************************************/
|
||||
|
||||
/* This is the size of the heap provided to mm */
|
||||
#if !defined(CONFIG_NUTTX_KERNEL) || !defined(__KERNEL__)
|
||||
/* This is the user heap */
|
||||
|
||||
size_t g_heapsize;
|
||||
struct mm_heap_s g_mmheap;
|
||||
|
||||
/* This is the first and last nodes of the heap */
|
||||
|
||||
FAR struct mm_allocnode_s *g_heapstart[CONFIG_MM_REGIONS];
|
||||
FAR struct mm_allocnode_s *g_heapend[CONFIG_MM_REGIONS];
|
||||
|
||||
#if CONFIG_MM_REGIONS > 1
|
||||
int g_nregions;
|
||||
#endif
|
||||
|
||||
/* All free nodes are maintained in a doubly linked list. This array
|
||||
* provides some hooks into the list at various points to speed searches for
|
||||
* free nodes.
|
||||
*/
|
||||
|
||||
FAR struct mm_freenode_s g_nodelist[MM_NNODES];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mm_initialize
|
||||
* Name: _mm_addregion
|
||||
*
|
||||
* Description:
|
||||
* This is an internal OS function called only at power-up boot time.
|
||||
*
|
||||
* Parameters:
|
||||
* heapstart - Start of the initial heap region
|
||||
* heapsize - Size of the initial heap region
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mm_initialize(FAR void *heapstart, size_t heapsize)
|
||||
{
|
||||
int i;
|
||||
|
||||
mlldbg("Heap: start=%p size=%u\n", heapstart, heapsize);
|
||||
|
||||
/* The following two lines have cause problems for some older ZiLog
|
||||
* compilers in the past (but not the more recent). Life is easier if we
|
||||
* just the suppress them altogther for those tools.
|
||||
*/
|
||||
|
||||
#ifndef __ZILOG__
|
||||
CHECK_ALLOCNODE_SIZE;
|
||||
CHECK_FREENODE_SIZE;
|
||||
#endif
|
||||
|
||||
/* Set up global variables */
|
||||
|
||||
g_heapsize = 0;
|
||||
|
||||
#if CONFIG_MM_REGIONS > 1
|
||||
g_nregions = 0;
|
||||
#endif
|
||||
|
||||
/* Initialize the node array */
|
||||
|
||||
memset(g_nodelist, 0, sizeof(struct mm_freenode_s) * MM_NNODES);
|
||||
for (i = 1; i < MM_NNODES; i++)
|
||||
{
|
||||
g_nodelist[i-1].flink = &g_nodelist[i];
|
||||
g_nodelist[i].blink = &g_nodelist[i-1];
|
||||
}
|
||||
|
||||
/* Initialize the malloc semaphore to one (to support one-at-
|
||||
* a-time access to private data sets).
|
||||
*/
|
||||
|
||||
mm_seminitialize();
|
||||
|
||||
/* Add the initial region of memory to the heap */
|
||||
|
||||
mm_addregion(heapstart, heapsize);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mm_addregion
|
||||
*
|
||||
* Description:
|
||||
* This function gives a region of contiguous memory to the memory manager
|
||||
* This function adds a region of contiguous memory to the selected heap.
|
||||
*
|
||||
* Parameters:
|
||||
* heap - The selected heap
|
||||
* heapstart - Start of the heap region
|
||||
* heapsize - Size of the heap region
|
||||
*
|
||||
@ -150,13 +77,14 @@ void mm_initialize(FAR void *heapstart, size_t heapsize)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mm_addregion(FAR void *heapstart, size_t heapsize)
|
||||
static inline void _mm_addregion(FAR struct mm_heap_s *heap,
|
||||
FAR void *heapstart, size_t heapsize)
|
||||
{
|
||||
FAR struct mm_freenode_s *node;
|
||||
uintptr_t heapbase;
|
||||
uintptr_t heapend;
|
||||
#if CONFIG_MM_REGIONS > 1
|
||||
int IDX = g_nregions;
|
||||
int IDX = heap->mm_nregions;
|
||||
#else
|
||||
# define IDX 0
|
||||
#endif
|
||||
@ -182,7 +110,7 @@ void mm_addregion(FAR void *heapstart, size_t heapsize)
|
||||
|
||||
/* Add the size of this region to the total size of the heap */
|
||||
|
||||
g_heapsize += heapsize;
|
||||
heap->mm_heapsize += heapsize;
|
||||
|
||||
/* Create two "allocated" guard nodes at the beginning and end of
|
||||
* the heap. These only serve to keep us from allocating outside
|
||||
@ -192,25 +120,146 @@ void mm_addregion(FAR void *heapstart, size_t heapsize)
|
||||
* all available memory.
|
||||
*/
|
||||
|
||||
g_heapstart[IDX] = (FAR struct mm_allocnode_s *)heapbase;
|
||||
g_heapstart[IDX]->size = SIZEOF_MM_ALLOCNODE;
|
||||
g_heapstart[IDX]->preceding = MM_ALLOC_BIT;
|
||||
heap->mm_heapstart[IDX] = (FAR struct mm_allocnode_s *)heapbase;
|
||||
heap->mm_heapstart[IDX]->size = SIZEOF_MM_ALLOCNODE;
|
||||
heap->mm_heapstart[IDX]->preceding = MM_ALLOC_BIT;
|
||||
|
||||
node = (FAR struct mm_freenode_s *)(heapbase + SIZEOF_MM_ALLOCNODE);
|
||||
node->size = heapsize - 2*SIZEOF_MM_ALLOCNODE;
|
||||
node->preceding = SIZEOF_MM_ALLOCNODE;
|
||||
|
||||
g_heapend[IDX] = (FAR struct mm_allocnode_s *)(heapend - SIZEOF_MM_ALLOCNODE);
|
||||
g_heapend[IDX]->size = SIZEOF_MM_ALLOCNODE;
|
||||
g_heapend[IDX]->preceding = node->size | MM_ALLOC_BIT;
|
||||
heap->mm_heapend[IDX] = (FAR struct mm_allocnode_s *)(heapend - SIZEOF_MM_ALLOCNODE);
|
||||
heap->mm_heapend[IDX]->size = SIZEOF_MM_ALLOCNODE;
|
||||
heap->mm_heapend[IDX]->preceding = node->size | MM_ALLOC_BIT;
|
||||
|
||||
#undef IDX
|
||||
|
||||
#if CONFIG_MM_REGIONS > 1
|
||||
g_nregions++;
|
||||
heap->mm_nregions++;
|
||||
#endif
|
||||
|
||||
/* Add the single, large free node to the nodelist */
|
||||
|
||||
mm_addfreechunk(node);
|
||||
mm_addfreechunk(heap, node);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: _mm_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the selected heap data structures, providing the initial
|
||||
* heap region.
|
||||
*
|
||||
* Parameters:
|
||||
* heap - The selected heap
|
||||
* heapstart - Start of the initial heap region
|
||||
* heapsize - Size of the initial heap region
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void _mm_initialize(FAR struct mm_heap_s *heap,
|
||||
FAR void *heapstart, size_t heapsize)
|
||||
{
|
||||
int i;
|
||||
|
||||
mlldbg("Heap: start=%p size=%u\n", heapstart, heapsize);
|
||||
|
||||
/* The following two lines have cause problems for some older ZiLog
|
||||
* compilers in the past (but not the more recent). Life is easier if we
|
||||
* just the suppress them altogther for those tools.
|
||||
*/
|
||||
|
||||
#ifndef __ZILOG__
|
||||
CHECK_ALLOCNODE_SIZE;
|
||||
CHECK_FREENODE_SIZE;
|
||||
#endif
|
||||
|
||||
/* Set up global variables */
|
||||
|
||||
heap->mm_heapsize = 0;
|
||||
|
||||
#if CONFIG_MM_REGIONS > 1
|
||||
heap->mm_nregions = 0;
|
||||
#endif
|
||||
|
||||
/* Initialize the node array */
|
||||
|
||||
memset(heap->mm_nodelist, 0, sizeof(struct mm_freenode_s) * MM_NNODES);
|
||||
for (i = 1; i < MM_NNODES; i++)
|
||||
{
|
||||
heap->mm_nodelist[i-1].flink = &heap->mm_nodelist[i];
|
||||
heap->mm_nodelist[i].blink = &heap->mm_nodelist[i-1];
|
||||
}
|
||||
|
||||
/* Initialize the malloc semaphore to one (to support one-at-
|
||||
* a-time access to private data sets).
|
||||
*/
|
||||
|
||||
mm_seminitialize(heap);
|
||||
|
||||
/* Add the initial region of memory to the heap */
|
||||
|
||||
_mm_addregion(heap, heapstart, heapsize);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mm_initialize
|
||||
*
|
||||
* Description:
|
||||
* This this function is called during initialization to initialize the
|
||||
* user heap.
|
||||
*
|
||||
* Parameters:
|
||||
* heapstart - Start of the initial heap region
|
||||
* heapsize - Size of the initial heap region
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_NUTTX_KERNEL) || !defined(__KERNEL__)
|
||||
|
||||
void mm_initialize(FAR void *heapstart, size_t heapsize)
|
||||
{
|
||||
_mm_initialize(&g_mmheap, heapstart, heapsize);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mm_addregion
|
||||
*
|
||||
* Description:
|
||||
* This function adds a region of contiguous memory to the user heap.
|
||||
*
|
||||
* Parameters:
|
||||
* heapstart - Start of the heap region
|
||||
* heapsize - Size of the heap region
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_NUTTX_KERNEL) || !defined(__KERNEL__)
|
||||
|
||||
void mm_addregion(FAR void *heapstart, size_t heapsize)
|
||||
{
|
||||
_mm_addregion(&g_mmheap, heapstart, heapsize);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
102
mm/mm_internal.h
102
mm/mm_internal.h
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* mm/mm_internal.h
|
||||
*
|
||||
* Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 2011, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -113,7 +113,7 @@
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Determine the size of the chunk size/offset type */
|
||||
/* Determines the size of the chunk size/offset type */
|
||||
|
||||
#ifdef CONFIG_MM_SMALL
|
||||
typedef uint16_t mmsize_t;
|
||||
@ -170,6 +170,39 @@ struct mm_freenode_s
|
||||
#define CHECK_FREENODE_SIZE \
|
||||
DEBUGASSERT(sizeof(struct mm_freenode_s) == SIZEOF_MM_FREENODE)
|
||||
|
||||
/* This describes one heap (possibly with multiple regions) */
|
||||
|
||||
struct mm_heap_s
|
||||
{
|
||||
/* Mutually exclusive access to this data set is enforced with
|
||||
* the following un-named semaphore.
|
||||
*/
|
||||
|
||||
sem_t mm_semaphore;
|
||||
pid_t mm_holder;
|
||||
int mm_counts_held;
|
||||
|
||||
/* This is the size of the heap provided to mm */
|
||||
|
||||
size_t mm_heapsize;
|
||||
|
||||
/* This is the first and last nodes of the heap */
|
||||
|
||||
FAR struct mm_allocnode_s *mm_heapstart[CONFIG_MM_REGIONS];
|
||||
FAR struct mm_allocnode_s *mm_heapend[CONFIG_MM_REGIONS];
|
||||
|
||||
#if CONFIG_MM_REGIONS > 1
|
||||
int mm_nregions;
|
||||
#endif
|
||||
|
||||
/* All free nodes are maintained in a doubly linked list. This
|
||||
* array provides some hooks into the list at various points to
|
||||
* speed searches for free nodes.
|
||||
*/
|
||||
|
||||
struct mm_freenode_s mm_nodelist[MM_NNODES];
|
||||
};
|
||||
|
||||
/* Normally defined in stdlib.h */
|
||||
|
||||
#ifdef MM_TEST
|
||||
@ -187,57 +220,58 @@ struct mallinfo
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Global Variables
|
||||
* Public Variables
|
||||
****************************************************************************/
|
||||
|
||||
/* This is the size of the heap provided to mm */
|
||||
|
||||
extern size_t g_heapsize;
|
||||
|
||||
/* This is the first and last nodes of the heap */
|
||||
|
||||
extern FAR struct mm_allocnode_s *g_heapstart[CONFIG_MM_REGIONS];
|
||||
extern FAR struct mm_allocnode_s *g_heapend[CONFIG_MM_REGIONS];
|
||||
|
||||
#if CONFIG_MM_REGIONS > 1
|
||||
extern int g_nregions;
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
# define g_nregions 1
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/* All free nodes are maintained in a doubly linked list. This
|
||||
* array provides some hooks into the list at various points to
|
||||
* speed searches for free nodes.
|
||||
*/
|
||||
#if !defined(CONFIG_NUTTX_KERNEL) || !defined(__KERNEL__)
|
||||
/* This is the user heap */
|
||||
|
||||
extern FAR struct mm_freenode_s g_nodelist[MM_NNODES];
|
||||
EXTERN struct mm_heap_s g_mmheap;
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef MM_TEST
|
||||
FAR void *mm_malloc(size_t);
|
||||
void mm_free(void*);
|
||||
FAR void *mm_realloc(void*, size_t);
|
||||
FAR void *mm_memalign(size_t, size_t);
|
||||
FAR void *mm_zalloc(size_t);
|
||||
FAR void *mm_calloc(size_t, size_t);
|
||||
FAR void *mm_malloc(size_t);
|
||||
void mm_free(void*);
|
||||
FAR void *mm_realloc(void*, size_t);
|
||||
FAR void *mm_memalign(size_t, size_t);
|
||||
FAR void *mm_zalloc(size_t);
|
||||
FAR void *mm_calloc(size_t, size_t);
|
||||
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
struct mallinfo mallinfo(void);
|
||||
#else
|
||||
int mallinfo(struct mallinfo *info);
|
||||
int mallinfo(struct mallinfo *info);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void mm_shrinkchunk(FAR struct mm_allocnode_s *node, size_t size);
|
||||
void mm_addfreechunk(FAR struct mm_freenode_s *node);
|
||||
int mm_size2ndx(size_t size);
|
||||
void mm_seminitialize(void);
|
||||
void mm_takesemaphore(void);
|
||||
void mm_givesemaphore(void);
|
||||
void mm_shrinkchunk(FAR struct mm_heap_s *heap,
|
||||
FAR struct mm_allocnode_s *node, size_t size);
|
||||
void mm_addfreechunk(FAR struct mm_heap_s *heap,
|
||||
FAR struct mm_freenode_s *node);
|
||||
int mm_size2ndx(size_t size);
|
||||
void mm_seminitialize(FAR struct mm_heap_s *heap);
|
||||
void mm_takesemaphore(FAR struct mm_heap_s *heap);
|
||||
void mm_givesemaphore(FAR struct mm_heap_s *heap);
|
||||
#ifdef MM_TEST
|
||||
int mm_getsemaphore(void);
|
||||
int mm_getsemaphore(FAR struct mm_heap_s *heap);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MM_MM_INTERNAL_H */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* mm/mm_mallinfo.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -55,22 +55,15 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mallinfo
|
||||
* Name: _mm_mallinfo
|
||||
*
|
||||
* Description:
|
||||
* mallinfo returns a copy of updated current mallinfo.
|
||||
* mallinfo returns a copy of updated current heap information.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
struct mallinfo mallinfo(void)
|
||||
#else
|
||||
int mallinfo(struct mallinfo *info)
|
||||
#endif
|
||||
static inline int _mm_mallinfo(FAR struct mm_heap_s *heap,
|
||||
FAR struct mallinfo *info)
|
||||
{
|
||||
struct mm_allocnode_s *node;
|
||||
size_t mxordblk = 0;
|
||||
@ -83,29 +76,22 @@ int mallinfo(struct mallinfo *info)
|
||||
# define region 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
static struct mallinfo info;
|
||||
#else
|
||||
if (!info)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
#endif
|
||||
DEBUGASSERT(info);
|
||||
|
||||
/* Visit each region */
|
||||
|
||||
#if CONFIG_MM_REGIONS > 1
|
||||
for (region = 0; region < g_nregions; region++)
|
||||
for (region = 0; region < heap->mm_nregions; region++)
|
||||
#endif
|
||||
{
|
||||
/* Visit each node in the region
|
||||
* Retake the semaphore for each region to reduce latencies
|
||||
*/
|
||||
|
||||
mm_takesemaphore();
|
||||
mm_takesemaphore(heap);
|
||||
|
||||
for (node = g_heapstart[region];
|
||||
node < g_heapend[region];
|
||||
for (node = heap->mm_heapstart[region];
|
||||
node < heap->mm_heapend[region];
|
||||
node = (struct mm_allocnode_s *)((char*)node + node->size))
|
||||
{
|
||||
mvdbg("region=%d node=%p size=%p preceding=%p\n", region, node, node->size, node->preceding);
|
||||
@ -124,29 +110,54 @@ int mallinfo(struct mallinfo *info)
|
||||
}
|
||||
}
|
||||
|
||||
mm_givesemaphore();
|
||||
mm_givesemaphore(heap);
|
||||
|
||||
mvdbg("region=%d node=%p g_heapend=%p\n", region, node, g_heapend[region]);
|
||||
DEBUGASSERT(node == g_heapend[region]);
|
||||
mvdbg("region=%d node=%p heapend=%p\n", region, node, heap->mm_heapend[region]);
|
||||
DEBUGASSERT(node == heap->mm_heapend[region]);
|
||||
uordblks += SIZEOF_MM_ALLOCNODE; /* account for the tail node */
|
||||
}
|
||||
#undef region
|
||||
|
||||
DEBUGASSERT(uordblks + fordblks == g_heapsize);
|
||||
DEBUGASSERT(uordblks + fordblks == heap->mm_heapsize);
|
||||
|
||||
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
info.arena = g_heapsize;
|
||||
info.ordblks = ordblks;
|
||||
info.mxordblk = mxordblk;
|
||||
info.uordblks = uordblks;
|
||||
info.fordblks = fordblks;
|
||||
return info;
|
||||
#else
|
||||
info->arena = g_heapsize;
|
||||
info->arena = heap->mm_heapsize;
|
||||
info->ordblks = ordblks;
|
||||
info->mxordblk = mxordblk;
|
||||
info->uordblks = uordblks;
|
||||
info->fordblks = fordblks;
|
||||
return OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: kmallinfo and mallinfo
|
||||
*
|
||||
* Description:
|
||||
* mallinfo returns a copy of updated current heap information for either
|
||||
* the user heap (mallinfo) or the kernel heap (kmallinfo).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_NUTTX_KERNEL) || !defined(__KERNEL__)
|
||||
# ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
|
||||
struct mallinfo mallinfo(void)
|
||||
{
|
||||
struct mallinfo info;
|
||||
|
||||
_mm_mallinfo(&g_mmheap, &info);
|
||||
return info;
|
||||
}
|
||||
|
||||
# else
|
||||
|
||||
int mallinfo(struct mallinfo *info)
|
||||
{
|
||||
return _mm_mallinfo(&g_mmheap, info);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* !CONFIG_NUTTX_KERNEL || !__KERNEL__ */
|
||||
|
@ -71,11 +71,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: malloc
|
||||
* Name: _mm_malloc
|
||||
*
|
||||
* Description:
|
||||
* Find the smallest chunk that satisfies the request. Take the memory from
|
||||
@ -85,7 +81,7 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR void *malloc(size_t size)
|
||||
static inline FAR void *_mm_malloc(FAR struct mm_heap_s *heap, size_t size)
|
||||
{
|
||||
FAR struct mm_freenode_s *node;
|
||||
void *ret = NULL;
|
||||
@ -106,7 +102,7 @@ FAR void *malloc(size_t size)
|
||||
|
||||
/* We need to hold the MM semaphore while we muck with the nodelist. */
|
||||
|
||||
mm_takesemaphore();
|
||||
mm_takesemaphore(heap);
|
||||
|
||||
/* Get the location in the node list to start the search. Special case
|
||||
* really big allocations
|
||||
@ -125,10 +121,10 @@ FAR void *malloc(size_t size)
|
||||
|
||||
/* Search for a large enough chunk in the list of nodes. This list is
|
||||
* ordered by size, but will have occasional zero sized nodes as we visit
|
||||
* other g_nodelist[] entries.
|
||||
* other mm_nodelist[] entries.
|
||||
*/
|
||||
|
||||
for (node = g_nodelist[ndx].flink;
|
||||
for (node = heap->mm_nodelist[ndx].flink;
|
||||
node && node->size < size;
|
||||
node = node->flink);
|
||||
|
||||
@ -186,7 +182,7 @@ FAR void *malloc(size_t size)
|
||||
|
||||
/* Add the remainder back into the nodelist */
|
||||
|
||||
mm_addfreechunk(remainder);
|
||||
mm_addfreechunk(heap, remainder);
|
||||
}
|
||||
|
||||
/* Handle the case of an exact size match */
|
||||
@ -195,7 +191,7 @@ FAR void *malloc(size_t size)
|
||||
ret = (void*)((char*)node + SIZEOF_MM_ALLOCNODE);
|
||||
}
|
||||
|
||||
mm_givesemaphore();
|
||||
mm_givesemaphore(heap);
|
||||
|
||||
/* If CONFIG_DEBUG_MM is defined, then output the result of the allocation
|
||||
* to the SYSLOG.
|
||||
@ -214,3 +210,26 @@ FAR void *malloc(size_t size)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: malloc
|
||||
*
|
||||
* Description:
|
||||
* Find the smallest chunk that satisfies the request. Take the memory from
|
||||
* that chunk, save the remaining, smaller chunk (if any).
|
||||
*
|
||||
* 8-byte alignment of the allocated data is assured.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_NUTTX_KERNEL) || !defined(__KERNEL__)
|
||||
FAR void *malloc(size_t size)
|
||||
{
|
||||
return _mm_malloc(&g_mmheap, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* mm/mm_memalign.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 2011, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -47,11 +47,11 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Global Functions
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: memalign
|
||||
* Name: _mm_memalign
|
||||
*
|
||||
* Description:
|
||||
* memalign requests more than enough space from malloc, finds a region
|
||||
@ -63,7 +63,8 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR void *memalign(size_t alignment, size_t size)
|
||||
static inline FAR void *_mm_memalign(FAR struct mm_heap_s *heap,
|
||||
size_t alignment, size_t size)
|
||||
{
|
||||
FAR struct mm_allocnode_s *node;
|
||||
size_t rawchunk;
|
||||
@ -107,7 +108,7 @@ FAR void *memalign(size_t alignment, size_t size)
|
||||
* nodelist.
|
||||
*/
|
||||
|
||||
mm_takesemaphore();
|
||||
mm_takesemaphore(heap);
|
||||
|
||||
/* Get the node associated with the allocation and the next node after
|
||||
* the allocation.
|
||||
@ -182,7 +183,7 @@ FAR void *memalign(size_t alignment, size_t size)
|
||||
|
||||
/* Add the original, newly freed node to the free nodelist */
|
||||
|
||||
mm_addfreechunk((FAR struct mm_freenode_s *)node);
|
||||
mm_addfreechunk(heap, (FAR struct mm_freenode_s *)node);
|
||||
|
||||
/* Replace the original node with the newlay realloaced,
|
||||
* aligned node
|
||||
@ -200,9 +201,35 @@ FAR void *memalign(size_t alignment, size_t size)
|
||||
* malloc-compatible sizes that we have.
|
||||
*/
|
||||
|
||||
mm_shrinkchunk(node, size + SIZEOF_MM_ALLOCNODE);
|
||||
mm_shrinkchunk(heap, node, size + SIZEOF_MM_ALLOCNODE);
|
||||
}
|
||||
|
||||
mm_givesemaphore();
|
||||
mm_givesemaphore(heap);
|
||||
return (FAR void*)alignedchunk;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: _mm_memalign
|
||||
*
|
||||
* Description:
|
||||
* memalign requests more than enough space from malloc, finds a region
|
||||
* within that chunk that meets the alignment request and then frees any
|
||||
* leading or trailing space.
|
||||
*
|
||||
* The alignment argument must be a power of two (not checked). 8-byte
|
||||
* alignment is guaranteed by normal malloc calls.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_NUTTX_KERNEL) || !defined(__KERNEL__)
|
||||
|
||||
FAR void *memalign(size_t alignment, size_t size)
|
||||
{
|
||||
return _mm_memalign(&g_mmheap, alignment, size);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* mm/mm_realloc.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -47,11 +47,11 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Global Functions
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: realloc
|
||||
* Name: _mm_realloc
|
||||
*
|
||||
* Description:
|
||||
* If the reallocation is for less space, then:
|
||||
@ -73,7 +73,8 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR void *realloc(FAR void *oldmem, size_t size)
|
||||
static inline FAR void *_mm_realloc(FAR struct mm_heap_s *heap,
|
||||
FAR void *oldmem, size_t size)
|
||||
{
|
||||
FAR struct mm_allocnode_s *oldnode;
|
||||
FAR struct mm_freenode_s *prev;
|
||||
@ -110,7 +111,7 @@ FAR void *realloc(FAR void *oldmem, size_t size)
|
||||
|
||||
/* We need to hold the MM semaphore while we muck with the nodelist. */
|
||||
|
||||
mm_takesemaphore();
|
||||
mm_takesemaphore(heap);
|
||||
|
||||
/* Check if this is a request to reduce the size of the allocation. */
|
||||
|
||||
@ -123,12 +124,12 @@ FAR void *realloc(FAR void *oldmem, size_t size)
|
||||
|
||||
if (size < oldsize)
|
||||
{
|
||||
mm_shrinkchunk(oldnode, size);
|
||||
mm_shrinkchunk(heap, oldnode, size);
|
||||
}
|
||||
|
||||
/* Then return the original address */
|
||||
|
||||
mm_givesemaphore();
|
||||
mm_givesemaphore(heap);
|
||||
return oldmem;
|
||||
}
|
||||
|
||||
@ -248,7 +249,7 @@ FAR void *realloc(FAR void *oldmem, size_t size)
|
||||
|
||||
/* Return the previous free node to the nodelist (with the new size) */
|
||||
|
||||
mm_addfreechunk(prev);
|
||||
mm_addfreechunk(heap, prev);
|
||||
|
||||
/* Now we want to return newnode */
|
||||
|
||||
@ -317,7 +318,7 @@ FAR void *realloc(FAR void *oldmem, size_t size)
|
||||
|
||||
/* Add the new free node to the nodelist (with the new size) */
|
||||
|
||||
mm_addfreechunk(newnode);
|
||||
mm_addfreechunk(heap, newnode);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -327,7 +328,7 @@ FAR void *realloc(FAR void *oldmem, size_t size)
|
||||
}
|
||||
}
|
||||
|
||||
mm_givesemaphore();
|
||||
mm_givesemaphore(heap);
|
||||
return newmem;
|
||||
}
|
||||
|
||||
@ -339,7 +340,7 @@ FAR void *realloc(FAR void *oldmem, size_t size)
|
||||
* leave the original memory in place.
|
||||
*/
|
||||
|
||||
mm_givesemaphore();
|
||||
mm_givesemaphore(heap);
|
||||
newmem = (FAR void*)malloc(size);
|
||||
if (newmem)
|
||||
{
|
||||
@ -350,3 +351,40 @@ FAR void *realloc(FAR void *oldmem, size_t size)
|
||||
return newmem;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: realloc
|
||||
*
|
||||
* Description:
|
||||
* If the reallocation is for less space, then:
|
||||
*
|
||||
* (1) the current allocation is reduced in size
|
||||
* (2) the remainder at the end of the allocation is returned to the
|
||||
* free list.
|
||||
*
|
||||
* If the request is for more space and the current allocation can be
|
||||
* extended, it will be extended by:
|
||||
*
|
||||
* (1) Taking the additional space from the following free chunk, or
|
||||
* (2) Taking the additional space from the preceding free chunk.
|
||||
* (3) Or both
|
||||
*
|
||||
* If the request is for more space but the current chunk cannot be
|
||||
* extended, then malloc a new buffer, copy the data into the new buffer,
|
||||
* and free the old buffer.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_NUTTX_KERNEL) || !defined(__KERNEL__)
|
||||
|
||||
FAR void *realloc(FAR void *oldmem, size_t size)
|
||||
{
|
||||
return _mm_realloc(&g_mmheap, oldmem, size);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
64
mm/mm_sem.c
64
mm/mm_sem.c
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* mm/mm_sem.c
|
||||
*
|
||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -40,7 +40,6 @@
|
||||
#include "mm_environment.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
@ -72,13 +71,6 @@
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Mutually exclusive access to this data set is enforced with
|
||||
* the following (un-named) semaphore. */
|
||||
|
||||
static sem_t g_mm_semaphore;
|
||||
static pid_t g_holder;
|
||||
static int g_counts_held;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -91,16 +83,16 @@ static int g_counts_held;
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mm_seminitialize(void)
|
||||
void mm_seminitialize(FAR struct mm_heap_s *heap)
|
||||
{
|
||||
/* Initialize the MM semaphore to one (to support one-at-a-time access to
|
||||
* private data sets.
|
||||
*/
|
||||
|
||||
(void)sem_init(&g_mm_semaphore, 0, 1);
|
||||
(void)sem_init(&heap->mm_semaphore, 0, 1);
|
||||
|
||||
g_holder = -1;
|
||||
g_counts_held = 0;
|
||||
heap->mm_holder = -1;
|
||||
heap->mm_counts_held = 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -115,32 +107,32 @@ void mm_seminitialize(void)
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MM_TEST
|
||||
int mm_trysemaphore(void)
|
||||
int mm_trysemaphore(FAR struct mm_heap_s *heap)
|
||||
{
|
||||
pid_t my_pid = getpid();
|
||||
|
||||
/* Do I already have the semaphore? */
|
||||
|
||||
if (g_holder == my_pid)
|
||||
if (heap->mm_holder == my_pid)
|
||||
{
|
||||
/* Yes, just increment the number of references that I have */
|
||||
|
||||
g_counts_held++;
|
||||
heap->mm_counts_held++;
|
||||
return OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Try to take the semaphore (perhaps waiting) */
|
||||
|
||||
if (sem_trywait(&g_mm_semaphore) != 0)
|
||||
if (sem_trywait(&heap->mm_semaphore) != 0)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* We have it. Claim the stak and return */
|
||||
|
||||
g_holder = my_pid;
|
||||
g_counts_held = 1;
|
||||
heap->mm_holder = my_pid;
|
||||
heap->mm_counts_held = 1;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
@ -155,24 +147,24 @@ int mm_trysemaphore(void)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mm_takesemaphore(void)
|
||||
void mm_takesemaphore(FAR struct mm_heap_s *heap)
|
||||
{
|
||||
pid_t my_pid = getpid();
|
||||
|
||||
/* Do I already have the semaphore? */
|
||||
|
||||
if (g_holder == my_pid)
|
||||
if (heap->mm_holder == my_pid)
|
||||
{
|
||||
/* Yes, just increment the number of references that I have */
|
||||
|
||||
g_counts_held++;
|
||||
heap->mm_counts_held++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Take the semaphore (perhaps waiting) */
|
||||
|
||||
msemdbg("PID=%d taking\n", my_pid);
|
||||
while (sem_wait(&g_mm_semaphore) != 0)
|
||||
while (sem_wait(&heap->mm_semaphore) != 0)
|
||||
{
|
||||
/* The only case that an error should occur here is if
|
||||
* the wait was awakened by a signal.
|
||||
@ -183,11 +175,11 @@ void mm_takesemaphore(void)
|
||||
|
||||
/* We have it. Claim the stake and return */
|
||||
|
||||
g_holder = my_pid;
|
||||
g_counts_held = 1;
|
||||
heap->mm_holder = my_pid;
|
||||
heap->mm_counts_held = 1;
|
||||
}
|
||||
|
||||
msemdbg("Holder=%d count=%d\n", g_holder, g_counts_held);
|
||||
msemdbg("Holder=%d count=%d\n", heap->mm_holder, heap->mm_counts_held);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -198,7 +190,7 @@ void mm_takesemaphore(void)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mm_givesemaphore(void)
|
||||
void mm_givesemaphore(FAR struct mm_heap_s *heap)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG
|
||||
pid_t my_pid = getpid();
|
||||
@ -206,25 +198,25 @@ void mm_givesemaphore(void)
|
||||
|
||||
/* I better be holding at least one reference to the semaphore */
|
||||
|
||||
DEBUGASSERT(g_holder == my_pid);
|
||||
DEBUGASSERT(heap->mm_holder == my_pid);
|
||||
|
||||
/* Do I hold multiple references to the semphore */
|
||||
|
||||
if (g_counts_held > 1)
|
||||
if (heap->mm_counts_held > 1)
|
||||
{
|
||||
/* Yes, just release one count and return */
|
||||
|
||||
g_counts_held--;
|
||||
msemdbg("Holder=%d count=%d\n", g_holder, g_counts_held);
|
||||
heap->mm_counts_held--;
|
||||
msemdbg("Holder=%d count=%d\n", heap->mm_holder, heap->mm_counts_held);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nope, this is the last reference I have */
|
||||
|
||||
msemdbg("PID=%d giving\n", my_pid);
|
||||
g_holder = -1;
|
||||
g_counts_held = 0;
|
||||
ASSERT(sem_post(&g_mm_semaphore) == 0);
|
||||
heap->mm_holder = -1;
|
||||
heap->mm_counts_held = 0;
|
||||
ASSERT(sem_post(&heap->mm_semaphore) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,10 +229,10 @@ void mm_givesemaphore(void)
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef MM_TEST
|
||||
int mm_getsemaphore(void)
|
||||
int mm_getsemaphore(FAR struct mm_heap_s *heap)
|
||||
{
|
||||
int sval;
|
||||
sem_getvalue(&g_mm_semaphore, &sval);
|
||||
sem_getvalue(&heap->mm_semaphore, &sval);
|
||||
return sval;
|
||||
}
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* mm/mm_shrinkchunk.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 1013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -63,7 +63,8 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mm_shrinkchunk(FAR struct mm_allocnode_s *node, size_t size)
|
||||
void mm_shrinkchunk(FAR struct mm_heap_s *heap,
|
||||
FAR struct mm_allocnode_s *node, size_t size)
|
||||
{
|
||||
FAR struct mm_freenode_s *next;
|
||||
|
||||
@ -108,7 +109,7 @@ void mm_shrinkchunk(FAR struct mm_allocnode_s *node, size_t size)
|
||||
|
||||
/* Add the new node to the freenodelist */
|
||||
|
||||
mm_addfreechunk(newnode);
|
||||
mm_addfreechunk(heap, newnode);
|
||||
}
|
||||
|
||||
/* The next chunk is allocated. Try to free the end portion at the end
|
||||
@ -134,6 +135,6 @@ void mm_shrinkchunk(FAR struct mm_allocnode_s *node, size_t size)
|
||||
|
||||
/* Add the new node to the freenodelist */
|
||||
|
||||
mm_addfreechunk(newnode);
|
||||
mm_addfreechunk(heap, newnode);
|
||||
}
|
||||
}
|
||||
|
23
mm/mm_test.c
23
mm/mm_test.c
@ -1,7 +1,7 @@
|
||||
/************************************************************************
|
||||
* mm/mm_test.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 2011, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -40,6 +40,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
/************************************************************************
|
||||
* Pre-processor Definitions
|
||||
@ -133,7 +134,7 @@ static int mm_findinfreelist(struct mm_freenode_s *node)
|
||||
{
|
||||
struct mm_freenode_s *list;
|
||||
|
||||
for(list = &g_nodelist[0];
|
||||
for(list = &g_mmheap.mm_nodelist[0];
|
||||
list;
|
||||
list = list->flink)
|
||||
{
|
||||
@ -165,13 +166,13 @@ static void mm_showchunkinfo(void)
|
||||
/* Visit each region */
|
||||
|
||||
#if CONFIG_MM_REGIONS > 1
|
||||
for (region = 0; region < g_nregions; region++)
|
||||
for (region = 0; region < g_mmheap.mm_nregions; region++)
|
||||
#endif
|
||||
{
|
||||
/* Visit each node in each region */
|
||||
|
||||
for (node = g_heapstart[region];
|
||||
node < g_heapend[region];
|
||||
for (node = g_mmheap.mm_heapstart[region];
|
||||
node < g_mmheap.mm_heapend[region];
|
||||
node = (struct mm_allocnode_s *)((char*)node + node->size))
|
||||
{
|
||||
printf(" %p 0x%08x 0x%08x %s",
|
||||
@ -206,7 +207,7 @@ static void mm_showfreelist(void)
|
||||
int i = 0;
|
||||
|
||||
printf(" FREE NODE LIST:\n");
|
||||
for(prev = NULL, node = &g_nodelist[0];
|
||||
for(prev = NULL, node = &g_mmheap.mm_nodelist[0];
|
||||
node;
|
||||
prev = node, node = node->flink)
|
||||
{
|
||||
@ -258,7 +259,7 @@ static void mm_showmallinfo(void)
|
||||
printf(" Total non-inuse space = %ld\n",
|
||||
alloc_info.fordblks);
|
||||
|
||||
sval = mm_getsemaphore();
|
||||
sval = mm_getsemaphore(&g_mmheap);
|
||||
if (sval != 1)
|
||||
{
|
||||
fprintf(stderr, "After mallinfo, semaphore count=%d, should be 1\n", sval);
|
||||
@ -322,7 +323,7 @@ static void do_mallocs(void **mem, const int *size, const int *rand,
|
||||
memset(mem[j], 0xAA, size[j]);
|
||||
}
|
||||
|
||||
sval = mm_getsemaphore();
|
||||
sval = mm_getsemaphore(&g_mmheap);
|
||||
if (sval != 1)
|
||||
{
|
||||
fprintf(stderr, " After malloc semaphore count=%d, should be 1\n", sval);
|
||||
@ -371,7 +372,7 @@ static void do_reallocs(void **mem, const int *oldsize,
|
||||
memset(mem[j], 0x55, newsize[j]);
|
||||
}
|
||||
|
||||
sval = mm_getsemaphore();
|
||||
sval = mm_getsemaphore(&g_mmheap);
|
||||
if (sval != 1)
|
||||
{
|
||||
fprintf(stderr, " After realloc semaphore count=%d, should be 1\n", sval);
|
||||
@ -419,7 +420,7 @@ static void do_memaligns(void **mem, const int *size, const int *align,
|
||||
memset(mem[j], 0x33, size[j]);
|
||||
}
|
||||
|
||||
sval = mm_getsemaphore();
|
||||
sval = mm_getsemaphore(&g_mmheap);
|
||||
if (sval != 1)
|
||||
{
|
||||
fprintf(stderr, " After memalign semaphore count=%d, should be 1\n", sval);
|
||||
@ -448,7 +449,7 @@ static void do_frees(void **mem, const int *size, const int *rand, int n)
|
||||
mm_free(mem[j]);
|
||||
mem[j] = NULL;
|
||||
|
||||
sval = mm_getsemaphore();
|
||||
sval = mm_getsemaphore(&g_mmheap);
|
||||
if (sval != 1)
|
||||
{
|
||||
fprintf(stderr, " After free semaphore count=%d, should be 1\n", sval);
|
||||
|
Loading…
Reference in New Issue
Block a user