1 /* 2 Copyright (c) 2005-2021 Intel Corporation 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 #include "tbb/cache_aligned_allocator.h" 18 #include "tbb/tbb_allocator.h" 19 20 // the real body of the test is there: 21 #include "common/allocator_test_common.h" 22 #include "common/allocator_stl_test_common.h" 23 24 //! \file test_allocators.cpp 25 //! \brief Test for [memory_allocation.cache_aligned_allocator memory_allocation.tbb_allocator memory_allocation.cache_aligned_resource] specifications 26 27 #if TBB_USE_EXCEPTIONS 28 //! Test that cache_aligned_allocate() throws bad_alloc if cannot allocate memory. 29 //! \brief \ref requirement 30 TEST_CASE("Test cache_aligned_allocate throws") { 31 #if __APPLE__ 32 // On macOS*, failure to map memory results in messages to stderr; 33 // suppress them. 34 DisableStderr disableStderr; 35 #endif 36 37 using namespace tbb::detail::r1; 38 39 // First, allocate a reasonably big amount of memory, big enough 40 // to not cause warp around in system allocator after adding object header 41 // during address2 allocation. 42 const size_t itemsize = 1024; 43 const size_t nitems = 1024; 44 void *address1 = NULL; 45 try { 46 address1 = cache_aligned_allocate(nitems * itemsize); 47 } catch(...) { 48 // intentionally empty 49 } 50 REQUIRE_MESSAGE(address1, "cache_aligned_allocate unable to obtain 1024*1024 bytes"); 51 52 bool exception_caught = false; 53 try { 54 // Try allocating more memory than left in the address space; should cause std::bad_alloc 55 (void)cache_aligned_allocate(~size_t(0) - itemsize * nitems + cache_line_size()); 56 } catch (std::bad_alloc&) { 57 exception_caught = true; 58 } catch (...) { 59 REQUIRE_MESSAGE(false, "Unexpected exception type (std::bad_alloc was expected)"); 60 exception_caught = true; 61 } 62 REQUIRE_MESSAGE(exception_caught, "cache_aligned_allocate did not throw bad_alloc"); 63 64 try { 65 cache_aligned_deallocate(address1); 66 } catch (...) { 67 REQUIRE_MESSAGE(false, "cache_aligned_deallocate did not accept the address obtained with cache_aligned_allocate"); 68 } 69 } 70 #endif /* TBB_USE_EXCEPTIONS */ 71 72 #if TBB_ALLOCATOR_TRAITS_BROKEN 73 //! Testing allocator types in case std::allocator traits is broken 74 //! \brief \ref error_guessing 75 TEST_CASE("Broken allocator concept") { 76 TestAllocator<tbb::cache_aligned_allocator<void>>(Broken); 77 TestAllocator<tbb::tbb_allocator<void>>(Broken); 78 } 79 #endif 80 81 //! Testing allocators compatibility with STL containers 82 //! \brief \ref interface 83 TEST_CASE("Test allocators with STL containers") { 84 TestAllocatorWithSTL<tbb::cache_aligned_allocator<void>>(); 85 TestAllocatorWithSTL<tbb::tbb_allocator<void>>(); 86 } 87 88 #if __TBB_CPP17_MEMORY_RESOURCE_PRESENT 89 //! Testing memory resources compatibility with STL containers through the 90 //! std::pmr::polymorphic_allocator 91 //! \brief \ref interface 92 TEST_CASE("polymorphic_allocator test") { 93 tbb::cache_aligned_resource aligned_resource; 94 tbb::cache_aligned_resource equal_aligned_resource(std::pmr::get_default_resource()); 95 REQUIRE_MESSAGE(aligned_resource.is_equal(equal_aligned_resource), 96 "Underlying upstream resources should be equal."); 97 REQUIRE_MESSAGE(!aligned_resource.is_equal(*std::pmr::null_memory_resource()), 98 "Cache aligned resource upstream shouldn't be equal to the standard resource."); 99 TestAllocatorWithSTL(std::pmr::polymorphic_allocator<void>(&aligned_resource)); 100 } 101 #endif 102 103