2 Copyright (c) 2005-2019 Intel Corporation
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
8 http://www.apache.org/licenses/LICENSE-2.0
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.
18 This test ensures that tbb.h brings in all the public TBB interface definitions,
19 and if all the necessary symbols are exported from the library.
21 Most of the checks happen at the compilation or link phases.
24 // Add testing of preview features
25 #define TBB_PREVIEW_AGGREGATOR 1
26 #define TBB_PREVIEW_CONCURRENT_LRU_CACHE 1
27 #define TBB_PREVIEW_VARIADIC_PARALLEL_INVOKE 1
28 #define TBB_PREVIEW_FLOW_GRAPH_NODES 1
29 #define TBB_PREVIEW_BLOCKED_RANGE_ND 1
30 #define TBB_PREVIEW_WAITING_FOR_WORKERS 1
31 #define TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS 1
34 #if __TBB_TEST_SECONDARY
35 // Test _DEBUG macro custom definitions.
40 // Check that empty value successfully enables the debug mode.
42 static bool isDebugExpected = true;
44 // Check that zero value does not enable the debug mode.
46 static bool isDebugExpected = false;
47 #endif /* TBB_USE_DEBUG */
48 #define DO_TEST_DEBUG_MACRO 1
50 // Test default definitions of _DEBUG.
52 static bool isDebugExpected = true;
53 #define DO_TEST_DEBUG_MACRO 1
55 // for MSVC, _DEBUG not defined indicates a release mode.
56 static bool isDebugExpected = false;
57 #define DO_TEST_DEBUG_MACRO 1
59 #endif /* __TBB_TEST_SECONDARY */
61 #if DO_TEST_DEBUG_MACRO
62 // Reset TBB_USE_DEBUG defined in makefiles.
64 #endif /* DO_TEST_DEBUG_MACRO */
65 #define __TBB_CONFIG_PREPROC_ONLY _MSC_VER // For MSVC, prevent including standard headers in tbb_config.h
66 #include "tbb/tbb_config.h"
68 #if !TBB_USE_DEBUG && defined(_DEBUG)
69 // TBB_USE_DEBUG is 0 but _DEBUG is defined, it means that _DEBUG is 0
70 // MSVC C++ headers consider any definition of _DEBUG, including 0, as debug mode
72 #endif /* !TBB_USE_DEBUG && defined(_DEBUG) */
74 #include "harness_defs.h"
76 #pragma warning (disable : 4503) // decorated name length exceeded, name was truncated
79 #if !(__TBB_TEST_SECONDARY && __TBB_CPP11_STD_PLACEHOLDERS_LINKAGE_BROKEN)
83 static volatile size_t g_sink;
85 #define TestTypeDefinitionPresence( Type ) g_sink = sizeof(tbb::Type);
86 #define TestTypeDefinitionPresence2(TypeStart, TypeEnd) g_sink = sizeof(tbb::TypeStart,TypeEnd);
87 #define TestTypeDefinitionPresence3(TypeStart, TypeMid, TypeEnd) g_sink = sizeof(tbb::TypeStart,TypeMid,TypeEnd);
88 #define TestFuncDefinitionPresence(Fn, Args, ReturnType) { ReturnType (*pfn)Args = &tbb::Fn; (void)pfn; }
91 void operator() () const {}
94 void operator() ( int ) const {}
96 struct Body1a { // feeder body for parallel_do
97 void operator() ( int, tbb::parallel_do_feeder<int>& ) const {}
99 struct Body1b { // binary operator for reduction and comparison
100 int operator() ( const int, const int ) const { return 0; }
104 Body2 ( const Body2&, tbb::split ) {}
105 void operator() ( const tbb::blocked_range<int>& ) const {}
106 void join( const Body2& ) {}
108 struct Body2a { // for lambda-friendly parallel_reduce
109 int operator() ( const tbb::blocked_range<int>&, const int ) const { return 0; }
111 struct Body3 { // for parallel_scan
113 Body3 ( const Body3&, tbb::split ) {}
114 void operator() ( const tbb::blocked_range2d<int>&, tbb::pre_scan_tag ) const {}
115 void operator() ( const tbb::blocked_range2d<int>&, tbb::final_scan_tag ) const {}
116 void reverse_join( Body3& ) {}
117 void assign( const Body3& ) {}
119 struct Body3a { // for lambda-friednly parallel_scan
120 int operator() ( const tbb::blocked_range<int>&, const int, bool ) const { return 0; }
124 #if !__TBB_TEST_SECONDARY
126 #define HARNESS_NO_PARSE_COMMAND_LINE 1
129 // Test if all the necessary symbols are exported for the exceptions thrown by TBB.
130 // Missing exports result either in link error or in runtime assertion failure.
133 template <typename E>
134 void TestExceptionClassExports ( const E& exc, tbb::internal::exception_id eid ) {
135 // The assertion here serves to shut up warnings about "eid not used".
136 ASSERT( eid<tbb::internal::eid_max, NULL );
137 #if TBB_USE_EXCEPTIONS
138 for ( int i = 0; i < 2; ++i ) {
142 #if !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN
144 tbb::internal::throw_exception( eid );
148 ASSERT ( e.what(), "Missing what() string" );
151 ASSERT ( __TBB_EXCEPTION_TYPE_INFO_BROKEN, "Unrecognized exception. Likely RTTI related exports are missing" );
154 #else /* TBB_USE_EXCEPTIONS */
156 #endif /* TBB_USE_EXCEPTIONS */
159 void TestExceptionClassesExports () {
160 TestExceptionClassExports( std::bad_alloc(), tbb::internal::eid_bad_alloc );
161 TestExceptionClassExports( tbb::bad_last_alloc(), tbb::internal::eid_bad_last_alloc );
162 TestExceptionClassExports( std::invalid_argument("test"), tbb::internal::eid_nonpositive_step );
163 TestExceptionClassExports( std::out_of_range("test"), tbb::internal::eid_out_of_range );
164 TestExceptionClassExports( std::range_error("test"), tbb::internal::eid_segment_range_error );
165 TestExceptionClassExports( std::range_error("test"), tbb::internal::eid_index_range_error );
166 TestExceptionClassExports( tbb::missing_wait(), tbb::internal::eid_missing_wait );
167 TestExceptionClassExports( tbb::invalid_multiple_scheduling(), tbb::internal::eid_invalid_multiple_scheduling );
168 TestExceptionClassExports( tbb::improper_lock(), tbb::internal::eid_improper_lock );
169 TestExceptionClassExports( std::runtime_error("test"), tbb::internal::eid_possible_deadlock );
170 TestExceptionClassExports( std::runtime_error("test"), tbb::internal::eid_operation_not_permitted );
171 TestExceptionClassExports( std::runtime_error("test"), tbb::internal::eid_condvar_wait_failed );
172 TestExceptionClassExports( std::out_of_range("test"), tbb::internal::eid_invalid_load_factor );
173 TestExceptionClassExports( std::invalid_argument("test"), tbb::internal::eid_invalid_swap );
174 TestExceptionClassExports( std::length_error("test"), tbb::internal::eid_reservation_length_error );
175 TestExceptionClassExports( std::out_of_range("test"), tbb::internal::eid_invalid_key );
176 TestExceptionClassExports( tbb::user_abort(), tbb::internal::eid_user_abort );
177 TestExceptionClassExports( std::runtime_error("test"), tbb::internal::eid_bad_tagged_msg_cast );
179 #endif /* !__TBB_TEST_SECONDARY */
182 // These names are only tested in "preview" configuration
183 // When a feature becomes fully supported, its names should be moved to the main test
185 void operator()( tbb::aggregator_operation* ) {}
187 static void TestPreviewNames() {
188 TestTypeDefinitionPresence( aggregator );
189 TestTypeDefinitionPresence( aggregator_ext<Handler> );
190 #if __TBB_CPP11_PRESENT
191 TestTypeDefinitionPresence2(blocked_rangeNd<int,4> );
193 TestTypeDefinitionPresence2(concurrent_lru_cache<int, int> );
194 #if !__TBB_TEST_SECONDARY
195 TestExceptionClassExports( std::runtime_error("test"), tbb::internal::eid_blocking_thread_join_impossible );
197 #if __TBB_CONCURRENT_ORDERED_CONTAINERS_PRESENT
198 TestTypeDefinitionPresence2(concurrent_map<int, int> );
199 TestTypeDefinitionPresence2(concurrent_multimap<int, int> );
200 TestTypeDefinitionPresence(concurrent_set<int> );
201 TestTypeDefinitionPresence(concurrent_multiset<int> );
206 #if __TBB_TEST_SECONDARY
207 /* This mode is used to produce a secondary object file that is linked with
208 the main one in order to detect "multiple definition" linker error.
210 #include "harness_assert.h"
217 #if __TBB_CPP11_STD_PLACEHOLDERS_LINKAGE_BROKEN
218 REPORT("Known issue: \"multiple definition\" linker error detection test skipped.\n");
220 TestTypeDefinitionPresence( aligned_space<int> );
221 TestTypeDefinitionPresence( atomic<int> );
222 TestTypeDefinitionPresence( cache_aligned_allocator<int> );
223 TestTypeDefinitionPresence( tbb_hash_compare<int> );
224 TestTypeDefinitionPresence2(concurrent_hash_map<int, int> );
225 TestTypeDefinitionPresence2(concurrent_unordered_map<int, int> );
226 TestTypeDefinitionPresence2(concurrent_unordered_multimap<int, int> );
227 TestTypeDefinitionPresence( concurrent_unordered_set<int> );
228 TestTypeDefinitionPresence( concurrent_unordered_multiset<int> );
229 TestTypeDefinitionPresence( concurrent_bounded_queue<int> );
230 TestTypeDefinitionPresence( concurrent_queue<int> );
231 TestTypeDefinitionPresence( strict_ppl::concurrent_queue<int> );
232 TestTypeDefinitionPresence( concurrent_priority_queue<int> );
233 TestTypeDefinitionPresence( concurrent_vector<int> );
234 TestTypeDefinitionPresence( combinable<int> );
235 TestTypeDefinitionPresence( enumerable_thread_specific<int> );
236 /* Flow graph names */
237 TestTypeDefinitionPresence( flow::graph );
238 TestTypeDefinitionPresence( flow::continue_msg );
239 TestTypeDefinitionPresence2(flow::tagged_msg<int, int> );
240 TestFuncDefinitionPresence( flow::make_edge, (tbb::flow::sender<Msg>&, tbb::flow::receiver<Msg>&), void );
241 TestFuncDefinitionPresence( flow::remove_edge, (tbb::flow::sender<Msg>&, tbb::flow::receiver<Msg>&), void );
242 typedef tbb::flow::tuple<int, int> intpair;
243 TestTypeDefinitionPresence( flow::source_node<int> );
244 TestTypeDefinitionPresence3(flow::function_node<int, int, tbb::flow::rejecting> );
245 TestTypeDefinitionPresence3(flow::multifunction_node<int, intpair, tbb::flow::queueing> );
246 TestTypeDefinitionPresence3(flow::async_node<int, int, tbb::flow::queueing_lightweight> );
247 TestTypeDefinitionPresence2(flow::continue_node<int, tbb::flow::lightweight> );
248 TestTypeDefinitionPresence2(flow::join_node<intpair, tbb::flow::reserving> );
249 TestTypeDefinitionPresence2(flow::join_node<intpair, tbb::flow::key_matching<int> > );
250 TestTypeDefinitionPresence( flow::split_node<intpair> );
251 TestTypeDefinitionPresence( flow::overwrite_node<int> );
252 TestTypeDefinitionPresence( flow::write_once_node<int> );
253 TestTypeDefinitionPresence( flow::broadcast_node<int> );
254 TestTypeDefinitionPresence( flow::buffer_node<int> );
255 TestTypeDefinitionPresence( flow::queue_node<int> );
256 TestTypeDefinitionPresence( flow::sequencer_node<int> );
257 TestTypeDefinitionPresence( flow::priority_queue_node<int> );
258 TestTypeDefinitionPresence( flow::limiter_node<int> );
259 TestTypeDefinitionPresence2(flow::indexer_node<int, int> );
260 #if __TBB_FLOW_GRAPH_CPP11_FEATURES
261 TestTypeDefinitionPresence2(flow::composite_node<tbb::flow::tuple<int>, tbb::flow::tuple<int> > );
264 TestTypeDefinitionPresence( mutex );
265 TestTypeDefinitionPresence( null_mutex );
266 TestTypeDefinitionPresence( null_rw_mutex );
267 TestTypeDefinitionPresence( queuing_mutex );
268 TestTypeDefinitionPresence( queuing_rw_mutex );
269 TestTypeDefinitionPresence( recursive_mutex );
270 TestTypeDefinitionPresence( spin_mutex );
271 TestTypeDefinitionPresence( spin_rw_mutex );
272 TestTypeDefinitionPresence( speculative_spin_mutex );
273 TestTypeDefinitionPresence( speculative_spin_rw_mutex );
274 TestTypeDefinitionPresence( critical_section );
275 TestTypeDefinitionPresence( reader_writer_lock );
276 #if __TBB_TASK_GROUP_CONTEXT
277 TestTypeDefinitionPresence( tbb_exception );
278 TestTypeDefinitionPresence( captured_exception );
279 TestTypeDefinitionPresence( movable_exception<int> );
280 #if !TBB_USE_CAPTURED_EXCEPTION
281 TestTypeDefinitionPresence( internal::tbb_exception_ptr );
282 #endif /* !TBB_USE_CAPTURED_EXCEPTION */
283 TestTypeDefinitionPresence( task_group_context );
284 TestTypeDefinitionPresence( task_group );
285 TestTypeDefinitionPresence( structured_task_group );
286 TestTypeDefinitionPresence( task_handle<Body> );
287 #endif /* __TBB_TASK_GROUP_CONTEXT */
288 /* Algorithm related names */
289 TestTypeDefinitionPresence( blocked_range<int> );
290 TestTypeDefinitionPresence( blocked_range2d<int> );
291 TestTypeDefinitionPresence( blocked_range3d<int> );
292 TestFuncDefinitionPresence( parallel_invoke, (const Body&, const Body&, const Body&), void );
293 TestFuncDefinitionPresence( parallel_do, (int*, int*, const Body1&), void );
294 TestFuncDefinitionPresence( parallel_for_each, (int*, int*, const Body1&), void );
295 TestFuncDefinitionPresence( parallel_for, (int, int, int, const Body1&), void );
296 TestFuncDefinitionPresence( parallel_for, (const tbb::blocked_range<int>&, const Body2&, const tbb::simple_partitioner&), void );
297 TestFuncDefinitionPresence( parallel_reduce, (const tbb::blocked_range<int>&, const int&, const Body2a&, const Body1b&), int );
298 TestFuncDefinitionPresence( parallel_reduce, (const tbb::blocked_range<int>&, Body2&, tbb::affinity_partitioner&), void );
299 TestFuncDefinitionPresence( parallel_deterministic_reduce, (const tbb::blocked_range<int>&, const int&, const Body2a&, const Body1b&), int );
300 TestFuncDefinitionPresence( parallel_deterministic_reduce, (const tbb::blocked_range<int>&, Body2&, const tbb::static_partitioner&), void );
301 TestFuncDefinitionPresence( parallel_scan, (const tbb::blocked_range2d<int>&, Body3&, const tbb::auto_partitioner&), void );
302 TestFuncDefinitionPresence( parallel_scan, (const tbb::blocked_range<int>&, const int&, const Body3a&, const Body1b&), int );
303 typedef int intarray[10];
304 TestFuncDefinitionPresence( parallel_sort, (int*, int*), void );
305 TestFuncDefinitionPresence( parallel_sort, (intarray&, const Body1b&), void );
306 TestTypeDefinitionPresence( pipeline );
307 TestFuncDefinitionPresence( parallel_pipeline, (size_t, const tbb::filter_t<void,void>&), void );
308 #if __TBB_TASK_GROUP_CONTEXT
309 TestFuncDefinitionPresence( parallel_invoke, (const Body&, const Body&, tbb::task_group_context&), void );
310 TestFuncDefinitionPresence( parallel_do, (const intarray&, const Body1a&, tbb::task_group_context&), void );
311 TestFuncDefinitionPresence( parallel_for_each, (const intarray&, const Body1&, tbb::task_group_context&), void );
312 TestFuncDefinitionPresence( parallel_for, (int, int, const Body1&, const tbb::auto_partitioner&, tbb::task_group_context&), void );
313 TestFuncDefinitionPresence( parallel_for, (int, int, const Body1&, tbb::task_group_context&), void );
314 TestFuncDefinitionPresence( parallel_reduce, (const tbb::blocked_range<int>&, Body2&, const tbb::auto_partitioner&, tbb::task_group_context&), void );
315 TestFuncDefinitionPresence( parallel_reduce, (const tbb::blocked_range<int>&, Body2&, tbb::task_group_context&), void );
316 TestFuncDefinitionPresence( parallel_deterministic_reduce, (const tbb::blocked_range<int>&, Body2&, const tbb::simple_partitioner&, tbb::task_group_context&), void );
317 TestFuncDefinitionPresence( parallel_deterministic_reduce, (const tbb::blocked_range<int>&, Body2&, tbb::task_group_context&), void );
318 #endif /* __TBB_TASK_GROUP_CONTEXT */
319 TestTypeDefinitionPresence( proportional_split );
321 TestTypeDefinitionPresence( task );
322 TestTypeDefinitionPresence( empty_task );
323 TestTypeDefinitionPresence( task_list );
324 TestTypeDefinitionPresence( task_arena );
325 TestFuncDefinitionPresence( this_task_arena::current_thread_index, (), int );
326 TestFuncDefinitionPresence( this_task_arena::max_concurrency, (), int );
327 #if !__TBB_GCC_OVERLOADED_TEMPLATE_FUNCTION_ADDRESS_BROKEN
328 TestFuncDefinitionPresence( this_task_arena::isolate, (const Body&), void );
330 TestTypeDefinitionPresence( task_scheduler_init );
331 TestTypeDefinitionPresence( task_scheduler_observer );
332 TestTypeDefinitionPresence( tbb_thread );
333 TestFuncDefinitionPresence( tbb_thread::hardware_concurrency, (), unsigned );
334 TestFuncDefinitionPresence( this_tbb_thread::yield, (), void );
335 TestTypeDefinitionPresence( tbb_allocator<int> );
336 TestTypeDefinitionPresence( zero_allocator<int> );
337 TestTypeDefinitionPresence( tick_count );
338 TestTypeDefinitionPresence( global_control );
339 #if __TBB_CPP11_PRESENT
340 TestTypeDefinitionPresence( counting_iterator<int> );
341 TestTypeDefinitionPresence2(zip_iterator<int*,int*> );
347 #ifdef DO_TEST_DEBUG_MACRO
349 ASSERT( isDebugExpected, "Debug mode is observed while release mode is expected." );
351 ASSERT( !isDebugExpected, "Release mode is observed while debug mode is expected." );
352 #endif /* TBB_USE_DEBUG */
353 #endif /* DO_TEST_DEBUG_MACRO */
354 #if __TBB_TEST_SECONDARY
357 TestExceptionClassesExports();
359 return Harness::Done;
360 #endif /* __TBB_TEST_SECONDARY */
362 #endif //!(__TBB_TEST_SECONDARY && __TBB_CPP11_STD_PLACEHOLDERS_LINKING_BROKEN)