151c0b2f7Stbbdev /* 2b15aabb3Stbbdev Copyright (c) 2005-2021 Intel Corporation 351c0b2f7Stbbdev 451c0b2f7Stbbdev Licensed under the Apache License, Version 2.0 (the "License"); 551c0b2f7Stbbdev you may not use this file except in compliance with the License. 651c0b2f7Stbbdev You may obtain a copy of the License at 751c0b2f7Stbbdev 851c0b2f7Stbbdev http://www.apache.org/licenses/LICENSE-2.0 951c0b2f7Stbbdev 1051c0b2f7Stbbdev Unless required by applicable law or agreed to in writing, software 1151c0b2f7Stbbdev distributed under the License is distributed on an "AS IS" BASIS, 1251c0b2f7Stbbdev WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1351c0b2f7Stbbdev See the License for the specific language governing permissions and 1451c0b2f7Stbbdev limitations under the License. 1551c0b2f7Stbbdev */ 1651c0b2f7Stbbdev 1751c0b2f7Stbbdev //! \file test_malloc_new_handler.cpp 1851c0b2f7Stbbdev //! \brief Test for [memory_allocation] functionality 1951c0b2f7Stbbdev 2051c0b2f7Stbbdev #define __TBB_NO_IMPLICIT_LINKAGE 1 2151c0b2f7Stbbdev 2251c0b2f7Stbbdev #include "common/test.h" 2351c0b2f7Stbbdev #include "common/utils.h" 2451c0b2f7Stbbdev 2551c0b2f7Stbbdev #include "common/allocator_overload.h" 2651c0b2f7Stbbdev 27*3a658065SAnton Potapov // Under ASAN current approach is not viable as it breaks the ASAN itself as well 28*3a658065SAnton Potapov #if !HARNESS_SKIP_TEST && TBB_USE_EXCEPTIONS && !__TBB_TEST_USE_ADDRESS_SANITIZER 2951c0b2f7Stbbdev 3055f9b178SIvan Kochin #if _MSC_VER 3155f9b178SIvan Kochin #pragma warning (push) 3255f9b178SIvan Kochin // Forcing value to bool 'true' or 'false' (occurred inside tls.h) 3355f9b178SIvan Kochin #pragma warning (disable: 4800) 3455f9b178SIvan Kochin #endif //#if _MSC_VER 3555f9b178SIvan Kochin 3651c0b2f7Stbbdev #include "../../src/tbb/tls.h" 3751c0b2f7Stbbdev 3851c0b2f7Stbbdev tbb::detail::r1::tls<bool> new_handler_called; 3951c0b2f7Stbbdev void customNewHandler() { 4051c0b2f7Stbbdev new_handler_called = true; 4151c0b2f7Stbbdev throw std::bad_alloc(); 4251c0b2f7Stbbdev } 4351c0b2f7Stbbdev 4451c0b2f7Stbbdev // Return true if operator new threw exception 4551c0b2f7Stbbdev bool allocateWithException(size_t big_mem) { 4651c0b2f7Stbbdev bool exception_caught = false; 4751c0b2f7Stbbdev try { 4851c0b2f7Stbbdev // Allocate big array (should throw exception) 4951c0b2f7Stbbdev char* volatile big_array = new char[big_mem]; 5051c0b2f7Stbbdev // If succeeded, double the size (unless it overflows) and recursively retry 5151c0b2f7Stbbdev if (big_mem * 2 > big_mem) { 5251c0b2f7Stbbdev exception_caught = allocateWithException(big_mem * 2); 5351c0b2f7Stbbdev } 5451c0b2f7Stbbdev delete[] big_array; 5551c0b2f7Stbbdev } catch (const std::bad_alloc&) { 5651c0b2f7Stbbdev bool is_called = new_handler_called; 5751c0b2f7Stbbdev REQUIRE_MESSAGE(is_called, "User provided new_handler was not called."); 5851c0b2f7Stbbdev exception_caught = true; 5951c0b2f7Stbbdev } 6051c0b2f7Stbbdev return exception_caught; 6151c0b2f7Stbbdev } 6251c0b2f7Stbbdev 6351c0b2f7Stbbdev class AllocLoopBody : utils::NoAssign { 6451c0b2f7Stbbdev public: 6551c0b2f7Stbbdev void operator()(int) const { 6651c0b2f7Stbbdev size_t BIG_MEM = 100 * 1024 * 1024; 6751c0b2f7Stbbdev new_handler_called = false; 6851c0b2f7Stbbdev REQUIRE_MESSAGE(allocateWithException(BIG_MEM), "Operator new did not throw bad_alloc."); 6951c0b2f7Stbbdev } 7051c0b2f7Stbbdev }; 7151c0b2f7Stbbdev 7251c0b2f7Stbbdev //! \brief \ref error_guessing 7351c0b2f7Stbbdev TEST_CASE("New handler callback") { 7451c0b2f7Stbbdev #if __TBB_CPP11_GET_NEW_HANDLER_PRESENT 7551c0b2f7Stbbdev std::new_handler default_handler = std::get_new_handler(); 7651c0b2f7Stbbdev REQUIRE_MESSAGE(default_handler == nullptr, "No handler should be set at this point."); 7751c0b2f7Stbbdev #endif 7851c0b2f7Stbbdev // Define the handler for new operations 7951c0b2f7Stbbdev std::set_new_handler(customNewHandler); 8051c0b2f7Stbbdev // Run the test 8151c0b2f7Stbbdev utils::NativeParallelFor(8, AllocLoopBody()); 8251c0b2f7Stbbdev // Undo custom handler 8351c0b2f7Stbbdev std::set_new_handler(0); 8451c0b2f7Stbbdev } 8555f9b178SIvan Kochin 8655f9b178SIvan Kochin #if _MSC_VER 8755f9b178SIvan Kochin #pragma warning (pop) 8855f9b178SIvan Kochin #endif 8955f9b178SIvan Kochin 9051c0b2f7Stbbdev #endif // !HARNESS_SKIP_TEST && TBB_USE_EXCEPTIONS 91