From 3b5acd2fec4e10713cb0823859e0087241d81bc3 Mon Sep 17 00:00:00 2001 From: Schrodinger ZHU Yifan Date: Sun, 2 Jan 2022 16:23:39 +0800 Subject: [PATCH 1/3] init mingw support Signed-off-by: Schrodinger ZHU Yifan --- CMakeLists.txt | 3 +- src/override/memcpy.cc | 2 +- src/pal/pal_windows.h | 4 ++- src/test/func/malloc/malloc.cc | 66 ++++++++++++++++------------------ 4 files changed, 36 insertions(+), 39 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b23d067ee..73db7a8db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -227,7 +227,8 @@ if(MSVC) target_compile_definitions(snmalloc INTERFACE -D_HAS_EXCEPTIONS=0) else() # All symbols are always dynamic on haiku and -rdynamic is redundant (and unsupported). - if (NOT CMAKE_SYSTEM_NAME STREQUAL "Haiku") + # MinGW does not recognize rdynamic either. + if (NOT CMAKE_SYSTEM_NAME STREQUAL "Haiku" AND NOT MINGW) # Get better stack traces in CI and debug builds. target_link_options(snmalloc INTERFACE $<${ci_or_debug}:-rdynamic>) endif() diff --git a/src/override/memcpy.cc b/src/override/memcpy.cc index 6c858f422..ad72ebf41 100644 --- a/src/override/memcpy.cc +++ b/src/override/memcpy.cc @@ -15,7 +15,7 @@ using namespace snmalloc; # define snprintf_l(buf, size, loc, msg, ...) \ snprintf(buf, size, msg, __VA_ARGS__) // Windows has it with an underscore prefix -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) || defined(__MINGW32__) # define snprintf_l(buf, size, loc, msg, ...) \ _snprintf_s_l(buf, size, _TRUNCATE, msg, loc, __VA_ARGS__) #endif diff --git a/src/pal/pal_windows.h b/src/pal/pal_windows.h index 1667dce9f..abadcf1d4 100644 --- a/src/pal/pal_windows.h +++ b/src/pal/pal_windows.h @@ -13,7 +13,9 @@ # define NOMINMAX # endif # include -# pragma comment(lib, "bcrypt.lib") +# ifndef __MINGW32__ +# pragma comment(lib, "bcrypt.lib") +# endif # include // VirtualAlloc2 is exposed in RS5 headers. # ifdef NTDDI_WIN10_RS5 diff --git a/src/test/func/malloc/malloc.cc b/src/test/func/malloc/malloc.cc index a672a25a1..dc764f360 100644 --- a/src/test/func/malloc/malloc.cc +++ b/src/test/func/malloc/malloc.cc @@ -1,4 +1,6 @@ -#include +#include +#include +#include #include #define SNMALLOC_NAME_MANGLE(a) our_##a @@ -15,7 +17,7 @@ void check_result(size_t size, size_t align, void* p, int err, bool null) bool failed = false; if (errno != err && err != SUCCESS) { - printf("Expected error: %d but got %d\n", err, errno); + std::cout << "Expected error: " << err << " but got " << errno << std::endl; failed = true; } @@ -23,7 +25,7 @@ void check_result(size_t size, size_t align, void* p, int err, bool null) { if (p != nullptr) { - printf("Expected null, and got non-null return!\n"); + std::cout << "Expected null, and got non-null return!" << std::endl; abort(); } return; @@ -31,7 +33,7 @@ void check_result(size_t size, size_t align, void* p, int err, bool null) if ((p == nullptr) && (size != 0)) { - printf("Unexpected null returned.\n"); + std::cout << "Unexpected null returned." << std::endl; failed = true; } const auto alloc_size = our_malloc_usable_size(p); @@ -46,44 +48,36 @@ void check_result(size_t size, size_t align, void* p, int err, bool null) #endif if (exact_size && (alloc_size != expected_size) && (size != 0)) { - printf( - "Usable size is %zu, but required to be %zu.\n", - alloc_size, - expected_size); + std::cout << "Usable size is " << alloc_size << ", but required to be " << expected_size << "." << std::endl; failed = true; } if ((!exact_size) && (alloc_size < expected_size)) { - printf( - "Usable size is %zu, but required to be at least %zu.\n", - alloc_size, - expected_size); + std::cout << "Usable size is " << alloc_size << ", but required to be at least " << expected_size << "." << std::endl; failed = true; } if ( (static_cast(reinterpret_cast(p) % align) != 0) && (size != 0)) { - printf( - "Address is 0x%zx, but required to be aligned to 0x%zx.\n", - reinterpret_cast(p), - align); + std::ios_base::fmtflags f(std::cout.flags()); + std::cout << std::hex << "Address is " << p << ", but required to be aligned to 0x" << align << "." << std::endl; + std::cout.flags(f); failed = true; } if ( static_cast( reinterpret_cast(p) % natural_alignment(size)) != 0) { - printf( - "Address is 0x%zx, but should have natural alignment to 0x%zx.\n", - reinterpret_cast(p), - natural_alignment(size)); + std::ios_base::fmtflags f(std::cout.flags()); + std::cout << std::hex << "Address is " << p << ", but should have natural alignment to 0x" << natural_alignment(size) << "." << std::endl; + std::cout.flags(f); failed = true; } if (failed) { - printf("check_result failed! %p", p); + std::cout << "check_result failed! " << p << std::endl; abort(); } our_free(p); @@ -91,7 +85,7 @@ void check_result(size_t size, size_t align, void* p, int err, bool null) void test_calloc(size_t nmemb, size_t size, int err, bool null) { - printf("calloc(%zu, %zu) combined size %zu\n", nmemb, size, nmemb * size); + std::cout << "calloc(" << nmemb << ", " << size << ")" << " combined size " << nmemb * size << std::endl; errno = SUCCESS; void* p = our_calloc(nmemb, size); @@ -101,7 +95,7 @@ void test_calloc(size_t nmemb, size_t size, int err, bool null) { if (((uint8_t*)p)[i] != 0) { - printf("non-zero at @%zu\n", i); + std::cout << "non-zero at @" << i << std::endl; abort(); } } @@ -115,7 +109,7 @@ void test_realloc(void* p, size_t size, int err, bool null) if (p != nullptr) old_size = our_malloc_usable_size(p); - printf("realloc(%p(%zu), %zu)\n", p, old_size, size); + std::cout << "realloc(" << p << "(" << old_size << ")" << ", " << size << ")" << std::endl; errno = SUCCESS; auto new_p = our_realloc(p, size); // Realloc failure case, deallocate original block @@ -126,7 +120,7 @@ void test_realloc(void* p, size_t size, int err, bool null) void test_posix_memalign(size_t size, size_t align, int err, bool null) { - printf("posix_memalign(&p, %zu, %zu)\n", align, size); + std::cout << "posix_memalign(&p, " << align << ", " << size << ")" << std::endl; void* p = nullptr; errno = our_posix_memalign(&p, align, size); check_result(size, align, p, err, null); @@ -134,7 +128,7 @@ void test_posix_memalign(size_t size, size_t align, int err, bool null) void test_memalign(size_t size, size_t align, int err, bool null) { - printf("memalign(%zu, %zu)\n", align, size); + std::cout << "memalign(" << align << ", " << size << ")" << std::endl; errno = SUCCESS; void* p = our_memalign(align, size); check_result(size, align, p, err, null); @@ -147,7 +141,7 @@ void test_reallocarray(void* p, size_t nmemb, size_t size, int err, bool null) if (p != nullptr) old_size = our_malloc_usable_size(p); - printf("reallocarray(%p(%zu), %zu)\n", p, old_size, tsize); + std::cout << "reallocarray(" << p << "(" << old_size << ")" << ", " << tsize << ")" << std::endl; errno = SUCCESS; auto new_p = our_reallocarray(p, nmemb, size); if (new_p == nullptr && tsize != 0) @@ -166,11 +160,11 @@ void test_reallocarr( int r = our_reallocarr(&p, nmemb, size); if (r != err) { - printf("reallocarr failed! expected %d got %d\n", err, r); + std::cout << "reallocarr failed! expected " << err << " got " << r << std::endl; abort(); } - printf("reallocarr(%p(%zu), %zu)\n", p, nmemb, size); + std::cout << "reallocarr(" << p << "(" << nmemb << ")" << ", " << size << ")" << std::endl; check_result(nmemb * size, 1, p, err, null); p = our_malloc(size); if (!p) @@ -187,7 +181,7 @@ void test_reallocarr( { if (static_cast(p)[i] != 1) { - printf("data consistency failed! at %zu", i); + std::cout << "data consistency failed! at " << i << std::endl; abort(); } } @@ -206,7 +200,7 @@ int main(int argc, char** argv) for (smallsizeclass_t sc = 0; sc < (MAX_SMALL_SIZECLASS_BITS + 4); sc++) { const size_t size = bits::one_at_bit(sc); - printf("malloc: %zu\n", size); + std::cout << "malloc: " << size << std::endl; errno = SUCCESS; check_result(size, 1, our_malloc(size), SUCCESS, false); errno = SUCCESS; @@ -258,7 +252,7 @@ int main(int argc, char** argv) for (smallsizeclass_t sc2 = 0; sc2 < (MAX_SMALL_SIZECLASS_BITS + 4); sc2++) { const size_t size2 = bits::one_at_bit(sc2); - printf("size1: %zu, size2:%zu\n", size, size2); + std::cout << "size1: " << size << ", size2: " << size2 << std::endl; test_realloc(our_malloc(size), size2, SUCCESS, false); test_realloc(our_malloc(size + 1), size2, SUCCESS, false); } @@ -313,13 +307,13 @@ int main(int argc, char** argv) void* p = our_malloc(size); if (p == nullptr) { - printf("realloc alloc failed with %zu\n", size); + std::cout << "realloc alloc failed with " << size << std::endl; abort(); } int r = our_reallocarr(&p, 1, ((size_t)-1) / 2); if (r != ENOMEM) { - printf("expected failure on allocation\n"); + std::cout << "expected failure on allocation" << std::endl; abort(); } our_free(p); @@ -327,14 +321,14 @@ int main(int argc, char** argv) for (smallsizeclass_t sc2 = 0; sc2 < (MAX_SMALL_SIZECLASS_BITS + 4); sc2++) { const size_t size2 = bits::one_at_bit(sc2); - printf("size1: %zu, size2:%zu\n", size, size2); + std::cout << "size1: " << size << ", size2: " << size2 << std::endl; test_reallocarr(size, 1, size2, SUCCESS, false); } } if (our_malloc_usable_size(nullptr) != 0) { - printf("malloc_usable_size(nullptr) should be zero"); + std::cout << "malloc_usable_size(nullptr) should be zero" << std::endl; abort(); } From 5830dbd93e39af345e596375ad542d8e4b651e4e Mon Sep 17 00:00:00 2001 From: Schrodinger ZHU Yifan Date: Sun, 2 Jan 2022 16:31:43 +0800 Subject: [PATCH 2/3] format Signed-off-by: Schrodinger ZHU Yifan --- src/pal/pal_windows.h | 2 +- src/test/func/malloc/malloc.cc | 35 +++++++++++++++++++++++----------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/pal/pal_windows.h b/src/pal/pal_windows.h index abadcf1d4..b5ac5d74c 100644 --- a/src/pal/pal_windows.h +++ b/src/pal/pal_windows.h @@ -13,7 +13,7 @@ # define NOMINMAX # endif # include -# ifndef __MINGW32__ +# ifndef __MINGW32__ # pragma comment(lib, "bcrypt.lib") # endif # include diff --git a/src/test/func/malloc/malloc.cc b/src/test/func/malloc/malloc.cc index dc764f360..a649815a8 100644 --- a/src/test/func/malloc/malloc.cc +++ b/src/test/func/malloc/malloc.cc @@ -1,6 +1,6 @@ +#include #include #include -#include #include #define SNMALLOC_NAME_MANGLE(a) our_##a @@ -48,12 +48,15 @@ void check_result(size_t size, size_t align, void* p, int err, bool null) #endif if (exact_size && (alloc_size != expected_size) && (size != 0)) { - std::cout << "Usable size is " << alloc_size << ", but required to be " << expected_size << "." << std::endl; + std::cout << "Usable size is " << alloc_size << ", but required to be " + << expected_size << "." << std::endl; failed = true; } if ((!exact_size) && (alloc_size < expected_size)) { - std::cout << "Usable size is " << alloc_size << ", but required to be at least " << expected_size << "." << std::endl; + std::cout << "Usable size is " << alloc_size + << ", but required to be at least " << expected_size << "." + << std::endl; failed = true; } if ( @@ -61,7 +64,9 @@ void check_result(size_t size, size_t align, void* p, int err, bool null) (size != 0)) { std::ios_base::fmtflags f(std::cout.flags()); - std::cout << std::hex << "Address is " << p << ", but required to be aligned to 0x" << align << "." << std::endl; + std::cout << std::hex << "Address is " << p + << ", but required to be aligned to 0x" << align << "." + << std::endl; std::cout.flags(f); failed = true; } @@ -70,7 +75,9 @@ void check_result(size_t size, size_t align, void* p, int err, bool null) reinterpret_cast(p) % natural_alignment(size)) != 0) { std::ios_base::fmtflags f(std::cout.flags()); - std::cout << std::hex << "Address is " << p << ", but should have natural alignment to 0x" << natural_alignment(size) << "." << std::endl; + std::cout << std::hex << "Address is " << p + << ", but should have natural alignment to 0x" + << natural_alignment(size) << "." << std::endl; std::cout.flags(f); failed = true; } @@ -85,7 +92,8 @@ void check_result(size_t size, size_t align, void* p, int err, bool null) void test_calloc(size_t nmemb, size_t size, int err, bool null) { - std::cout << "calloc(" << nmemb << ", " << size << ")" << " combined size " << nmemb * size << std::endl; + std::cout << "calloc(" << nmemb << ", " << size << ")" + << " combined size " << nmemb * size << std::endl; errno = SUCCESS; void* p = our_calloc(nmemb, size); @@ -109,7 +117,8 @@ void test_realloc(void* p, size_t size, int err, bool null) if (p != nullptr) old_size = our_malloc_usable_size(p); - std::cout << "realloc(" << p << "(" << old_size << ")" << ", " << size << ")" << std::endl; + std::cout << "realloc(" << p << "(" << old_size << ")" + << ", " << size << ")" << std::endl; errno = SUCCESS; auto new_p = our_realloc(p, size); // Realloc failure case, deallocate original block @@ -120,7 +129,8 @@ void test_realloc(void* p, size_t size, int err, bool null) void test_posix_memalign(size_t size, size_t align, int err, bool null) { - std::cout << "posix_memalign(&p, " << align << ", " << size << ")" << std::endl; + std::cout << "posix_memalign(&p, " << align << ", " << size << ")" + << std::endl; void* p = nullptr; errno = our_posix_memalign(&p, align, size); check_result(size, align, p, err, null); @@ -141,7 +151,8 @@ void test_reallocarray(void* p, size_t nmemb, size_t size, int err, bool null) if (p != nullptr) old_size = our_malloc_usable_size(p); - std::cout << "reallocarray(" << p << "(" << old_size << ")" << ", " << tsize << ")" << std::endl; + std::cout << "reallocarray(" << p << "(" << old_size << ")" + << ", " << tsize << ")" << std::endl; errno = SUCCESS; auto new_p = our_reallocarray(p, nmemb, size); if (new_p == nullptr && tsize != 0) @@ -160,11 +171,13 @@ void test_reallocarr( int r = our_reallocarr(&p, nmemb, size); if (r != err) { - std::cout << "reallocarr failed! expected " << err << " got " << r << std::endl; + std::cout << "reallocarr failed! expected " << err << " got " << r + << std::endl; abort(); } - std::cout << "reallocarr(" << p << "(" << nmemb << ")" << ", " << size << ")" << std::endl; + std::cout << "reallocarr(" << p << "(" << nmemb << ")" + << ", " << size << ")" << std::endl; check_result(nmemb * size, 1, p, err, null); p = our_malloc(size); if (!p) From 906d2cc1098c4f32ecac6de231612386c51cf542 Mon Sep 17 00:00:00 2001 From: Schrodinger ZHU Yifan Date: Wed, 5 Jan 2022 09:40:57 +0800 Subject: [PATCH 3/3] more fixes Signed-off-by: Schrodinger ZHU Yifan --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 73db7a8db..a54c45f76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,8 @@ if (NOT SNMALLOC_HEADER_ONLY_LIBRARY) set(SNMALLOC_CLEANUP_DEFAULT THREAD_CLEANUP) elseif (UNIX AND NOT APPLE) set(SNMALLOC_CLEANUP_DEFAULT PTHREAD_DESTRUCTORS) + elseif(MINGW) + set(SNMALLOC_CLEANUP_DEFAULT PTHREAD_DESTRUCTORS) else () set(SNMALLOC_CLEANUP_DEFAULT CXX11_DESTRUCTORS) endif() @@ -186,6 +188,10 @@ if (WIN32) message(STATUS "snmalloc: Avoiding Windows 10 APIs is ${WIN8COMPAT}") endif() +if (MINGW) + target_link_libraries(snmalloc INTERFACE -lbcrypt) +endif() + # Detect support for cmpxchg16b; Werror is needed to make sure mcx16 must be used by targets check_cxx_compiler_flag("-Werror -Wextra -Wall -mcx16" SNMALLOC_COMPILER_SUPPORT_MCX16) if(SNMALLOC_COMPILER_SUPPORT_MCX16)