int test_parallel(int num_threads) { tbb::flow::graph g; tbb::flow::sequencer_node<T> s(g, seq_inspector<T>()); NativeParallelFor( num_threads, parallel_puts<T>(s, num_threads) ); { touches<T> t( num_threads ); NativeParallelFor( num_threads, parallel_gets<T>(s, num_threads, t) ); g.wait_for_all(); ASSERT( t.validate_touches(), NULL ); } T bogus_value(-1); T j = bogus_value; ASSERT( s.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); tbb::flow::sequencer_node<T> s1(g, seq_inspector<T>()); tbb::flow::sequencer_node<T> s2(g, seq_inspector<T>()); tbb::flow::sequencer_node<T> s3(g, seq_inspector<T>()); tbb::flow::make_edge( s1, s2 ); tbb::flow::make_edge( s2, s3 ); { touches<T> t( num_threads ); tbb::atomic<int> counter; counter = 0; NativeParallelFor( num_threads, parallel_put_get<T>(s1, s3, num_threads, counter, t) ); g.wait_for_all(); t.validate_touches(); } g.wait_for_all(); ASSERT( s1.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( s2.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( s3.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); // test copy constructor tbb::flow::sequencer_node<T> s_copy(s); NativeParallelFor( num_threads, parallel_puts<T>(s_copy, num_threads) ); for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( s_copy, j ); ASSERT( i == j, NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( s_copy.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); return 0; }
int test_reservation(int num_threads) { tbb::graph g; T bogus_value(-1); // Simple tests tbb::queue_node<T> q(g); q.try_put(T(1)); q.try_put(T(2)); q.try_put(T(3)); T v; ASSERT( q.reserve_item(v) == true, NULL ); ASSERT( v == T(1), NULL ); ASSERT( q.release_reservation() == true, NULL ); v = bogus_value; g.wait_for_all(); ASSERT( q.reserve_item(v) == true, NULL ); ASSERT( v == T(1), NULL ); ASSERT( q.consume_reservation() == true, NULL ); v = bogus_value; g.wait_for_all(); ASSERT( q.try_get(v) == true, NULL ); ASSERT( v == T(2), NULL ); v = bogus_value; g.wait_for_all(); ASSERT( q.reserve_item(v) == true, NULL ); ASSERT( v == T(3), NULL ); ASSERT( q.release_reservation() == true, NULL ); v = bogus_value; g.wait_for_all(); ASSERT( q.reserve_item(v) == true, NULL ); ASSERT( v == T(3), NULL ); ASSERT( q.consume_reservation() == true, NULL ); v = bogus_value; g.wait_for_all(); return 0; }
int test_reservation(int num_threads) { tbb::graph g; T bogus_value(-1); // Simple tests tbb::buffer_node<T> b(g); b.try_put(T(1)); b.try_put(T(2)); b.try_put(T(3)); T v, vsum; ASSERT( b.try_reserve(v) == true, NULL ); ASSERT( b.try_release() == true, NULL ); v = bogus_value; g.wait_for_all(); ASSERT( b.try_reserve(v) == true, NULL ); ASSERT( b.try_consume() == true, NULL ); vsum += v; v = bogus_value; g.wait_for_all(); ASSERT( b.try_get(v) == true, NULL ); vsum += v; v = bogus_value; g.wait_for_all(); ASSERT( b.try_reserve(v) == true, NULL ); ASSERT( b.try_release() == true, NULL ); v = bogus_value; g.wait_for_all(); ASSERT( b.try_reserve(v) == true, NULL ); ASSERT( b.try_consume() == true, NULL ); vsum += v; ASSERT( vsum == T(6), NULL); v = bogus_value; g.wait_for_all(); return 0; }
int test_serial() { tbb::graph g; T bogus_value(-1); tbb::buffer_node<T> b(g); tbb::buffer_node<T> b2(g); T j = bogus_value; // // Rejects attempts to add / remove predecessor // Rejects request from empty buffer // ASSERT( b.register_predecessor( b2 ) == false, NULL ); ASSERT( b.remove_predecessor( b2 ) == false, NULL ); ASSERT( b.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); // // Simple puts and gets // for (int i = 0; i < N; ++i) { bool msg = b.try_put( T(i) ); ASSERT( msg == true, NULL ); } T vsum = T(0); for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( b, j ); vsum += j; } ASSERT( vsum == (N*(N-1))/2, NULL); j = bogus_value; g.wait_for_all(); ASSERT( b.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( b.register_successor( b2 ) == true, NULL ); vsum = T(0); for (int i = 0; i < N; ++i) { bool msg = b.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( b2, j ); vsum += j; } ASSERT( vsum == (N*(N-1))/2, NULL); j = bogus_value; g.wait_for_all(); ASSERT( b.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( b2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( b.remove_successor( b2 ) == true, NULL ); ASSERT( b.try_put( 1 ) == true, NULL ); g.wait_for_all(); ASSERT( b2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); ASSERT( b.try_get( j ) == true, NULL ); ASSERT( j == 1, NULL ); tbb::buffer_node<T> b3(g); ASSERT( b.register_successor( b2 ) == true, NULL ); ASSERT( b2.register_successor( b3 ) == true, NULL ); vsum = T(0); for (int i = 0; i < N; ++i) { bool msg = b.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( b3, j ); vsum += j; } ASSERT( vsum == (N*(N-1))/2, NULL); j = bogus_value; g.wait_for_all(); ASSERT( b.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( b2.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( b3.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( b.remove_successor( b2 ) == true, NULL ); ASSERT( b.try_put( 1 ) == true, NULL ); g.wait_for_all(); ASSERT( b2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); ASSERT( b3.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); ASSERT( b.try_get( j ) == true, NULL ); ASSERT( j == 1, NULL ); return 0; }
int test_parallel(int num_threads) { tbb::graph g; tbb::buffer_node<T> b(g); tbb::buffer_node<T> b2(g); tbb::buffer_node<T> b3(g); T bogus_value(-1); T j = bogus_value; NativeParallelFor( num_threads, parallel_puts<T>(b) ); T *next_value = new T[num_threads]; for (int tid = 0; tid < num_threads; ++tid) next_value[tid] = T(0); for (int i = 0; i < num_threads * N; ++i ) { spin_try_get( b, j ); check_item( next_value, j ); j = bogus_value; } for (int tid = 0; tid < num_threads; ++tid) { ASSERT( next_value[tid] == T((N*(N-1))/2), NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( b.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); NativeParallelFor( num_threads, parallel_puts<T>(b) ); { touches< T > t( num_threads ); NativeParallelFor( num_threads, parallel_gets<T>(b, t) ); g.wait_for_all(); ASSERT( t.validate_touches(), NULL ); } j = bogus_value; ASSERT( b.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); { touches< T > t( num_threads ); NativeParallelFor( num_threads, parallel_put_get<T>(b, t) ); g.wait_for_all(); ASSERT( t.validate_touches(), NULL ); } j = bogus_value; ASSERT( b.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( b.register_successor( b2 ) == true, NULL ); ASSERT( b2.register_successor( b3 ) == true, NULL ); NativeParallelFor( num_threads, parallel_puts<T>(b) ); { touches< T > t( num_threads ); NativeParallelFor( num_threads, parallel_gets<T>(b3, t) ); g.wait_for_all(); ASSERT( t.validate_touches(), NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( b.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( b2.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( b3.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); return 0; }
int test_serial() { tbb::flow::graph g; T bogus_value(-1); tbb::flow::sequencer_node<T> s(g, seq_inspector<T>()); tbb::flow::sequencer_node<T> s2(g, seq_inspector<T>()); T j = bogus_value; // // Rejects attempts to add / remove predecessor // Rejects request from empty Q // ASSERT( s.register_predecessor( s2 ) == false, NULL ); ASSERT( s.remove_predecessor( s2 ) == false, NULL ); ASSERT( s.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); // // In-order simple puts and gets // for (int i = 0; i < N; ++i) { bool msg = s.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; ASSERT(wait_try_get( g, s, j ) == true, NULL); ASSERT( i == j, NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( s.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); // // Reverse-order simple puts and gets // for (int i = N-1; i >= 0; --i) { bool msg = s2.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; ASSERT(wait_try_get( g, s2, j ) == true, NULL); ASSERT( i == j, NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( s2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); // // Chained in-order simple puts and gets // tbb::flow::sequencer_node<T> s3(g, seq_inspector<T>()); tbb::flow::sequencer_node<T> s4(g, seq_inspector<T>()); tbb::flow::sequencer_node<T> s5(g, seq_inspector<T>()); tbb::flow::make_edge( s3, s4 ); tbb::flow::make_edge( s4, s5 ); for (int i = 0; i < N; ++i) { bool msg = s3.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; ASSERT(wait_try_get( g, s5, j ) == true, NULL); ASSERT( i == j, NULL ); } j = bogus_value; ASSERT( wait_try_get( g, s3, j ) == false, NULL ); ASSERT( wait_try_get( g, s4, j ) == false, NULL ); ASSERT( wait_try_get( g, s5, j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); tbb::flow::remove_edge( s3, s4 ); ASSERT( s3.try_put( N ) == true, NULL ); ASSERT( wait_try_get( g, s4, j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( wait_try_get( g, s5, j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( wait_try_get( g, s3, j ) == true, NULL ); ASSERT( j == N, NULL ); // // Chained reverse-order simple puts and gets // tbb::flow::sequencer_node<T> s6(g, seq_inspector<T>()); tbb::flow::sequencer_node<T> s7(g, seq_inspector<T>()); tbb::flow::sequencer_node<T> s8(g, seq_inspector<T>()); tbb::flow::make_edge( s6, s7 ); tbb::flow::make_edge( s7, s8 ); for (int i = N-1; i >= 0; --i) { bool msg = s6.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; ASSERT( wait_try_get( g, s8, j ) == true, NULL ); ASSERT( i == j, NULL ); } j = bogus_value; ASSERT( wait_try_get( g, s6, j ) == false, NULL ); ASSERT( wait_try_get( g, s7, j ) == false, NULL ); ASSERT( wait_try_get( g, s8, j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); tbb::flow::remove_edge( s6, s7 ); ASSERT( s6.try_put( N ) == true, NULL ); ASSERT( wait_try_get( g, s7, j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( wait_try_get( g, s8, j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( wait_try_get( g, s6, j ) == true, NULL ); ASSERT( j == N, NULL ); return 0; }
int test_serial() { tbb::graph g; T bogus_value(-1); tbb::queue_node<T> q(g); tbb::queue_node<T> q2(g); T j = bogus_value; // // Rejects attempts to add / remove predecessor // Rejects request from empty Q // ASSERT( q.register_predecessor( q2 ) == false, NULL ); ASSERT( q.remove_predecessor( q2 ) == false, NULL ); ASSERT( q.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); // // Simple puts and gets // for (int i = 0; i < N; ++i) { bool msg = q.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( q, j ); ASSERT( i == j, NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( q.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( q.register_successor( q2 ) == true, NULL ); for (int i = 0; i < N; ++i) { bool msg = q.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( q2, j ); ASSERT( i == j, NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( q.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( q2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( q.remove_successor( q2 ) == true, NULL ); ASSERT( q.try_put( 1 ) == true, NULL ); g.wait_for_all(); ASSERT( q2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); ASSERT( q.try_get( j ) == true, NULL ); ASSERT( j == 1, NULL ); tbb::queue_node<T> q3(g); ASSERT( q.register_successor( q2 ) == true, NULL ); ASSERT( q2.register_successor( q3 ) == true, NULL ); for (int i = 0; i < N; ++i) { bool msg = q.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( q3, j ); ASSERT( i == j, NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( q.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( q2.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( q3.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( q.remove_successor( q2 ) == true, NULL ); ASSERT( q.try_put( 1 ) == true, NULL ); g.wait_for_all(); ASSERT( q2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); ASSERT( q3.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); ASSERT( q.try_get( j ) == true, NULL ); ASSERT( j == 1, NULL ); return 0; }
int test_parallel(int num_threads) { tbb::graph g; tbb::queue_node<T> q(g); tbb::queue_node<T> q2(g); tbb::queue_node<T> q3(g); T bogus_value(-1); T j = bogus_value; NativeParallelFor( num_threads, parallel_puts<T>(q) ); T *next_value = new T[num_threads]; for (int tid = 0; tid < num_threads; ++tid) next_value[tid] = T(0); for (int i = 0; i < num_threads * N; ++i ) { spin_try_get( q, j ); check_item( next_value, j ); j = bogus_value; } for (int tid = 0; tid < num_threads; ++tid) { ASSERT( next_value[tid] == T(N), NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( q.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); NativeParallelFor( num_threads, parallel_puts<T>(q) ); { touches< T > t( num_threads ); NativeParallelFor( num_threads, parallel_gets<T>(q, t) ); g.wait_for_all(); ASSERT( t.validate_touches(), NULL ); } j = bogus_value; ASSERT( q.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); { touches< T > t2( num_threads ); NativeParallelFor( num_threads, parallel_put_get<T>(q, t2) ); g.wait_for_all(); ASSERT( t2.validate_touches(), NULL ); } j = bogus_value; ASSERT( q.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( q.register_successor( q2 ) == true, NULL ); ASSERT( q2.register_successor( q3 ) == true, NULL ); NativeParallelFor( num_threads, parallel_puts<T>(q) ); { touches< T > t3( num_threads ); NativeParallelFor( num_threads, parallel_gets<T>(q3, t3) ); g.wait_for_all(); ASSERT( t3.validate_touches(), NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( q.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( q2.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( q3.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); return 0; }
int test_serial() { tbb::flow::graph g; tbb::flow::queue_node<T> q(g); tbb::flow::queue_node<T> q2(g); { // destroy the graph after manipulating it, and see if all the items in the buffers // have been destroyed before the graph Check<T> my_check; // if check_type< U > count constructions and destructions T bogus_value(-1); T j = bogus_value; // // Rejects attempts to add / remove predecessor // Rejects request from empty Q // ASSERT( q.register_predecessor( q2 ) == false, NULL ); ASSERT( q.remove_predecessor( q2 ) == false, NULL ); ASSERT( q.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); // // Simple puts and gets // for (int i = 0; i < N; ++i) { bool msg = q.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( q, j ); ASSERT( i == j, NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( q.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); tbb::flow::make_edge( q, q2 ); for (int i = 0; i < N; ++i) { bool msg = q.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( q2, j ); ASSERT( i == j, NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( q.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( q2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); tbb::flow::remove_edge( q, q2 ); ASSERT( q.try_put( 1 ) == true, NULL ); g.wait_for_all(); ASSERT( q2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); ASSERT( q.try_get( j ) == true, NULL ); ASSERT( j == 1, NULL ); tbb::flow::queue_node<T> q3(g); tbb::flow::make_edge( q, q2 ); tbb::flow::make_edge( q2, q3 ); for (int i = 0; i < N; ++i) { bool msg = q.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( q3, j ); ASSERT( i == j, NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( q.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( q2.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( q3.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); tbb::flow::remove_edge( q, q2 ); ASSERT( q.try_put( 1 ) == true, NULL ); g.wait_for_all(); ASSERT( q2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); ASSERT( q3.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); ASSERT( q.try_get( j ) == true, NULL ); ASSERT( j == 1, NULL ); } return 0; }