summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/test-api-fill.c332
-rw-r--r--test/test-api.c35
-rw-r--r--test/testhelper.h49
3 files changed, 384 insertions, 32 deletions
diff --git a/test/test-api-fill.c b/test/test-api-fill.c
new file mode 100644
index 0000000..0e5a65d
--- /dev/null
+++ b/test/test-api-fill.c
@@ -0,0 +1,332 @@
+/* ----------------------------------------------------------------------------
+Copyright (c) 2018-2020, Microsoft Research, Daan Leijen
+This is free software; you can redistribute it and/or modify it under the
+terms of the MIT license. A copy of the license can be found in the file
+"LICENSE" at the root of this distribution.
+-----------------------------------------------------------------------------*/
+#include "mimalloc.h"
+#include "mimalloc-types.h"
+
+#include "testhelper.h"
+
+// ---------------------------------------------------------------------------
+// Helper functions
+// ---------------------------------------------------------------------------
+bool check_zero_init(uint8_t* p, size_t size);
+#if MI_DEBUG >= 2
+bool check_debug_fill_uninit(uint8_t* p, size_t size);
+bool check_debug_fill_freed(uint8_t* p, size_t size);
+#endif
+
+// ---------------------------------------------------------------------------
+// Main testing
+// ---------------------------------------------------------------------------
+int main(void) {
+ mi_option_disable(mi_option_verbose);
+
+ // ---------------------------------------------------
+ // Zeroing allocation
+ // ---------------------------------------------------
+ CHECK_BODY("zeroinit-zalloc-small", {
+ size_t zalloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_zalloc(zalloc_size);
+ result = check_zero_init(p, zalloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("zeroinit-zalloc-large", {
+ size_t zalloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_zalloc(zalloc_size);
+ result = check_zero_init(p, zalloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("zeroinit-zalloc_small", {
+ size_t zalloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_zalloc_small(zalloc_size);
+ result = check_zero_init(p, zalloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("zeroinit-calloc-small", {
+ size_t calloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_calloc(calloc_size, 1);
+ result = check_zero_init(p, calloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("zeroinit-calloc-large", {
+ size_t calloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_calloc(calloc_size, 1);
+ result = check_zero_init(p, calloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("zeroinit-rezalloc-small", {
+ size_t zalloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_zalloc(zalloc_size);
+ result = check_zero_init(p, zalloc_size);
+ zalloc_size *= 3;
+ p = (uint8_t*)mi_rezalloc(p, zalloc_size);
+ result &= check_zero_init(p, zalloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("zeroinit-rezalloc-large", {
+ size_t zalloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_zalloc(zalloc_size);
+ result = check_zero_init(p, zalloc_size);
+ zalloc_size *= 3;
+ p = (uint8_t*)mi_rezalloc(p, zalloc_size);
+ result &= check_zero_init(p, zalloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("zeroinit-recalloc-small", {
+ size_t calloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_calloc(calloc_size, 1);
+ result = check_zero_init(p, calloc_size);
+ calloc_size *= 3;
+ p = (uint8_t*)mi_recalloc(p, calloc_size, 1);
+ result &= check_zero_init(p, calloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("zeroinit-recalloc-large", {
+ size_t calloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_calloc(calloc_size, 1);
+ result = check_zero_init(p, calloc_size);
+ calloc_size *= 3;
+ p = (uint8_t*)mi_recalloc(p, calloc_size, 1);
+ result &= check_zero_init(p, calloc_size);
+ mi_free(p);
+ });
+
+ // ---------------------------------------------------
+ // Zeroing in aligned API
+ // ---------------------------------------------------
+ CHECK_BODY("zeroinit-zalloc_aligned-small", {
+ size_t zalloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_zalloc_aligned(zalloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result = check_zero_init(p, zalloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("zeroinit-zalloc_aligned-large", {
+ size_t zalloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_zalloc_aligned(zalloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result = check_zero_init(p, zalloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("zeroinit-calloc_aligned-small", {
+ size_t calloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_calloc_aligned(calloc_size, 1, MI_MAX_ALIGN_SIZE * 2);
+ result = check_zero_init(p, calloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("zeroinit-calloc_aligned-large", {
+ size_t calloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_calloc_aligned(calloc_size, 1, MI_MAX_ALIGN_SIZE * 2);
+ result = check_zero_init(p, calloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("zeroinit-rezalloc_aligned-small", {
+ size_t zalloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_zalloc_aligned(zalloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result = check_zero_init(p, zalloc_size);
+ zalloc_size *= 3;
+ p = (uint8_t*)mi_rezalloc_aligned(p, zalloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result &= check_zero_init(p, zalloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("zeroinit-rezalloc_aligned-large", {
+ size_t zalloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_zalloc_aligned(zalloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result = check_zero_init(p, zalloc_size);
+ zalloc_size *= 3;
+ p = (uint8_t*)mi_rezalloc_aligned(p, zalloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result &= check_zero_init(p, zalloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("zeroinit-recalloc_aligned-small", {
+ size_t calloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_calloc_aligned(calloc_size, 1, MI_MAX_ALIGN_SIZE * 2);
+ result = check_zero_init(p, calloc_size);
+ calloc_size *= 3;
+ p = (uint8_t*)mi_recalloc_aligned(p, calloc_size, 1, MI_MAX_ALIGN_SIZE * 2);
+ result &= check_zero_init(p, calloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("zeroinit-recalloc_aligned-large", {
+ size_t calloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_calloc_aligned(calloc_size, 1, MI_MAX_ALIGN_SIZE * 2);
+ result = check_zero_init(p, calloc_size);
+ calloc_size *= 3;
+ p = (uint8_t*)mi_recalloc_aligned(p, calloc_size, 1, MI_MAX_ALIGN_SIZE * 2);
+ result &= check_zero_init(p, calloc_size);
+ mi_free(p);
+ });
+
+#if MI_DEBUG >= 2
+ // ---------------------------------------------------
+ // Debug filling
+ // ---------------------------------------------------
+ CHECK_BODY("uninit-malloc-small", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_malloc(malloc_size);
+ result = check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("uninit-malloc-large", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_malloc(malloc_size);
+ result = check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("uninit-malloc_small", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_malloc_small(malloc_size);
+ result = check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("uninit-realloc-small", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_malloc(malloc_size);
+ result = check_debug_fill_uninit(p, malloc_size);
+ malloc_size *= 3;
+ p = (uint8_t*)mi_realloc(p, malloc_size);
+ result &= check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("uninit-realloc-large", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_malloc(malloc_size);
+ result = check_debug_fill_uninit(p, malloc_size);
+ malloc_size *= 3;
+ p = (uint8_t*)mi_realloc(p, malloc_size);
+ result &= check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("uninit-mallocn-small", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_mallocn(malloc_size, 1);
+ result = check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("uninit-mallocn-large", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_mallocn(malloc_size, 1);
+ result = check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("uninit-reallocn-small", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_mallocn(malloc_size, 1);
+ result = check_debug_fill_uninit(p, malloc_size);
+ malloc_size *= 3;
+ p = (uint8_t*)mi_reallocn(p, malloc_size, 1);
+ result &= check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("uninit-reallocn-large", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_mallocn(malloc_size, 1);
+ result = check_debug_fill_uninit(p, malloc_size);
+ malloc_size *= 3;
+ p = (uint8_t*)mi_reallocn(p, malloc_size, 1);
+ result &= check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("uninit-malloc_aligned-small", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_malloc_aligned(malloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result = check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("uninit-malloc_aligned-large", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_malloc_aligned(malloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result = check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+
+ CHECK_BODY("uninit-realloc_aligned-small", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_malloc_aligned(malloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result = check_debug_fill_uninit(p, malloc_size);
+ malloc_size *= 3;
+ p = (uint8_t*)mi_realloc_aligned(p, malloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result &= check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+ CHECK_BODY("uninit-realloc_aligned-large", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_malloc_aligned(malloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result = check_debug_fill_uninit(p, malloc_size);
+ malloc_size *= 3;
+ p = (uint8_t*)mi_realloc_aligned(p, malloc_size, MI_MAX_ALIGN_SIZE * 2);
+ result &= check_debug_fill_uninit(p, malloc_size);
+ mi_free(p);
+ });
+
+
+ CHECK_BODY("fill-freed-small", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX / 2;
+ uint8_t* p = (uint8_t*)mi_malloc(malloc_size);
+ mi_free(p);
+ // First sizeof(void*) bytes will contain housekeeping data, skip these
+ result = check_debug_fill_freed(p + sizeof(void*), malloc_size - sizeof(void*));
+ });
+ CHECK_BODY("fill-freed-large", {
+ size_t malloc_size = MI_SMALL_SIZE_MAX * 2;
+ uint8_t* p = (uint8_t*)mi_malloc(malloc_size);
+ mi_free(p);
+ // First sizeof(void*) bytes will contain housekeeping data, skip these
+ result = check_debug_fill_freed(p + sizeof(void*), malloc_size - sizeof(void*));
+ });
+#endif
+
+ // ---------------------------------------------------
+ // Done
+ // ---------------------------------------------------[]
+ return print_test_summary();
+}
+
+// ---------------------------------------------------------------------------
+// Helper functions
+// ---------------------------------------------------------------------------
+bool check_zero_init(uint8_t* p, size_t size) {
+ if(!p)
+ return false;
+ bool result = true;
+ for (size_t i = 0; i < size; ++i) {
+ result &= p[i] == 0;
+ }
+ return result;
+}
+
+#if MI_DEBUG >= 2
+bool check_debug_fill_uninit(uint8_t* p, size_t size) {
+ if(!p)
+ return false;
+
+ bool result = true;
+ for (size_t i = 0; i < size; ++i) {
+ result &= p[i] == MI_DEBUG_UNINIT;
+ }
+ return result;
+}
+
+bool check_debug_fill_freed(uint8_t* p, size_t size) {
+ if(!p)
+ return false;
+
+ bool result = true;
+ for (size_t i = 0; i < size; ++i) {
+ result &= p[i] == MI_DEBUG_FREED;
+ }
+ return result;
+}
+#endif
diff --git a/test/test-api.c b/test/test-api.c
index f057799..7ce6f11 100644
--- a/test/test-api.c
+++ b/test/test-api.c
@@ -23,7 +23,6 @@ we therefore test the API over various inputs. Please add more tests :-)
[1] https://github.com/daanx/mimalloc-bench
*/
-#include <stdio.h>
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
@@ -35,34 +34,9 @@ we therefore test the API over various inputs. Please add more tests :-)
#include "mimalloc.h"
// #include "mimalloc-internal.h"
+#include "mimalloc-types.h" // for MI_DEBUG
-// ---------------------------------------------------------------------------
-// Test macros: CHECK(name,predicate) and CHECK_BODY(name,body)
-// ---------------------------------------------------------------------------
-static int ok = 0;
-static int failed = 0;
-
-#define CHECK_BODY(name,body) \
- do { \
- fprintf(stderr,"test: %s... ", name ); \
- bool result = true; \
- do { body } while(false); \
- if (!(result)) { \
- failed++; \
- fprintf(stderr, \
- "\n FAILED: %s:%d:\n %s\n", \
- __FILE__, \
- __LINE__, \
- #body); \
- /* exit(1); */ \
- } \
- else { \
- ok++; \
- fprintf(stderr,"ok.\n"); \
- } \
- } while (false)
-
-#define CHECK(name,expr) CHECK_BODY(name,{ result = (expr); })
+#include "testhelper.h"
// ---------------------------------------------------------------------------
// Test functions
@@ -219,10 +193,7 @@ int main(void) {
// ---------------------------------------------------
// Done
// ---------------------------------------------------[]
- fprintf(stderr,"\n\n---------------------------------------------\n"
- "succeeded: %i\n"
- "failed : %i\n\n", ok, failed);
- return failed;
+ return print_test_summary();
}
// ---------------------------------------------------
diff --git a/test/testhelper.h b/test/testhelper.h
new file mode 100644
index 0000000..46d63a0
--- /dev/null
+++ b/test/testhelper.h
@@ -0,0 +1,49 @@
+/* ----------------------------------------------------------------------------
+Copyright (c) 2018-2020, Microsoft Research, Daan Leijen
+This is free software; you can redistribute it and/or modify it under the
+terms of the MIT license. A copy of the license can be found in the file
+"LICENSE" at the root of this distribution.
+-----------------------------------------------------------------------------*/
+#ifndef TESTHELPER_H_
+#define TESTHELPER_H_
+
+#include <stdio.h>
+
+// ---------------------------------------------------------------------------
+// Test macros: CHECK(name,predicate) and CHECK_BODY(name,body)
+// ---------------------------------------------------------------------------
+static int ok = 0;
+static int failed = 0;
+
+#define CHECK_BODY(name,body) \
+ do { \
+ fprintf(stderr,"test: %s... ", name ); \
+ bool result = true; \
+ do { body } while(false); \
+ if (!(result)) { \
+ failed++; \
+ fprintf(stderr, \
+ "\n FAILED: %s:%d:\n %s\n", \
+ __FILE__, \
+ __LINE__, \
+ #body); \
+ /* exit(1); */ \
+ } \
+ else { \
+ ok++; \
+ fprintf(stderr,"ok.\n"); \
+ } \
+ } while (false)
+
+#define CHECK(name,expr) CHECK_BODY(name,{ result = (expr); })
+
+// Print summary of test. Return value can be directly use as a return value for main().
+static inline int print_test_summary(void)
+{
+ fprintf(stderr,"\n\n---------------------------------------------\n"
+ "succeeded: %i\n"
+ "failed : %i\n\n", ok, failed);
+ return failed;
+}
+
+#endif // TESTHELPER_H_