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 | #define HARNESS_DEFAULT_MIN_THREADS 2 |
18 | #define HARNESS_DEFAULT_MAX_THREADS 2 |
19 | |
20 | #if !TBB_USE_THREADING_TOOLS |
21 | #define TBB_USE_THREADING_TOOLS 1 |
22 | #endif |
23 | |
24 | #include "harness.h" |
25 | |
26 | #if DO_ITT_NOTIFY |
27 | |
28 | #include "tbb/spin_mutex.h" |
29 | #include "tbb/spin_rw_mutex.h" |
30 | #include "tbb/queuing_rw_mutex.h" |
31 | #include "tbb/queuing_mutex.h" |
32 | #include "tbb/mutex.h" |
33 | #include "tbb/recursive_mutex.h" |
34 | #include "tbb/parallel_for.h" |
35 | #include "tbb/blocked_range.h" |
36 | #include "tbb/task_scheduler_init.h" |
37 | |
38 | |
39 | #include "../tbb/itt_notify.h" |
40 | |
41 | |
42 | template<typename M> |
43 | class WorkEmulator: NoAssign { |
44 | M& m_mutex; |
45 | static volatile size_t s_anchor; |
46 | public: |
47 | void operator()( tbb::blocked_range<size_t>& range ) const { |
48 | for( size_t i=range.begin(); i!=range.end(); ++i ) { |
49 | typename M::scoped_lock lock(m_mutex); |
50 | for ( size_t j = 0; j!=range.end(); ++j ) |
51 | s_anchor = (s_anchor - i) / 2 + (s_anchor + j) / 2; |
52 | } |
53 | } |
54 | WorkEmulator( M& mutex ) : m_mutex(mutex) {} |
55 | }; |
56 | |
57 | template<typename M> |
58 | volatile size_t WorkEmulator<M>::s_anchor = 0; |
59 | |
60 | |
61 | template<class M> |
62 | void Test( const char * name ) { |
63 | REMARK("Testing %s\n" ,name); |
64 | M mtx; |
65 | tbb::profiling::set_name(mtx, name); |
66 | |
67 | const int n = 10000; |
68 | tbb::parallel_for( tbb::blocked_range<size_t>(0,n,n/100), WorkEmulator<M>(mtx) ); |
69 | } |
70 | |
71 | #define TEST_MUTEX(type, name) Test<tbb::type>( name ) |
72 | |
73 | #endif /* !DO_ITT_NOTIFY */ |
74 | |
75 | int TestMain () { |
76 | #if DO_ITT_NOTIFY |
77 | for( int p=MinThread; p<=MaxThread; ++p ) { |
78 | REMARK( "testing with %d workers\n" , p ); |
79 | tbb::task_scheduler_init init( p ); |
80 | TEST_MUTEX( spin_mutex, "Spin Mutex" ); |
81 | TEST_MUTEX( queuing_mutex, "Queuing Mutex" ); |
82 | TEST_MUTEX( queuing_rw_mutex, "Queuing RW Mutex" ); |
83 | TEST_MUTEX( spin_rw_mutex, "Spin RW Mutex" ); |
84 | } |
85 | return Harness::Done; |
86 | #else /* !DO_ITT_NOTIFY */ |
87 | return Harness::Skipped; |
88 | #endif /* !DO_ITT_NOTIFY */ |
89 | } |
90 | |