Merge branch 'dev' into dev-slice

This commit is contained in:
Daan Leijen 2022-04-19 11:07:41 -07:00
commit 5c64f51503
13 changed files with 1457 additions and 170 deletions

View file

@ -27,39 +27,39 @@ int main(void) {
// ---------------------------------------------------
// Zeroing allocation
// ---------------------------------------------------
CHECK_BODY("zeroinit-zalloc-small", {
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", {
};
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", {
};
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", {
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", {
};
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", {
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);
@ -67,8 +67,8 @@ int main(void) {
p = (uint8_t*)mi_rezalloc(p, zalloc_size);
result &= check_zero_init(p, zalloc_size);
mi_free(p);
});
CHECK_BODY("zeroinit-rezalloc-large", {
};
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);
@ -76,9 +76,9 @@ int main(void) {
p = (uint8_t*)mi_rezalloc(p, zalloc_size);
result &= check_zero_init(p, zalloc_size);
mi_free(p);
});
};
CHECK_BODY("zeroinit-recalloc-small", {
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);
@ -86,8 +86,8 @@ int main(void) {
p = (uint8_t*)mi_recalloc(p, calloc_size, 1);
result &= check_zero_init(p, calloc_size);
mi_free(p);
});
CHECK_BODY("zeroinit-recalloc-large", {
};
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);
@ -95,38 +95,38 @@ int main(void) {
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", {
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", {
};
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", {
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", {
};
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", {
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);
@ -134,8 +134,8 @@ int main(void) {
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", {
};
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);
@ -143,9 +143,9 @@ int main(void) {
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", {
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);
@ -153,8 +153,8 @@ int main(void) {
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", {
};
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);
@ -162,33 +162,33 @@ int main(void) {
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", {
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", {
};
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", {
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", {
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);
@ -196,8 +196,8 @@ int main(void) {
p = (uint8_t*)mi_realloc(p, malloc_size);
result &= check_debug_fill_uninit(p, malloc_size);
mi_free(p);
});
CHECK_BODY("uninit-realloc-large", {
};
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);
@ -205,22 +205,22 @@ int main(void) {
p = (uint8_t*)mi_realloc(p, malloc_size);
result &= check_debug_fill_uninit(p, malloc_size);
mi_free(p);
});
};
CHECK_BODY("uninit-mallocn-small", {
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", {
};
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", {
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);
@ -228,8 +228,8 @@ int main(void) {
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", {
};
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);
@ -237,22 +237,22 @@ int main(void) {
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", {
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", {
};
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", {
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);
@ -260,8 +260,8 @@ int main(void) {
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", {
};
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);
@ -269,23 +269,23 @@ int main(void) {
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", {
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", {
};
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
// ---------------------------------------------------

View file

