4ed3763c742d99cc71e81282dfb656797bc03f2d
[platform/upstream/tbb.git] / src / test / test_tbb_header.cpp
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 /**
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.
20
21     Most of the checks happen at the compilation or link phases.
22 **/
23 #if __TBB_CPF_BUILD
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
32 #endif
33
34 #if __TBB_TEST_SECONDARY
35     // Test _DEBUG macro custom definitions.
36     #if TBB_USE_DEBUG
37         #ifdef _DEBUG
38             #undef _DEBUG
39         #endif /* _DEBUG */
40         // Check that empty value successfully enables the debug mode.
41         #define _DEBUG
42         static bool isDebugExpected = true;
43     #else
44         // Check that zero value does not enable the debug mode.
45         #define _DEBUG 0x0
46         static bool isDebugExpected = false;
47     #endif /* TBB_USE_DEBUG */
48     #define DO_TEST_DEBUG_MACRO 1
49 #else
50     // Test default definitions of _DEBUG.
51     #if _DEBUG
52         static bool isDebugExpected = true;
53         #define DO_TEST_DEBUG_MACRO 1
54     #elif _MSC_VER
55         // for MSVC, _DEBUG not defined indicates a release mode.
56         static bool isDebugExpected = false;
57         #define DO_TEST_DEBUG_MACRO 1
58     #endif /* _DEBUG */
59 #endif /* __TBB_TEST_SECONDARY */
60
61 #if DO_TEST_DEBUG_MACRO
62 // Reset TBB_USE_DEBUG defined in makefiles.
63 #undef TBB_USE_DEBUG
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"
67
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
71 #undef _DEBUG
72 #endif /* !TBB_USE_DEBUG && defined(_DEBUG) */
73
74 #include "harness_defs.h"
75 #if _MSC_VER
76 #pragma warning (disable : 4503)      // decorated name length exceeded, name was truncated
77 #endif
78
79 #if !(__TBB_TEST_SECONDARY && __TBB_CPP11_STD_PLACEHOLDERS_LINKAGE_BROKEN)
80
81 #include "tbb/tbb.h"
82
83 static volatile size_t g_sink;
84
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; }
89
90 struct Body {
91     void operator() () const {}
92 };
93 struct Body1 {
94     void operator() ( int ) const {}
95 };
96 struct Body1a { // feeder body for parallel_do
97     void operator() ( int, tbb::parallel_do_feeder<int>& ) const {}
98 };
99 struct Body1b { // binary operator for reduction and comparison
100     int operator() ( const int, const int ) const { return 0; }
101 };
102 struct Body2 {
103     Body2 () {}
104     Body2 ( const Body2&, tbb::split ) {}
105     void operator() ( const tbb::blocked_range<int>& ) const {}
106     void join( const Body2& ) {}
107 };
108 struct Body2a { // for lambda-friendly parallel_reduce
109     int operator() ( const tbb::blocked_range<int>&, const int ) const { return 0; }
110 };
111 struct Body3 { // for parallel_scan
112     Body3 () {}
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& ) {}
118 };
119 struct Body3a { // for lambda-friednly parallel_scan
120     int operator() ( const tbb::blocked_range<int>&, const int, bool ) const { return 0; }
121 };
122 struct Msg {};
123
124 #if !__TBB_TEST_SECONDARY
125
126 #define HARNESS_NO_PARSE_COMMAND_LINE 1
127 #include "harness.h"
128
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.
131 #include <stdexcept>
132
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 ) {
139         try {
140             if ( i == 0 )
141                 throw exc;
142 #if !__TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN
143             else
144                 tbb::internal::throw_exception( eid );
145 #endif
146         }
147         catch ( E& e ) {
148             ASSERT ( e.what(), "Missing what() string" );
149         }
150         catch ( ... ) {
151             ASSERT ( __TBB_EXCEPTION_TYPE_INFO_BROKEN, "Unrecognized exception. Likely RTTI related exports are missing" );
152         }
153     }
154 #else /* TBB_USE_EXCEPTIONS */
155     (void)exc;
156 #endif /* TBB_USE_EXCEPTIONS */
157 }
158
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 );
178 }
179 #endif /* !__TBB_TEST_SECONDARY */
180
181 #if __TBB_CPF_BUILD
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
184 struct Handler {
185     void operator()( tbb::aggregator_operation* ) {}
186 };
187 static void TestPreviewNames() {
188     TestTypeDefinitionPresence( aggregator );
189     TestTypeDefinitionPresence( aggregator_ext<Handler> );
190 #if __TBB_CPP11_PRESENT
191     TestTypeDefinitionPresence2(blocked_rangeNd<int,4> );
192 #endif
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 );
196 #endif
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> );
202 #endif
203 }
204 #endif
205
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.
209 */
210 #include "harness_assert.h"
211 bool Secondary()
212 #else
213 bool Secondary();
214 int TestMain ()
215 #endif
216 {
217     #if __TBB_CPP11_STD_PLACEHOLDERS_LINKAGE_BROKEN
218         REPORT("Known issue: \"multiple definition\" linker error detection test skipped.\n");
219     #endif
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> > );
262 #endif
263     /* Mutex names */
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 );
320
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 );
329 #endif
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*> );
342 #endif
343
344 #if __TBB_CPF_BUILD
345     TestPreviewNames();
346 #endif
347 #ifdef DO_TEST_DEBUG_MACRO
348 #if TBB_USE_DEBUG
349     ASSERT( isDebugExpected, "Debug mode is observed while release mode is expected." );
350 #else
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
355     return true;
356 #else
357     TestExceptionClassesExports();
358     Secondary();
359     return Harness::Done;
360 #endif /* __TBB_TEST_SECONDARY */
361 }
362 #endif //!(__TBB_TEST_SECONDARY && __TBB_CPP11_STD_PLACEHOLDERS_LINKING_BROKEN)