From 3b23ee2703a28a1b46bbd3eb4835b05ae321de29 Mon Sep 17 00:00:00 2001 From: patacongo Date: Sun, 4 Mar 2007 15:23:22 +0000 Subject: Add capability to manager memory in discontiguous regions. git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@35 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/arch/README.txt | 4 + nuttx/arch/c5471/defconfig | 5 ++ nuttx/arch/pjrc-8051/defconfig | 7 +- nuttx/arch/pjrc-8051/src/up_allocateheap.c | 7 ++ nuttx/arch/pjrc-8051/src/up_assert.c | 2 +- nuttx/arch/pjrc-8051/src/up_initialize.c | 6 ++ nuttx/arch/pjrc-8051/src/up_internal.h | 7 +- nuttx/arch/pjrc-8051/src/up_putc.c | 6 +- nuttx/arch/sim/defconfig | 5 ++ nuttx/examples/ostest/main.c | 4 +- nuttx/include/nuttx/os_external.h | 3 +- nuttx/lib/lib_rawprintf.c | 17 ++++ nuttx/mm/mm_environment.h | 10 +++ nuttx/mm/mm_initialize.c | 106 +++++++++++++++++++------ nuttx/mm/mm_internal.h | 10 ++- nuttx/mm/mm_mallinfo.c | 45 +++++++---- nuttx/mm/mm_test.c | 122 ++++++++++++++++++----------- nuttx/sched/sched_rrgetinterval.c | 2 +- nuttx/tools/mkconfig.c | 4 + 19 files changed, 277 insertions(+), 95 deletions(-) diff --git a/nuttx/arch/README.txt b/nuttx/arch/README.txt index c01215963..64a77e924 100644 --- a/nuttx/arch/README.txt +++ b/nuttx/arch/README.txt @@ -78,6 +78,10 @@ defconfig -- This is a configuration file similar to the Linux CONFIG_DEBUG_VERBOSE - enables verbose debug output CONFIG_HAVE_LOWPUTC - architecture supports low-level, boot time console output + CONFIG_MM_REGIONS - If the architecture includes multiple + regions of memory to allocate from, this specifies the + number of memory regions that the memory manager must + handle and enables the API mm_addregion(start, end); CONFIG_RR_INTERVAL - The round robin timeslice will be set this number of milliseconds; Round robin scheduling can be disabled by setting this value to zero. diff --git a/nuttx/arch/c5471/defconfig b/nuttx/arch/c5471/defconfig index 90ae4c898..1ce7dd879 100644 --- a/nuttx/arch/c5471/defconfig +++ b/nuttx/arch/c5471/defconfig @@ -81,6 +81,10 @@ CONFIG_UART_MODEM_2STOP=0 # that will be used in the build # CONFIG_DEBUG - enables built-in debug options # CONFIG_DEBUG_VERBOSE - enables verbose debug output +# CONFIG_MM_REGIONS - If the architecture includes multiple +# regions of memory to allocate from, this specifies the +# number of memory regions that the memory manager must +# handle and enables the API mm_addregion(start, end); # CONFIG_HAVE_LOWPUTC - architecture supports low-level, boot # time console output # CONFIG_RR_INTERVAL - The round robin timeslice will be set @@ -100,6 +104,7 @@ CONFIG_UART_MODEM_2STOP=0 CONFIG_EXAMPLE=ostest CONFIG_DEBUG=y CONFIG_DEBUG_VERBOSE=n +CONFIG_MM_REGIONS=1 CONFIG_ARCH_LOWPUTC=y CONFIG_RR_INTERVAL=200 CONFIG_SCHED_INSTRUMENTATION=n diff --git a/nuttx/arch/pjrc-8051/defconfig b/nuttx/arch/pjrc-8051/defconfig index d40be28da..508440c27 100644 --- a/nuttx/arch/pjrc-8051/defconfig +++ b/nuttx/arch/pjrc-8051/defconfig @@ -48,6 +48,10 @@ CONFIG_ARCH_8051=y # that will be used in the build # CONFIG_DEBUG - enables built-in debug options # CONFIG_DEBUG_VERBOSE - enables verbose debug output +# CONFIG_MM_REGIONS - If the architecture includes multiple +# regions of memory to allocate from, this specifies the +# number of memory regions that the memory manager must +# handle and enables the API mm_addregion(start, end); # CONFIG_HAVE_LOWPUTC - architecture supports low-level, boot # time console output # CONFIG_RR_INTERVAL - The round robin timeslice will be set @@ -67,8 +71,9 @@ CONFIG_ARCH_8051=y CONFIG_EXAMPLE=ostest CONFIG_DEBUG=n CONFIG_DEBUG_VERBOSE=n +CONFIG_MM_REGIONS=2 CONFIG_ARCH_LOWPUTC=y -CONFIG_RR_INTERVAL=200 +CONFIG_RR_INTERVAL=0 CONFIG_SCHED_INSTRUMENTATION=n CONFIG_TASK_NAME_SIZE=0 CONFIG_START_YEAR=2007 diff --git a/nuttx/arch/pjrc-8051/src/up_allocateheap.c b/nuttx/arch/pjrc-8051/src/up_allocateheap.c index 6f164f0d3..b6e6a0208 100644 --- a/nuttx/arch/pjrc-8051/src/up_allocateheap.c +++ b/nuttx/arch/pjrc-8051/src/up_allocateheap.c @@ -78,3 +78,10 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size) *heap_start = (FAR void*)UP_HEAP1_BASE; *heap_size = UP_HEAP1_END - UP_HEAP1_BASE; } + +#if CONFIG_MM_REGIONS > 1 +void up_addregion(void) +{ + mm_addregion((FAR void*)UP_HEAP2_BASE, UP_HEAP2_END - UP_HEAP2_BASE); +} +#endif \ No newline at end of file diff --git a/nuttx/arch/pjrc-8051/src/up_assert.c b/nuttx/arch/pjrc-8051/src/up_assert.c index b9ac5db43..0234e9ecd 100644 --- a/nuttx/arch/pjrc-8051/src/up_assert.c +++ b/nuttx/arch/pjrc-8051/src/up_assert.c @@ -75,6 +75,6 @@ void up_assert(void) void up_assert_code(int errorcode) { - dbg("Assertion failed with error code: %d\n", errcode); + dbg("Assertion failed with error code: %d\n", errorcode); exit(errorcode); } diff --git a/nuttx/arch/pjrc-8051/src/up_initialize.c b/nuttx/arch/pjrc-8051/src/up_initialize.c index ae297d585..5388882da 100644 --- a/nuttx/arch/pjrc-8051/src/up_initialize.c +++ b/nuttx/arch/pjrc-8051/src/up_initialize.c @@ -93,6 +93,12 @@ void up_initialize(void) g_irqtos = 0; + /* Add extra memory fragments to the memory manager */ + +#if CONFIG_MM_REGIONS > 1 + up_addregion(); +#endif + /* Initialize the interrupt subsystem */ up_irqinitialize(); diff --git a/nuttx/arch/pjrc-8051/src/up_internal.h b/nuttx/arch/pjrc-8051/src/up_internal.h index 54320a288..25fa06243 100644 --- a/nuttx/arch/pjrc-8051/src/up_internal.h +++ b/nuttx/arch/pjrc-8051/src/up_internal.h @@ -102,7 +102,9 @@ * when the following simple addtions do the job). */ +#ifndef __ASSEMBLY__ sfr at 0xc9 T2MOD ; +#endif /* Timing information. * @@ -175,9 +177,12 @@ extern ubyte g_irqtos; #ifndef __ASSEMBLY__ +#if CONFIG_MM_REGIONS > 1 +extern void up_addregion(void); +#endif extern void up_irqinitialize(void); extern void up_restorecontext(FAR struct xcptcontext *context); -extern void up_restorestack(FAR struct xcptcontext *context); +extern void up_restorestack(FAR struct xcptcontext *context); extern ubyte up_savecontext(FAR struct xcptcontext *context); extern void up_savestack(FAR struct xcptcontext *context); extern void up_timerinit(void); diff --git a/nuttx/arch/pjrc-8051/src/up_putc.c b/nuttx/arch/pjrc-8051/src/up_putc.c index d2e486829..95f25aa3b 100644 --- a/nuttx/arch/pjrc-8051/src/up_putc.c +++ b/nuttx/arch/pjrc-8051/src/up_putc.c @@ -48,7 +48,7 @@ static void _up_putc(int ch) __naked { -#if 0 +#if 1 ch; /* To avoid unreferenced argument warning */ _asm mov a, dpl @@ -73,6 +73,10 @@ cout: jnb ti, cout int up_putc(int ch) { _up_putc(ch); + if (ch == '\n') + { + _up_putc('\r'); + } return ch; } diff --git a/nuttx/arch/sim/defconfig b/nuttx/arch/sim/defconfig index 9a3cb893c..9d8aab7aa 100644 --- a/nuttx/arch/sim/defconfig +++ b/nuttx/arch/sim/defconfig @@ -48,6 +48,10 @@ CONFIG_ARCH_SIM=y # that will be used in the build # CONFIG_DEBUG - enables built-in debug options # CONFIG_DEBUG_VERBOSE - enables verbose debug output +# CONFIG_MM_REGIONS - If the architecture includes multiple +# regions of memory to allocate from, this specifies the +# number of memory regions that the memory manager must +# handle and enables the API mm_addregion(start, end); # CONFIG_HAVE_LOWPUTC - architecture supports low-level, boot # time console output # CONFIG_RR_INTERVAL - The round robin timeslice will be set @@ -67,6 +71,7 @@ CONFIG_ARCH_SIM=y CONFIG_EXAMPLE=ostest CONFIG_DEBUG=y CONFIG_DEBUG_VERBOSE=y +CONFIG_MM_REGIONS=1 CONFIG_ARCH_LOWPUTC=y CONFIG_RR_INTERVAL=200 CONFIG_SCHED_INSTRUMENTATION=n diff --git a/nuttx/examples/ostest/main.c b/nuttx/examples/ostest/main.c index 8e09230f5..4e360e6b5 100644 --- a/nuttx/examples/ostest/main.c +++ b/nuttx/examples/ostest/main.c @@ -178,12 +178,12 @@ int user_start(int parm1, int parm2, int parm3, int parm4) /* Verify that we can communicate */ #if CONFIG_NFILE_DESCRIPTORS > 0 - write(1, write_data1, sizeof(write_data1)); + write(1, write_data1, sizeof(write_data1)-1); #endif printf("user_start: Standard I/O Check: printf\n"); #if CONFIG_NFILE_DESCRIPTORS > 1 - write(2, write_data2, sizeof(write_data2)); + write(2, write_data2, sizeof(write_data2)-1); #endif #if CONFIG_NFILE_STREAMS > 0 fprintf(stderr, "user_start: Standard I/O Check: fprintf to stderr\n"); diff --git a/nuttx/include/nuttx/os_external.h b/nuttx/include/nuttx/os_external.h index 1d475d84e..09557595c 100644 --- a/nuttx/include/nuttx/os_external.h +++ b/nuttx/include/nuttx/os_external.h @@ -73,9 +73,10 @@ EXTERN int user_start(int parm1, int parm2, int parm3, int parm4); EXTERN void os_start(void); /* OS entry point called by boot logic */ -/* Functions contained in mm_init.c *************************/ +/* 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); #undef EXTERN #ifdef __cplusplus diff --git a/nuttx/lib/lib_rawprintf.c b/nuttx/lib/lib_rawprintf.c index 9b65f5a8a..fa2f5a63e 100644 --- a/nuttx/lib/lib_rawprintf.c +++ b/nuttx/lib/lib_rawprintf.c @@ -83,6 +83,8 @@ int lib_rawvprintf(const char *fmt, va_list ap) { +#if CONFIG_NFILE_DESCRIPTORS > 0 + struct lib_rawstream_s rawstream; /* Wrap the stdout in a stream object and let lib_vsprintf @@ -91,6 +93,21 @@ int lib_rawvprintf(const char *fmt, va_list ap) lib_rawstream(&rawstream, 1); return lib_vsprintf(&rawstream.public, fmt, ap); + +#elif defined(CONFIG_ARCH_LOWPUTC) + + struct lib_stream_s stream; + + /* Wrap the stdout in a stream object and let lib_vsprintf + * do the work. + */ + + lib_lowstream(&stream); + return lib_vsprintf(&stream, fmt, ap); + +#else + return 0; +#endif } /************************************************************ diff --git a/nuttx/mm/mm_environment.h b/nuttx/mm/mm_environment.h index 14476957d..8777323b0 100644 --- a/nuttx/mm/mm_environment.h +++ b/nuttx/mm/mm_environment.h @@ -54,6 +54,7 @@ # include # include # include +# include #else # include # include @@ -70,6 +71,15 @@ #ifdef MM_TEST +/* Fake NuttX dependencies */ + +# define FAR /* Normally in compiler.h */ +# define CONFIG_MM_REGIONS 2 /* Normally in config.h */ +# 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); + /* Use the real system errno */ # define mm_errno errno diff --git a/nuttx/mm/mm_initialize.c b/nuttx/mm/mm_initialize.c index 6d16a5677..c9c1c4bad 100644 --- a/nuttx/mm/mm_initialize.c +++ b/nuttx/mm/mm_initialize.c @@ -54,8 +54,12 @@ size_t g_heapsize; /* This is the first and last nodes of the heap */ -FAR struct mm_allocnode_s *g_heapstart; -FAR struct mm_allocnode_s *g_heapend; +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 @@ -76,7 +80,8 @@ FAR struct mm_freenode_s g_nodelist[MM_NNODES]; * boot time. * * Parameters: - * None + * heapstart - Start of the initial heap region + * heapsize - Size of the initial heap region * * Return Value: * None @@ -95,16 +100,13 @@ void mm_initialize(FAR void *heapstart, size_t heapsize) CHECK_ALLOCNODE_SIZE; CHECK_FREENODE_SIZE; - /* Adjust the provide heap start and size so that they are - * both aligned with the MM_MIN_CHUNK size. - */ + /* Set up global variables */ - heapbase = MM_ALIGN_UP((size_t)heapstart); - heapend = MM_ALIGN_DOWN((size_t)heapstart + (size_t)heapsize); + g_heapsize = 0; - /* Save the size of the heap */ - - g_heapsize = heapend - heapbase; +#if CONFIG_MM_REGIONS > 1 + g_nregions = 0; +#endif /* Initialize the node array */ @@ -115,6 +117,58 @@ void mm_initialize(FAR void *heapstart, size_t heapsize) 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); +} + +/************************************************************ + * Function: mm_addregion + * + * Description: + * This function gives a region of contiguous memory to + * the memory manager + * + * Parameters: + * heapstart - Start of the heap region + * heapsize - Size of the heap region + * + * Return Value: + * None + * + * Assumptions: + * + ************************************************************/ + +void mm_addregion(FAR void *heapstart, size_t heapsize) +{ + FAR struct mm_freenode_s *node; + size_t heapbase; + size_t heapend; +#if CONFIG_MM_REGIONS > 1 + int IDX = g_nregions; +#else +# define IDX 0 +#endif + + /* Adjust the provide heap start and size so that they are + * both aligned with the MM_MIN_CHUNK size. + */ + + heapbase = MM_ALIGN_UP((size_t)heapstart); + heapend = MM_ALIGN_DOWN((size_t)heapstart + (size_t)heapsize); + heapsize = heapend - heapbase; + + /* Add the size of this region to the total size of the heap */ + + g_heapsize += heapsize; + /* Create two "allocated" guard nodes at the beginning and end of * the heap. These only serve to keep us from allocating outside * of the heap. @@ -123,25 +177,25 @@ void mm_initialize(FAR void *heapstart, size_t heapsize) * all available memory. */ - g_heapstart = (FAR struct mm_allocnode_s *)heapbase; - g_heapstart->size = SIZEOF_MM_ALLOCNODE; - g_heapstart->preceding = MM_ALLOC_BIT; + g_heapstart[IDX] = (FAR struct mm_allocnode_s *)heapbase; + g_heapstart[IDX]->size = SIZEOF_MM_ALLOCNODE; + g_heapstart[IDX]->preceding = MM_ALLOC_BIT; - node = (FAR struct mm_freenode_s *)(heapbase + SIZEOF_MM_ALLOCNODE); - node->size = g_heapsize - 2*SIZEOF_MM_ALLOCNODE; - node->preceding = SIZEOF_MM_ALLOCNODE; + node = (FAR struct mm_freenode_s *)(heapbase + SIZEOF_MM_ALLOCNODE); + node->size = heapsize - 2*SIZEOF_MM_ALLOCNODE; + node->preceding = SIZEOF_MM_ALLOCNODE; - g_heapend = (FAR struct mm_allocnode_s *)(heapend - SIZEOF_MM_ALLOCNODE); - g_heapend->size = SIZEOF_MM_ALLOCNODE; - g_heapend->preceding = node->size | MM_ALLOC_BIT; + 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; - /* Add the single, large free node to the nodelist */ +#undef IDX - mm_addfreechunk(node); +#if CONFIG_MM_REGIONS > 1 + g_nregions++; +#endif - /* Initialize the malloc semaphore to one (to support one-at- - * a-time access to private data sets. - */ + /* Add the single, large free node to the nodelist */ - mm_seminitialize(); + mm_addfreechunk(node); } diff --git a/nuttx/mm/mm_internal.h b/nuttx/mm/mm_internal.h index e1b9f9beb..e9ab414dc 100644 --- a/nuttx/mm/mm_internal.h +++ b/nuttx/mm/mm_internal.h @@ -160,8 +160,14 @@ extern size_t g_heapsize; /* This is the first and last nodes of the heap */ -extern FAR struct mm_allocnode_s *g_heapstart; -extern FAR struct mm_allocnode_s *g_heapend; +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; +#else +# define g_nregions 1 +#endif /* All free nodes are maintained in a doubly linked list. This * array provides some hooks into the list at various points to diff --git a/nuttx/mm/mm_mallinfo.c b/nuttx/mm/mm_mallinfo.c index 68c2a7bb7..0e6ae4e78 100644 --- a/nuttx/mm/mm_mallinfo.c +++ b/nuttx/mm/mm_mallinfo.c @@ -76,6 +76,11 @@ int mallinfo(struct mallinfo *info) int ordblks = 0; /* Number of non-inuse chunks */ size_t uordblks = 0; /* Total allocated space */ size_t fordblks = 0; /* Total non-inuse space */ +#if CONFIG_MM_REGIONS > 1 + int region; +#else +# define region 0 +#endif #ifdef CONFIG_CAN_PASS_STRUCTS static struct mallinfo info; @@ -85,29 +90,39 @@ int mallinfo(struct mallinfo *info) return ERROR; } #endif - /* Visit each node in physical memory */ - for (node = g_heapstart; - node < g_heapend; - node = (struct mm_allocnode_s *)((char*)node + node->size)) + /* Visit each region */ + +#if CONFIG_MM_REGIONS > 1 + for (region = 0; region < g_nregions; region++) +#endif { - if (node->preceding & MM_ALLOC_BIT) - { - uordblks += node->size; - } - else + /* Visit each node in the region */ + + for (node = g_heapstart[region]; + node < g_heapend[region]; + node = (struct mm_allocnode_s *)((char*)node + node->size)) { - ordblks++; - fordblks += node->size; - if (node->size > mxordblk) + if (node->preceding & MM_ALLOC_BIT) { - mxordblk = node->size; + uordblks += node->size; + } + else + { + ordblks++; + fordblks += node->size; + if (node->size > mxordblk) + { + mxordblk = node->size; + } } } + + DEBUGASSERT(node == g_heapend[region]); + uordblks += SIZEOF_MM_ALLOCNODE; /* account for the tail node */ } +#undef region - DEBUGASSERT(node == g_heapend); - uordblks += SIZEOF_MM_ALLOCNODE; /* account for the tail node */ DEBUGASSERT(uordblks + fordblks == g_heapsize); #ifdef CONFIG_CAN_PASS_STRUCTS diff --git a/nuttx/mm/mm_test.c b/nuttx/mm/mm_test.c index 779fd607c..4dadcec27 100644 --- a/nuttx/mm/mm_test.c +++ b/nuttx/mm/mm_test.c @@ -37,21 +37,24 @@ #include #include +/* Fake NuttX dependencies */ + +#define FAR +#define CONFIG_MM_REGIONS 2 +#define CONFIG_CAN_PASS_STRUCTS 1 +#undef CONFIG_SMALL_MEMORY + #include "mm_internal.h" /* Definitions */ -#define TEST_HEAP_SIZE 0x00100000 +#define TEST_HEAP1_SIZE 0x00080000 +#define TEST_HEAP2_SIZE 0x00080000 #define NTEST_ALLOCS 32 /* #define STOP_ON_ERRORS do{}while(0) */ #define STOP_ON_ERRORS exit(1) -/* Heap provided to memory manager */ - -unsigned long heap_base; -unsigned long heap_size = TEST_HEAP_SIZE; - /* Test allocations */ static const int alloc_sizes[NTEST_ALLOCS] = @@ -94,9 +97,10 @@ static const int alignment[NTEST_ALLOCS/2] = 128, 2048, 131072, 8192, 32, 32768, 16384 , 262144, 512, 4096, 65536, 8, 64, 1024, 16, 4 }; -static void *allocs[NTEST_ALLOCS]; -static struct mallinfo alloc_info; -static unsigned int g_adjheapsize = 0; +static void *allocs[NTEST_ALLOCS]; +static struct mallinfo alloc_info; +static unsigned int g_reportedheapsize = 0; +static unsigned int g_actualheapsize = 0; /************************************************************ * mm_showchunkinfo @@ -121,33 +125,46 @@ static int mm_findinfreelist(struct mm_freenode_s *node) static void mm_showchunkinfo(void) { struct mm_allocnode_s *node; +#if CONFIG_MM_REGIONS > 1 + int region; +#else +# define region 0 +#endif int found; - /* Visit each node in physical memory */ - printf(" CHUNK LIST:\n"); - for (node = g_heapstart; - node < g_heapend; - node = (struct mm_allocnode_s *)((char*)node + node->size)) + /* Visit each region */ + +#if CONFIG_MM_REGIONS > 1 + for (region = 0; region < g_nregions; region++) +#endif { - printf(" %p 0x%08x 0x%08x %s", - node, node->size, node->preceding & ~MM_ALLOC_BIT, - node->preceding & MM_ALLOC_BIT ? "Allocated" : "Free "); - found = mm_findinfreelist((struct mm_freenode_s *)node); - if (found && (node->preceding & MM_ALLOC_BIT) != 0) - { - printf(" Should NOT have been in free list\n"); - } - else if (!found && (node->preceding & MM_ALLOC_BIT) == 0) - { - printf(" SHOULD have been in free listT\n"); - } - else - { - printf(" OK\n"); + /* Visit each node in each region */ + + for (node = g_heapstart[region]; + node < g_heapend[region]; + node = (struct mm_allocnode_s *)((char*)node + node->size)) + { + printf(" %p 0x%08x 0x%08x %s", + node, node->size, node->preceding & ~MM_ALLOC_BIT, + node->preceding & MM_ALLOC_BIT ? "Allocated" : "Free "); + found = mm_findinfreelist((struct mm_freenode_s *)node); + if (found && (node->preceding & MM_ALLOC_BIT) != 0) + { + printf(" Should NOT have been in free list\n"); + } + else if (!found && (node->preceding & MM_ALLOC_BIT) == 0) + { + printf(" SHOULD have been in free listT\n"); + } + else + { + printf(" OK\n"); + } } } +#undef region } static void mm_showfreelist(void) @@ -212,21 +229,21 @@ static void mm_showmallinfo(void) STOP_ON_ERRORS; } - if (!g_adjheapsize) + if (!g_reportedheapsize) { - g_adjheapsize = alloc_info.uordblks + alloc_info.fordblks; - if (g_adjheapsize > TEST_HEAP_SIZE + 16 || - g_adjheapsize < TEST_HEAP_SIZE -16) + g_reportedheapsize = alloc_info.uordblks + alloc_info.fordblks; + if (g_reportedheapsize > g_actualheapsize + 16*CONFIG_MM_REGIONS || + g_reportedheapsize < g_actualheapsize -16*CONFIG_MM_REGIONS) { fprintf(stderr, "Total memory %d not close to uordlbks=%d + fordblks=%d = %d\n", - TEST_HEAP_SIZE, g_adjheapsize, alloc_info.uordblks, alloc_info.fordblks, g_adjheapsize); + g_actualheapsize, alloc_info.uordblks, alloc_info.fordblks, g_reportedheapsize); STOP_ON_ERRORS; } } - else if (alloc_info.uordblks + alloc_info.fordblks != g_adjheapsize) + else if (alloc_info.uordblks + alloc_info.fordblks != g_reportedheapsize) { fprintf(stderr, "Total memory %d != uordlbks=%d + fordblks=%d\n", - g_adjheapsize, alloc_info.uordblks, alloc_info.fordblks); + g_reportedheapsize, alloc_info.uordblks, alloc_info.fordblks); STOP_ON_ERRORS; } } @@ -389,23 +406,39 @@ static do_frees(void **mem, const int *size, const int *rand, int n) int main(int argc, char **argv, char **envp) { - void *heapbase; + void *heap1_base; + void *heap2_base; int i, j; /* Allocate a heap */ - printf("Allocating test heap of %ldKb\n", TEST_HEAP_SIZE/1024); - heapbase = malloc(TEST_HEAP_SIZE); - printf("Allocated heap_base=%p\n", heap_base); - if (heapbase == 0) + printf("Allocating test heap #1 of %ldKb\n", TEST_HEAP1_SIZE/1024); + heap1_base = malloc(TEST_HEAP1_SIZE); + printf("Allocated heap1_base=%p\n", heap1_base); + if (heap1_base == 0) { - fprintf(stderr, "Failed to allocate test heap\n"); + fprintf(stderr, "Failed to allocate test heap #1\n"); + exit(1); + } + + printf("Allocating test heap #2 of %ldKb\n", TEST_HEAP2_SIZE/1024); + heap2_base = malloc(TEST_HEAP2_SIZE); + printf("Allocated heap2_base=%p\n", heap2_base); + if (heap2_base == 0) + { + fprintf(stderr, "Failed to allocate test heap #2\n"); exit(1); } /* Initialize the memory manager */ - mm_initialize(heapbase, TEST_HEAP_SIZE); + mm_initialize(heap1_base, TEST_HEAP1_SIZE); + g_actualheapsize = TEST_HEAP1_SIZE; + mm_showmallinfo(); + + mm_addregion(heap2_base, TEST_HEAP2_SIZE); + g_reportedheapsize = 0; + g_actualheapsize += TEST_HEAP2_SIZE; mm_showmallinfo(); /* Allocate some memory */ @@ -431,7 +464,8 @@ int main(int argc, char **argv, char **envp) /* Clean up and exit */ - free(heapbase); + free(heap1_base); + free(heap2_base); printf("TEST COMPLETE\n"); return 0; diff --git a/nuttx/sched/sched_rrgetinterval.c b/nuttx/sched/sched_rrgetinterval.c index dff4ebb4c..8e0ca2824 100644 --- a/nuttx/sched/sched_rrgetinterval.c +++ b/nuttx/sched/sched_rrgetinterval.c @@ -150,7 +150,7 @@ int sched_rr_get_interval(pid_t pid, struct timespec *interval) return OK; #else - *get_errnor_ptr() = ENOSYS; + *get_errno_ptr() = ENOSYS; return ERROR; #endif } diff --git a/nuttx/tools/mkconfig.c b/nuttx/tools/mkconfig.c index e7394702f..668e2a945 100644 --- a/nuttx/tools/mkconfig.c +++ b/nuttx/tools/mkconfig.c @@ -225,6 +225,10 @@ int main(int argc, char **argv, char **envp) printf("# undef CONFIG_NFILE_STREAMS\n"); printf("# define CONFIG_NFILE_STREAMS 0\n"); printf("#endif\n\n"); + printf("/* There must be at least one memory region. */\n\n"); + printf("#ifndef CONFIG_MM_REGIONS\n"); + printf("# define CONFIG_MM_REGIONS 1\n"); + printf("#endif\n\n"); printf("/* If no file streams are configured, then make certain that\n"); printf(" * buffered I/O support is disabled.\n"); printf(" */\n\n"); -- cgit v1.2.3