@ -56,75 +56,77 @@ int main(void) {
// Malloc
// ---------------------------------------------------
CHECK_BODY("malloc-zero",{
void* p = mi_malloc(0); mi_free(p);
});
CHECK_BODY("malloc-nomem1",{
CHECK_BODY("malloc-zero") {
void* p = mi_malloc(0);
result = (p != NULL);
mi_free(p);
};
CHECK_BODY("malloc-nomem1") {
result = (mi_malloc((size_t)PTRDIFF_MAX + (size_t)1) == NULL);
});
CHECK_BODY("malloc-null",{
};
CHECK_BODY("malloc-null") {
mi_free(NULL);
});
CHECK_BODY("calloc-overflow",{
};
CHECK_BODY("calloc-overflow") {
// use (size_t)&mi_calloc to get some number without triggering compiler warnings
result = (mi_calloc((size_t)&mi_calloc,SIZE_MAX/1000) == NULL);
});
CHECK_BODY("calloc0",{
};
CHECK_BODY("calloc0") {
result = (mi_usable_size(mi_calloc(0,1000)) <= 16);
});
CHECK_BODY("malloc-large",{ // see PR #544.
};
CHECK_BODY("malloc-large") { // see PR #544.
void* p = mi_malloc(67108872);
mi_free(p);
});
};
// ---------------------------------------------------
// Extended
// ---------------------------------------------------
CHECK_BODY("posix_memalign1", {
CHECK_BODY("posix_memalign1") {
void* p = &p;
int err = mi_posix_memalign(&p, sizeof(void*), 32);
result = ((err==0 && (uintptr_t)p % sizeof(void*) == 0) || p==&p);
mi_free(p);
});
CHECK_BODY("posix_memalign_no_align", {
};
CHECK_BODY("posix_memalign_no_align") {
void* p = &p;
int err = mi_posix_memalign(&p, 3, 32);
result = (err==EINVAL && p==&p);
});
CHECK_BODY("posix_memalign_zero", {
};
CHECK_BODY("posix_memalign_zero") {
void* p = &p;
int err = mi_posix_memalign(&p, sizeof(void*), 0);
mi_free(p);
result = (err==0);
});
CHECK_BODY("posix_memalign_nopow2", {
};
CHECK_BODY("posix_memalign_nopow2") {
void* p = &p;
int err = mi_posix_memalign(&p, 3*sizeof(void*), 32);
result = (err==EINVAL && p==&p);
});
CHECK_BODY("posix_memalign_nomem", {
};
CHECK_BODY("posix_memalign_nomem") {
void* p = &p;
int err = mi_posix_memalign(&p, sizeof(void*), SIZE_MAX);
result = (err==ENOMEM && p==&p);
});
};
// ---------------------------------------------------
// Aligned API
// ---------------------------------------------------
CHECK_BODY("malloc-aligned1", {
CHECK_BODY("malloc-aligned1") {
void* p = mi_malloc_aligned(32,32); result = (p != NULL && (uintptr_t)(p) % 32 == 0); mi_free(p);
});
CHECK_BODY("malloc-aligned2", {
};
CHECK_BODY("malloc-aligned2") {
void* p = mi_malloc_aligned(48,32); result = (p != NULL && (uintptr_t)(p) % 32 == 0); mi_free(p);
});
CHECK_BODY("malloc-aligned3", {
};
CHECK_BODY("malloc-aligned3") {
void* p1 = mi_malloc_aligned(48,32); bool result1 = (p1 != NULL && (uintptr_t)(p1) % 32 == 0);
void* p2 = mi_malloc_aligned(48,32); bool result2 = (p2 != NULL && (uintptr_t)(p2) % 32 == 0);
mi_free(p2);
mi_free(p1);
result = (result1&&result2);
});
CHECK_BODY("malloc-aligned4", {
};
CHECK_BODY("malloc-aligned4") {
void* p;
bool ok = true;
for (int i = 0; i < 8 && ok; i++) {
@ -132,11 +134,11 @@ int main(void) {
ok = (p != NULL && (uintptr_t)(p) % 16 == 0); mi_free(p);
}
result = ok;
});
CHECK_BODY("malloc-aligned5", {
};
CHECK_BODY("malloc-aligned5") {
void* p = mi_malloc_aligned(4097,4096); size_t usable = mi_usable_size(p); result = usable >= 4097 && usable < 10000; mi_free(p);
});
CHECK_BODY("malloc-aligned6", {
};
CHECK_BODY("malloc-aligned6") {
bool ok = true;
for (size_t align = 1; align <= MI_ALIGNMENT_MAX && ok; align *= 2) {
void* ps[8];
@ -151,20 +153,20 @@ int main(void) {
}
}
result = ok;
});
CHECK_BODY("malloc-aligned7", {
};
CHECK_BODY("malloc-aligned7") {
void* p = mi_malloc_aligned(1024,MI_ALIGNMENT_MAX); mi_free(p);
});
CHECK_BODY("malloc-aligned8", {
};
CHECK_BODY("malloc-aligned8") {
void* p = mi_malloc_aligned(1024,2*MI_ALIGNMENT_MAX); mi_free(p);
});
CHECK_BODY("malloc-aligned-at1", {
};
CHECK_BODY("malloc-aligned-at1") {
void* p = mi_malloc_aligned_at(48,32,0); result = (p != NULL && ((uintptr_t)(p) + 0) % 32 == 0); mi_free(p);
});
CHECK_BODY("malloc-aligned-at2", {
};
CHECK_BODY("malloc-aligned-at2") {
void* p = mi_malloc_aligned_at(50,32,8); result = (p != NULL && ((uintptr_t)(p) + 8) % 32 == 0); mi_free(p);
});
CHECK_BODY("memalign1", {
};
CHECK_BODY("memalign1") {
void* p;
bool ok = true;
for (int i = 0; i < 8 && ok; i++) {
@ -172,8 +174,36 @@ int main(void) {
ok = (p != NULL && (uintptr_t)(p) % 16 == 0); mi_free(p);
}
result = ok;
});
};
// ---------------------------------------------------
// Reallocation
// ---------------------------------------------------
CHECK_BODY("realloc-null") {
void* p = mi_realloc(NULL,4);
result = (p != NULL);
mi_free(p);
};
CHECK_BODY("realloc-null-sizezero") {
void* p = mi_realloc(NULL,0); // <https://en.cppreference.com/w/c/memory/realloc> "If ptr is NULL, the behavior is the same as calling malloc(new_size)."
result = (p != NULL);
mi_free(p);
};
CHECK_BODY("realloc-sizezero") {
void* p = mi_malloc(4);
void* q = mi_realloc(p, 0);
result = (q != NULL);
mi_free(q);
};
CHECK_BODY("reallocarray-null-sizezero") {
void* p = mi_reallocarray(NULL,0,16); // issue #574
result = (p != NULL && errno == 0);
mi_free(p);
};
// ---------------------------------------------------
// Heaps
// ---------------------------------------------------
@ -185,11 +215,11 @@ int main(void) {
// ---------------------------------------------------
// various
// ---------------------------------------------------
CHECK_BODY("realpath", {
CHECK_BODY("realpath") {
char* s = mi_realpath( ".", NULL );
// printf("realpath: %s\n",s);
mi_free(s);
});
};
CHECK("stl_allocator1", test_stl_allocator1());
CHECK("stl_allocator2", test_stl_allocator2());

View file

@ -7,7 +7,9 @@ terms of the MIT license. A copy of the license can be found in the file
#ifndef TESTHELPER_H_
#define TESTHELPER_H_
#include <stdbool.h>
#include <stdio.h>
#include <errno.h>
// ---------------------------------------------------------------------------
// Test macros: CHECK(name,predicate) and CHECK_BODY(name,body)
@ -15,27 +17,25 @@ terms of the MIT license. A copy of the license can be found in the file
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)
static bool check_result(bool result, const char* testname, const char* fname, long lineno) {
if (!(result)) {
failed++;
fprintf(stderr,"\n FAILED: %s: %s:%ld\n", testname, fname, lineno);
/* exit(1); */
}
else {
ok++;
fprintf(stderr, "ok.\n");
}
return true;
}
#define CHECK(name,expr) CHECK_BODY(name,{ result = (expr); })
#define CHECK_BODY(name) \
fprintf(stderr,"test: %s... ", name ); \
errno = 0; \
for(bool done = false, result = true; !done; done = check_result(result,name,__FILE__,__LINE__))
#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)