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// Test correctness of forceful TBB initialization before any dynamic initialization
18// of static objects inside the library took place.
19namespace tbb {
20namespace internal {
21 // Forward declaration of the TBB general initialization routine from task.cpp
22 void DoOneTimeInitializations();
23}}
24
25struct StaticInitializationChecker {
26 StaticInitializationChecker () { tbb::internal::DoOneTimeInitializations(); }
27} theChecker;
28
29//------------------------------------------------------------------------
30// Test that important assertions in class task fail as expected.
31//------------------------------------------------------------------------
32
33#define HARNESS_NO_PARSE_COMMAND_LINE 1
34#include "harness_inject_scheduler.h"
35#include "harness.h"
36#include "harness_bad_expr.h"
37
38#if TRY_BAD_EXPR_ENABLED
39//! Task that will be abused.
40tbb::task* volatile AbusedTask;
41
42//! Number of times that AbuseOneTask
43int AbuseOneTaskRan;
44
45//! Body used to create task in thread 0 and abuse it in thread 1.
46struct AbuseOneTask {
47 void operator()( int ) const {
48 tbb::task_scheduler_init init;
49 // Thread 1 attempts to incorrectly use the task created by thread 0.
50 tbb::task_list list;
51 // spawn_root_and_wait over empty list should vacuously succeed.
52 tbb::task::spawn_root_and_wait(list);
53
54 // Check that spawn_root_and_wait fails on non-empty list.
55 list.push_back(*AbusedTask);
56
57 // Try abusing recycle_as_continuation
58 TRY_BAD_EXPR(AbusedTask->recycle_as_continuation(), "execute" );
59 TRY_BAD_EXPR(AbusedTask->recycle_as_safe_continuation(), "execute" );
60 TRY_BAD_EXPR(AbusedTask->recycle_to_reexecute(), "execute" );
61 ++AbuseOneTaskRan;
62 }
63};
64
65//! Test various __TBB_ASSERT assertions related to class tbb::task.
66void TestTaskAssertions() {
67 // Catch assertion failures
68 tbb::set_assertion_handler( AssertionFailureHandler );
69 tbb::task_scheduler_init init;
70 // Create task to be abused
71 AbusedTask = new( tbb::task::allocate_root() ) tbb::empty_task;
72 NativeParallelFor( 1, AbuseOneTask() );
73 ASSERT( AbuseOneTaskRan==1, NULL );
74 tbb::task::destroy(*AbusedTask);
75 // Restore normal assertion handling
76 tbb::set_assertion_handler( ReportError );
77}
78
79int TestMain () {
80 TestTaskAssertions();
81 return Harness::Done;
82}
83
84#else /* !TRY_BAD_EXPR_ENABLED */
85
86int TestMain () {
87 return Harness::Skipped;
88}
89
90#endif /* !TRY_BAD_EXPR_ENABLED */
91