1 | /* |
---|---|
2 | Copyright (c) 2005-2019 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 "harness_allocator_overload.h" |
18 | #define HARNESS_NO_PARSE_COMMAND_LINE 1 |
19 | #define __TBB_NO_IMPLICIT_LINKAGE 1 |
20 | |
21 | #include "harness.h" |
22 | |
23 | #if !HARNESS_SKIP_TEST && TBB_USE_EXCEPTIONS |
24 | |
25 | #include "harness_tbb_independence.h" |
26 | #include "harness_assert.h" |
27 | #include "harness_barrier.h" |
28 | |
29 | #include "../tbb/tls.h" |
30 | |
31 | tbb::internal::tls<bool> new_handler_called; |
32 | void customNewHandler() { |
33 | new_handler_called = true; |
34 | throw std::bad_alloc(); |
35 | } |
36 | |
37 | // Return true if operator new threw exception |
38 | bool allocateWithException(size_t big_mem) { |
39 | bool exception_caught = false; |
40 | try { |
41 | // Allocate big array (should throw exception) |
42 | char* volatile big_array = new char[big_mem]; |
43 | // If succeeded, double the size (unless it overflows) and recursively retry |
44 | if (big_mem * 2 > big_mem) { |
45 | exception_caught = allocateWithException(big_mem * 2); |
46 | } |
47 | delete[] big_array; |
48 | } catch (const std::bad_alloc&) { |
49 | ASSERT(new_handler_called, "User provided new_handler was not called."); |
50 | exception_caught = true; |
51 | } |
52 | return exception_caught; |
53 | } |
54 | |
55 | class AllocLoopBody : NoAssign { |
56 | public: |
57 | void operator()(int) const { |
58 | size_t BIG_MEM = 100 * 1024 * 1024; |
59 | new_handler_called = false; |
60 | ASSERT(allocateWithException(BIG_MEM), "Operator new did not throw bad_alloc."); |
61 | } |
62 | }; |
63 | |
64 | int TestMain() { |
65 | #if __TBB_CPP11_GET_NEW_HANDLER_PRESENT |
66 | std::new_handler default_handler = std::get_new_handler(); |
67 | ASSERT(default_handler == NULL, "No handler should be set at this point."); |
68 | #endif |
69 | // Define the handler for new operations |
70 | std::set_new_handler(customNewHandler); |
71 | // Run the test |
72 | NativeParallelFor(8, AllocLoopBody()); |
73 | // Undo custom handler |
74 | std::set_new_handler(0); |
75 | return Harness::Done; |
76 | } |
77 | #else |
78 | int TestMain() { |
79 | return Harness::Skipped; |
80 | } |
81 | #endif // !HARNESS_SKIP_TEST && TBB_USE_EXCEPTIONS |
82 |