[PATCH 2/3] Add rtems_malloc() and rtems_calloc()

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Nov 9 12:10:39 UTC 2018


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 <stdlib.h>
+#include <string.h>
 
 #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();
-- 
2.16.4




More information about the devel mailing list