mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-07-07 11:58:41 +03:00
merge from dev
This commit is contained in:
commit
8b8e689b91
41 changed files with 2107 additions and 1326 deletions
|
@ -100,7 +100,7 @@ static void various_tests() {
|
|||
auto tbuf = new unsigned char[sizeof(Test)];
|
||||
t = new (tbuf) Test(42);
|
||||
t->~Test();
|
||||
delete tbuf;
|
||||
delete[] tbuf;
|
||||
}
|
||||
|
||||
class Static {
|
||||
|
|
106
test/test-api.c
106
test/test-api.c
|
@ -35,7 +35,7 @@ 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 and MI_ALIGNMENT_MAX
|
||||
#include "mimalloc/types.h" // for MI_DEBUG and MI_BLOCK_ALIGNMENT_MAX
|
||||
|
||||
#include "testhelper.h"
|
||||
|
||||
|
@ -47,6 +47,11 @@ bool test_heap2(void);
|
|||
bool test_stl_allocator1(void);
|
||||
bool test_stl_allocator2(void);
|
||||
|
||||
bool test_stl_heap_allocator1(void);
|
||||
bool test_stl_heap_allocator2(void);
|
||||
bool test_stl_heap_allocator3(void);
|
||||
bool test_stl_heap_allocator4(void);
|
||||
|
||||
bool mem_is_zero(uint8_t* p, size_t size) {
|
||||
if (p==NULL) return false;
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
|
@ -156,7 +161,7 @@ int main(void) {
|
|||
};
|
||||
CHECK_BODY("malloc-aligned6") {
|
||||
bool ok = true;
|
||||
for (size_t align = 1; align <= MI_ALIGN_HUGE && ok; align *= 2) {
|
||||
for (size_t align = 1; align <= MI_BLOCK_ALIGNMENT_MAX && ok; align *= 2) {
|
||||
void* ps[8];
|
||||
for (int i = 0; i < 8 && ok; i++) {
|
||||
ps[i] = mi_malloc_aligned(align*13 // size
|
||||
|
@ -172,16 +177,16 @@ int main(void) {
|
|||
result = ok;
|
||||
};
|
||||
CHECK_BODY("malloc-aligned7") {
|
||||
void* p = mi_malloc_aligned(1024,MI_ALIGN_HUGE);
|
||||
void* p = mi_malloc_aligned(1024,MI_BLOCK_ALIGNMENT_MAX);
|
||||
mi_free(p);
|
||||
result = ((uintptr_t)p % MI_ALIGN_HUGE) == 0;
|
||||
result = ((uintptr_t)p % MI_BLOCK_ALIGNMENT_MAX) == 0;
|
||||
};
|
||||
CHECK_BODY("malloc-aligned8") {
|
||||
bool ok = true;
|
||||
for (int i = 0; i < 5 && ok; i++) {
|
||||
int n = (1 << i);
|
||||
void* p = mi_malloc_aligned(1024, n * MI_ALIGN_HUGE);
|
||||
ok = ((uintptr_t)p % (n*MI_ALIGN_HUGE)) == 0;
|
||||
void* p = mi_malloc_aligned(1024, n * MI_BLOCK_ALIGNMENT_MAX);
|
||||
ok = ((uintptr_t)p % (n*MI_BLOCK_ALIGNMENT_MAX)) == 0;
|
||||
mi_free(p);
|
||||
}
|
||||
result = ok;
|
||||
|
@ -189,7 +194,7 @@ int main(void) {
|
|||
CHECK_BODY("malloc-aligned9") {
|
||||
bool ok = true;
|
||||
void* p[8];
|
||||
size_t sizes[8] = { 8, 512, 1024 * 1024, MI_ALIGN_HUGE, MI_ALIGN_HUGE + 1, 2 * MI_ALIGN_HUGE, 8 * MI_ALIGN_HUGE, 0 };
|
||||
size_t sizes[8] = { 8, 512, 1024 * 1024, MI_BLOCK_ALIGNMENT_MAX, MI_BLOCK_ALIGNMENT_MAX + 1, 2 * MI_BLOCK_ALIGNMENT_MAX, 8 * MI_BLOCK_ALIGNMENT_MAX, 0 };
|
||||
for (int i = 0; i < 28 && ok; i++) {
|
||||
int align = (1 << i);
|
||||
for (int j = 0; j < 8 && ok; j++) {
|
||||
|
@ -227,6 +232,28 @@ int main(void) {
|
|||
result = (((uintptr_t)p % 0x100) == 0); // #602
|
||||
mi_free(p);
|
||||
}
|
||||
CHECK_BODY("mimalloc-aligned13") {
|
||||
bool ok = true;
|
||||
for( size_t size = 1; size <= (MI_SMALL_SIZE_MAX * 2) && ok; size++ ) {
|
||||
for(size_t align = 1; align <= size && ok; align *= 2 ) {
|
||||
void* p[10];
|
||||
for(int i = 0; i < 10 && ok; i++) {
|
||||
p[i] = mi_malloc_aligned(size,align);;
|
||||
ok = (p[i] != NULL && ((uintptr_t)(p[i]) % align) == 0);
|
||||
}
|
||||
for(int i = 0; i < 10 && ok; i++) {
|
||||
mi_free(p[i]);
|
||||
}
|
||||
/*
|
||||
if (ok && align <= size && ((size + MI_PADDING_SIZE) & (align-1)) == 0) {
|
||||
size_t bsize = mi_good_size(size);
|
||||
ok = (align <= bsize && (bsize & (align-1)) == 0);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
result = ok;
|
||||
}
|
||||
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);
|
||||
};
|
||||
|
@ -306,15 +333,22 @@ int main(void) {
|
|||
// ---------------------------------------------------
|
||||
// various
|
||||
// ---------------------------------------------------
|
||||
#if !defined(MI_TRACK_ASAN) // realpath may leak with ASAN enabled (as the ASAN allocator intercepts it)
|
||||
CHECK_BODY("realpath") {
|
||||
char* s = mi_realpath( ".", NULL );
|
||||
// printf("realpath: %s\n",s);
|
||||
mi_free(s);
|
||||
};
|
||||
#endif
|
||||
|
||||
CHECK("stl_allocator1", test_stl_allocator1());
|
||||
CHECK("stl_allocator2", test_stl_allocator2());
|
||||
|
||||
CHECK("stl_heap_allocator1", test_stl_heap_allocator1());
|
||||
CHECK("stl_heap_allocator2", test_stl_heap_allocator2());
|
||||
CHECK("stl_heap_allocator3", test_stl_heap_allocator3());
|
||||
CHECK("stl_heap_allocator4", test_stl_heap_allocator4());
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Done
|
||||
// ---------------------------------------------------[]
|
||||
|
@ -368,3 +402,61 @@ bool test_stl_allocator2(void) {
|
|||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool test_stl_heap_allocator1(void) {
|
||||
#ifdef __cplusplus
|
||||
std::vector<some_struct, mi_heap_stl_allocator<some_struct> > vec;
|
||||
vec.push_back(some_struct());
|
||||
vec.pop_back();
|
||||
return vec.size() == 0;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool test_stl_heap_allocator2(void) {
|
||||
#ifdef __cplusplus
|
||||
std::vector<some_struct, mi_heap_destroy_stl_allocator<some_struct> > vec;
|
||||
vec.push_back(some_struct());
|
||||
vec.pop_back();
|
||||
return vec.size() == 0;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool test_stl_heap_allocator3(void) {
|
||||
#ifdef __cplusplus
|
||||
mi_heap_t* heap = mi_heap_new();
|
||||
bool good = false;
|
||||
{
|
||||
mi_heap_stl_allocator<some_struct> myAlloc(heap);
|
||||
std::vector<some_struct, mi_heap_stl_allocator<some_struct> > vec(myAlloc);
|
||||
vec.push_back(some_struct());
|
||||
vec.pop_back();
|
||||
good = vec.size() == 0;
|
||||
}
|
||||
mi_heap_delete(heap);
|
||||
return good;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool test_stl_heap_allocator4(void) {
|
||||
#ifdef __cplusplus
|
||||
mi_heap_t* heap = mi_heap_new();
|
||||
bool good = false;
|
||||
{
|
||||
mi_heap_destroy_stl_allocator<some_struct> myAlloc(heap);
|
||||
std::vector<some_struct, mi_heap_destroy_stl_allocator<some_struct> > vec(myAlloc);
|
||||
vec.push_back(some_struct());
|
||||
vec.pop_back();
|
||||
good = vec.size() == 0;
|
||||
}
|
||||
mi_heap_destroy(heap);
|
||||
return good;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -37,11 +37,12 @@ static int ITER = 50; // N full iterations destructing and re-creating a
|
|||
// static int THREADS = 8; // more repeatable if THREADS <= #processors
|
||||
// static int SCALE = 100; // scaling factor
|
||||
|
||||
#define STRESS // undefine for leak test
|
||||
#define STRESS // undefine for leak test
|
||||
|
||||
static bool allow_large_objects = true; // allow very large objects? (set to `true` if SCALE>100)
|
||||
static size_t use_one_size = 0; // use single object size of `N * sizeof(uintptr_t)`?
|
||||
|
||||
static bool main_participates = false; // main thread participates as a worker too
|
||||
|
||||
// #define USE_STD_MALLOC
|
||||
#ifdef USE_STD_MALLOC
|
||||
|
@ -196,10 +197,13 @@ static void test_stress(void) {
|
|||
free_items(p);
|
||||
}
|
||||
}
|
||||
// mi_collect(false);
|
||||
#if !defined(NDEBUG) || defined(MI_TSAN)
|
||||
#ifndef NDEBUG
|
||||
//mi_collect(false);
|
||||
//mi_debug_show_arenas();
|
||||
#endif
|
||||
#if !defined(NDEBUG) || defined(MI_TSAN)
|
||||
if ((n + 1) % 10 == 0) { printf("- iterations left: %3d\n", ITER - (n + 1)); }
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,7 +271,8 @@ int main(int argc, char** argv) {
|
|||
|
||||
#ifndef USE_STD_MALLOC
|
||||
#ifndef NDEBUG
|
||||
mi_collect(true);
|
||||
// mi_collect(true);
|
||||
mi_debug_show_arenas(true,true,true);
|
||||
#endif
|
||||
mi_stats_print(NULL);
|
||||
#endif
|
||||
|
@ -291,13 +296,15 @@ static void run_os_threads(size_t nthreads, void (*fun)(intptr_t)) {
|
|||
thread_entry_fun = fun;
|
||||
DWORD* tids = (DWORD*)custom_calloc(nthreads,sizeof(DWORD));
|
||||
HANDLE* thandles = (HANDLE*)custom_calloc(nthreads,sizeof(HANDLE));
|
||||
for (uintptr_t i = 0; i < nthreads; i++) {
|
||||
const size_t start = (main_participates ? 1 : 0);
|
||||
for (size_t i = start; i < nthreads; i++) {
|
||||
thandles[i] = CreateThread(0, 8*1024, &thread_entry, (void*)(i), 0, &tids[i]);
|
||||
}
|
||||
for (size_t i = 0; i < nthreads; i++) {
|
||||
if (main_participates) fun(0); // run the main thread as well
|
||||
for (size_t i = start; i < nthreads; i++) {
|
||||
WaitForSingleObject(thandles[i], INFINITE);
|
||||
}
|
||||
for (size_t i = 0; i < nthreads; i++) {
|
||||
for (size_t i = start; i < nthreads; i++) {
|
||||
CloseHandle(thandles[i]);
|
||||
}
|
||||
custom_free(tids);
|
||||
|
@ -324,11 +331,13 @@ static void run_os_threads(size_t nthreads, void (*fun)(intptr_t)) {
|
|||
thread_entry_fun = fun;
|
||||
pthread_t* threads = (pthread_t*)custom_calloc(nthreads,sizeof(pthread_t));
|
||||
memset(threads, 0, sizeof(pthread_t) * nthreads);
|
||||
const size_t start = (main_participates ? 1 : 0);
|
||||
//pthread_setconcurrency(nthreads);
|
||||
for (size_t i = 0; i < nthreads; i++) {
|
||||
for (size_t i = start; i < nthreads; i++) {
|
||||
pthread_create(&threads[i], NULL, &thread_entry, (void*)i);
|
||||
}
|
||||
for (size_t i = 0; i < nthreads; i++) {
|
||||
if (main_participates) fun(0); // run the main thread as well
|
||||
for (size_t i = start; i < nthreads; i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
custom_free(threads);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue