From 6efc831f0ff3d975fa9086a46c3a67b6f2b95100 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 9 Nov 2018 12:11:11 +0100 Subject: Add rtems_malloc() and rtems_calloc() Close #3583. --- cpukit/include/rtems/malloc.h | 33 +++++++++++++++++++++ cpukit/libcsupport/src/malloc_deferred.c | 25 ++++++++++++++++ testsuites/libtests/malloctest/init.c | 51 ++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+) diff --git a/cpukit/include/rtems/malloc.h b/cpukit/include/rtems/malloc.h index a6cfeb574f..6fdab3d02f 100644 --- a/cpukit/include/rtems/malloc.h +++ b/cpukit/include/rtems/malloc.h @@ -141,6 +141,39 @@ void *rtems_heap_allocate_aligned_with_boundary( ) RTEMS_MALLOCLIKE RTEMS_ALLOC_SIZE(1) RTEMS_ALLOC_ALIGN(2) RTEMS_WARN_UNUSED_RESULT; +/** + * @brief Allocates a memory area of the specified size from the heap. + * + * This function is almost identical to malloc(). The only exception is that + * errno is not set in case of a memory allocation failure. + * + * @param[in] size The memory area size in bytes. + * + * @retval NULL The memory allocation failed or @a size is zero. + * @retval otherwise The begin address of the allocated memory area. + */ +void *rtems_malloc(size_t size) + RTEMS_MALLOCLIKE RTEMS_ALLOC_SIZE(1) RTEMS_WARN_UNUSED_RESULT; + +/** + * @brief Allocates a memory area for the specified count of elements from the + * heap. + * + * The allocated memory area is fully filled with zero bits. + * + * This function is almost identical to calloc(). The only exception is that + * errno is not set in case of a memory allocation failure. + * + * @param[in] nelem The count of elements. + * @param[in] elsize The size of each elements. + * + * @retval NULL The memory allocation failed or @a nelem is zero or @a elsize + * is zero. + * @retval otherwise The begin address of the allocated memory area. + */ +void *rtems_calloc(size_t nelem, size_t elsize) + RTEMS_MALLOCLIKE RTEMS_ALLOC_SIZE_2(1, 2) RTEMS_WARN_UNUSED_RESULT; + /** * @brief Extends the memory available for the heap using the memory area * starting at @a area_begin of size @a area_size bytes. diff --git a/cpukit/libcsupport/src/malloc_deferred.c b/cpukit/libcsupport/src/malloc_deferred.c index f37b852cba..ccb8dc3b8b 100644 --- a/cpukit/libcsupport/src/malloc_deferred.c +++ b/cpukit/libcsupport/src/malloc_deferred.c @@ -23,6 +23,7 @@ #ifdef RTEMS_NEWLIB #include +#include #include "malloc_p.h" @@ -136,4 +137,28 @@ void _Malloc_Deferred_free( void *p ) rtems_chain_append_unprotected( &_Malloc_GC_list, node ); rtems_interrupt_lock_release( &_Malloc_GC_lock, &lock_context ); } + +void *rtems_malloc( size_t size ) +{ + if ( size == 0 ) { + return NULL; + } + + return rtems_heap_allocate_aligned_with_boundary( size, 0, 0 ); +} + +void *rtems_calloc( size_t nelem, size_t elsize ) +{ + size_t length; + void *p; + + length = nelem * elsize; + p = rtems_malloc( length ); + RTEMS_OBFUSCATE_VARIABLE( p ); + if ( RTEMS_PREDICT_FALSE( p == NULL ) ) { + return p; + } + + return memset( p, 0, length ); +} #endif diff --git a/testsuites/libtests/malloctest/init.c b/testsuites/libtests/malloctest/init.c index be6f2c4755..1d91385683 100644 --- a/testsuites/libtests/malloctest/init.c +++ b/testsuites/libtests/malloctest/init.c @@ -1148,6 +1148,55 @@ static void test_rtems_heap_allocate_aligned_with_boundary(void) rtems_test_assert( p == NULL ); } +static void test_rtems_malloc(void) +{ + void *p; + + p = rtems_malloc(0); + rtems_test_assert(p == NULL); + + errno = 0; + p = rtems_malloc(SIZE_MAX / 2); + rtems_test_assert(p == NULL); + rtems_test_assert(errno == 0); + + p = rtems_malloc(1); + rtems_test_assert(p != NULL); + + free(p); +} + +static void test_rtems_calloc(void) +{ + void *p; + int *i; + + p = rtems_calloc(0, 0); + rtems_test_assert(p == NULL); + + p = rtems_calloc(0, 1); + rtems_test_assert(p == NULL); + + p = rtems_calloc(1, 0); + rtems_test_assert(p == NULL); + + errno = 0; + p = rtems_calloc(1, SIZE_MAX / 2); + rtems_test_assert(p == NULL); + rtems_test_assert(errno == 0); + + errno = 0; + p = rtems_calloc(SIZE_MAX / 2, 1); + rtems_test_assert(p == NULL); + rtems_test_assert(errno == 0); + + i = rtems_calloc(1, sizeof(*i)); + rtems_test_assert(i != NULL); + rtems_test_assert(*i == 0); + + free(i); +} + static void test_heap_size_with_overhead(void) { uintptr_t s; @@ -1296,6 +1345,8 @@ rtems_task Init( test_heap_size_with_overhead(); test_protected_heap_info(); test_rtems_heap_allocate_aligned_with_boundary(); + test_rtems_malloc(); + test_rtems_calloc(); test_greedy_allocate(); test_posix_memalign(); -- cgit v1.2.3