From 941b6b60334bf2279a6b55961d944493977ed96a Mon Sep 17 00:00:00 2001 From: Lukasz Dorau Date: Wed, 13 Nov 2024 15:05:45 +0100 Subject: [PATCH] Add tests for the size threshold of the proxy library The proxyLib_size_threshold_* tests test the size threshold of the proxy library. The size threshold is set to 64 bytes in this test, so all allocations of: 1) size < 64 go through the default system allocator and (umfPoolByPtr(ptr_size < 64) == nullptr) 2) size >= 64 go through the proxy lib allocator and (umfPoolByPtr(ptr_size >= 64) != nullptr). Ref: #894 Signed-off-by: Lukasz Dorau --- .github/workflows/reusable_proxy_lib.yml | 12 +- test/CMakeLists.txt | 2 + test/test_proxy_lib.cpp | 154 +++++++++++++++++++---- 3 files changed, 140 insertions(+), 28 deletions(-) diff --git a/.github/workflows/reusable_proxy_lib.yml b/.github/workflows/reusable_proxy_lib.yml index ea212633e0..e3b1b92b29 100644 --- a/.github/workflows/reusable_proxy_lib.yml +++ b/.github/workflows/reusable_proxy_lib.yml @@ -61,9 +61,14 @@ jobs: # TODO enable the provider_file_memory_ipc test when the IPC tests with the proxy library are fixed # see the issue: https://github.com/oneapi-src/unified-memory-framework/issues/864 + # TODO enable the proxy_lib_basic test for the JEMALLOC proxy_lib_pool + # see the issue: https://github.com/oneapi-src/unified-memory-framework/issues/894 - name: Run "ctest --output-on-failure" with proxy library working-directory: ${{env.BUILD_DIR}} - run: LD_PRELOAD=./lib/libumf_proxy.so ctest --output-on-failure -E provider_file_memory_ipc + run: > + LD_PRELOAD=./lib/libumf_proxy.so + ctest --output-on-failure + ${{ matrix.proxy_lib_pool == 'JEMALLOC' && '-E "provider_file_memory_ipc|proxy_lib_basic"' || '-E provider_file_memory_ipc' }} - name: Run "./test/umf_test-memoryPool" with proxy library working-directory: ${{env.BUILD_DIR}} @@ -79,13 +84,16 @@ jobs: # TODO enable the provider_file_memory_ipc test when the IPC tests with the proxy library are fixed # see the issue: https://github.com/oneapi-src/unified-memory-framework/issues/864 + # TODO enable the proxy_lib_basic test for the JEMALLOC proxy_lib_pool + # see the issue: https://github.com/oneapi-src/unified-memory-framework/issues/894 - name: Run "ctest --output-on-failure" with proxy library and size.threshold=128 working-directory: ${{env.BUILD_DIR}} run: > UMF_PROXY="size.threshold=128" UMF_LOG="level:debug;flush:debug;output:stderr;pid:yes" LD_PRELOAD=./lib/libumf_proxy.so - ctest --output-on-failure -E provider_file_memory_ipc + ctest --output-on-failure + ${{ matrix.proxy_lib_pool == 'JEMALLOC' && '-E "provider_file_memory_ipc|proxy_lib_basic"' || '-E provider_file_memory_ipc' }} - name: Check coverage if: ${{ matrix.build_type == 'Debug' }} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d24244ab05..d2b8018d95 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -413,6 +413,8 @@ if(UMF_PROXY_LIB_ENABLED AND UMF_BUILD_SHARED_LIBRARY) NAME proxy_lib_basic SRCS ${BA_SOURCES_FOR_TEST} test_proxy_lib.cpp LIBS ${UMF_UTILS_FOR_TEST} umf_proxy) + set_property(TEST umf-proxy_lib_basic + PROPERTY ENVIRONMENT "UMF_PROXY=size.threshold=64") # the memoryPool test run with the proxy library add_umf_test( diff --git a/test/test_proxy_lib.cpp b/test/test_proxy_lib.cpp index 85afc65be8..8b0ffeaae5 100644 --- a/test/test_proxy_lib.cpp +++ b/test/test_proxy_lib.cpp @@ -19,13 +19,11 @@ using umf_test::test; +#define SIZE_63 63 #define SIZE_64 64 #define ALIGN_1024 1024 TEST_F(test, proxyLib_basic) { - - ::free(::malloc(SIZE_64)); - // a check to verify we are running the proxy library void *ptr = (void *)0x01; @@ -41,46 +39,150 @@ TEST_F(test, proxyLib_basic) { } TEST_F(test, proxyLib_realloc_size0) { - // realloc(ptr, 0) == free (ptr) + // realloc(ptr, 0) == free(ptr) // realloc(ptr, 0) returns NULL ASSERT_EQ(::realloc(::malloc(SIZE_64), 0), nullptr); } -TEST_F(test, proxyLib_malloc_usable_size) { - - void *ptr = ::malloc(SIZE_64); - ASSERT_NE(ptr, nullptr); - if (ptr == nullptr) { - // Fix for the following CodeQL's warning on Windows: - // 'ptr' could be '0': this does not adhere to the specification for the function '_msize'. - return; - } +// The proxyLib_size_threshold_* tests test the size threshold of the proxy library. +// The size threshold is set to 64 bytes in this test, so all allocations of: +// 1) size < 64 go through the default system allocator (umfPoolByPtr(ptr_size < 64) == nullptr) +// 2) size >= 64 go through the proxy lib allocator (umfPoolByPtr(ptr_size >= 64) != nullptr) +TEST_F(test, proxyLib_size_threshold_aligned_alloc) { #ifdef _WIN32 - size_t size = _msize(ptr); -#elif __APPLE__ - size_t size = ::malloc_size(ptr); + void *ptr_63 = _aligned_malloc(SIZE_63, ALIGN_1024); + void *ptr_64 = _aligned_malloc(SIZE_64, ALIGN_1024); #else - size_t size = ::malloc_usable_size(ptr); + void *ptr_63 = ::aligned_alloc(ALIGN_1024, SIZE_63); + void *ptr_64 = ::aligned_alloc(ALIGN_1024, SIZE_64); #endif - ASSERT_EQ((int)(size == 0 || size >= SIZE_64), 1); + ASSERT_NE(ptr_63, nullptr); + ASSERT_NE(ptr_64, nullptr); - ::free(ptr); -} + // verify alignment + ASSERT_EQ((int)(IS_ALIGNED((uintptr_t)ptr_63, ALIGN_1024)), 1); + ASSERT_EQ((int)(IS_ALIGNED((uintptr_t)ptr_64, ALIGN_1024)), 1); + + // umfPoolByPtr(ptr_size_63) == nullptr + ASSERT_EQ(umfPoolByPtr(ptr_63), nullptr); + // umfPoolByPtr(ptr_size_64) != nullptr + ASSERT_NE(umfPoolByPtr(ptr_64), nullptr); -TEST_F(test, proxyLib_aligned_alloc) { #ifdef _WIN32 - void *ptr = _aligned_malloc(SIZE_64, ALIGN_1024); + _aligned_free(ptr_63); + _aligned_free(ptr_64); #else - void *ptr = ::aligned_alloc(ALIGN_1024, SIZE_64); + ::free(ptr_63); + ::free(ptr_64); #endif +} + +TEST_F(test, proxyLib_size_threshold_malloc) { + void *ptr_63 = malloc(SIZE_63); + void *ptr_64 = malloc(SIZE_64); + + ASSERT_NE(ptr_63, nullptr); + ASSERT_NE(ptr_64, nullptr); + + // umfPoolByPtr(ptr_size_63) == nullptr + ASSERT_EQ(umfPoolByPtr(ptr_63), nullptr); + // umfPoolByPtr(ptr_size_64) != nullptr + ASSERT_NE(umfPoolByPtr(ptr_64), nullptr); + + ::free(ptr_63); + ::free(ptr_64); +} + +TEST_F(test, proxyLib_size_threshold_calloc) { + void *ptr_63 = calloc(SIZE_63, 1); + void *ptr_64 = calloc(SIZE_64, 1); + + ASSERT_NE(ptr_63, nullptr); + ASSERT_NE(ptr_64, nullptr); + + // umfPoolByPtr(ptr_size_63) == nullptr + ASSERT_EQ(umfPoolByPtr(ptr_63), nullptr); + // umfPoolByPtr(ptr_size_64) != nullptr + ASSERT_NE(umfPoolByPtr(ptr_64), nullptr); + + ::free(ptr_63); + ::free(ptr_64); +} - ASSERT_EQ((int)(IS_ALIGNED((uintptr_t)ptr, ALIGN_1024)), 1); +TEST_F(test, proxyLib_size_threshold_realloc_up) { + void *ptr_63 = malloc(SIZE_63); + void *ptr_64 = malloc(SIZE_64); + + ASSERT_NE(ptr_63, nullptr); + ASSERT_NE(ptr_64, nullptr); + + ptr_63 = realloc(ptr_63, 2 * SIZE_63); + ptr_64 = realloc(ptr_64, 2 * SIZE_64); + + ASSERT_NE(ptr_63, nullptr); + ASSERT_NE(ptr_64, nullptr); + + // umfPoolByPtr(ptr_size_63) == nullptr + ASSERT_EQ(umfPoolByPtr(ptr_63), nullptr); + // umfPoolByPtr(ptr_size_64) != nullptr + ASSERT_NE(umfPoolByPtr(ptr_64), nullptr); + + ::free(ptr_63); + ::free(ptr_64); +} + +TEST_F(test, proxyLib_size_threshold_realloc_down) { + void *ptr_63 = malloc(SIZE_63); + void *ptr_64 = malloc(SIZE_64); + + ASSERT_NE(ptr_63, nullptr); + ASSERT_NE(ptr_64, nullptr); + + ptr_63 = realloc(ptr_63, SIZE_63 / 2); + ptr_64 = realloc(ptr_64, SIZE_64 / 2); + + ASSERT_NE(ptr_63, nullptr); + ASSERT_NE(ptr_64, nullptr); + + // umfPoolByPtr(ptr_size_63) == nullptr + ASSERT_EQ(umfPoolByPtr(ptr_63), nullptr); + // umfPoolByPtr(ptr_size_64) != nullptr + ASSERT_NE(umfPoolByPtr(ptr_64), nullptr); + + ::free(ptr_63); + ::free(ptr_64); +} + +TEST_F(test, proxyLib_size_threshold_malloc_usable_size) { + + void *ptr_63 = ::malloc(SIZE_63); + void *ptr_64 = ::malloc(SIZE_64); + + ASSERT_NE(ptr_63, nullptr); + ASSERT_NE(ptr_64, nullptr); + + if (ptr_63 == nullptr || ptr_64 == nullptr) { + // Fix for the following CodeQL's warning on Windows: + // 'ptr' could be '0': this does not adhere to the specification for the function '_msize'. + return; + } #ifdef _WIN32 - _aligned_free(ptr); + size_t size_63 = _msize(ptr_63); + size_t size_64 = _msize(ptr_64); +#elif __APPLE__ + size_t size_63 = ::malloc_size(ptr_63); + size_t size_64 = ::malloc_size(ptr_64); #else - ::free(ptr); + size_t size_63 = ::malloc_usable_size(ptr_63); + size_t size_64 = ::malloc_usable_size(ptr_64); #endif + + ASSERT_EQ((int)(size_63 == 0 || size_63 >= SIZE_63), 1); + ASSERT_EQ((int)(size_64 == 0 || size_64 >= SIZE_64), 1); + + ::free(ptr_63); + ::free(ptr_64); }