Status PerfCounterCollection::addCountersGroupedByInstanceName( StringData name, const std::vector<StringData>& paths) { auto swCounters = checkCounters(name, paths); if (!swCounters.getStatus().isOK()) { return swCounters.getStatus(); } _nestedCounters.emplace(name.toString(), std::move(swCounters.getValue())); return Status::OK(); }
void run_lambdas_test( mode_array *filter_type ) { tbb::atomic<int> counter; counter = max_counter; // Construct filters using lambda-syntax and create the sequence when parallel_pipeline() is being run; resetCounters(); // only need the output_counter reset. tbb::parallel_pipeline( n_tokens, tbb::make_filter<void, t1>(filter_type[0], [&counter]( tbb::flow_control& control ) -> t1 { if( --counter < 0 ) control.stop(); return t1(); } ) & tbb::make_filter<t1, t2>(filter_type[1], []( t1 /*my_storage*/ ) -> t2 { return t2(); } ) & tbb::make_filter<t2, void>(filter_type[2], [] ( t2 ) -> void { output_counter++; } ) ); checkCounters(no_pointer_counts); // don't have to worry about specializations counter = max_counter; // pointer filters resetCounters(); tbb::parallel_pipeline( n_tokens, tbb::make_filter<void, t1*>(filter_type[0], [&counter]( tbb::flow_control& control ) -> t1* { if( --counter < 0 ) { control.stop(); return NULL; } return new(fetchNextBuffer()) t1(); } ) & tbb::make_filter<t1*, t2*>(filter_type[1], []( t1* my_storage ) -> t2* { tbb::tbb_allocator<t1>().destroy(my_storage); // my_storage->~t1(); return new(my_storage) t2(); } ) & tbb::make_filter<t2*, void>(filter_type[2], [] ( t2* my_storage ) -> void { tbb::tbb_allocator<t2>().destroy(my_storage); // my_storage->~t2(); freeBuffer(my_storage); output_counter++; } ) ); checkCounters(no_pointer_counts); // first filter outputs pointer counter = max_counter; resetCounters(); tbb::parallel_pipeline( n_tokens, tbb::make_filter<void, t1*>(filter_type[0], [&counter]( tbb::flow_control& control ) -> t1* { if( --counter < 0 ) { control.stop(); return NULL; } return new(fetchNextBuffer()) t1(); } ) & tbb::make_filter<t1*, t2>(filter_type[1], []( t1* my_storage ) -> t2 { tbb::tbb_allocator<t1>().destroy(my_storage); // my_storage->~t1(); freeBuffer(my_storage); return t2(); } ) & tbb::make_filter<t2, void>(filter_type[2], [] ( t2 /*my_storage*/) -> void { output_counter++; } ) ); checkCounters(no_pointer_counts); // second filter outputs pointer counter = max_counter; resetCounters(); tbb::parallel_pipeline( n_tokens, tbb::make_filter<void, t1>(filter_type[0], [&counter]( tbb::flow_control& control ) -> t1 { if( --counter < 0 ) { control.stop(); } return t1(); } ) & tbb::make_filter<t1, t2*>(filter_type[1], []( t1 /*my_storage*/ ) -> t2* { return new(fetchNextBuffer()) t2(); } ) & tbb::make_filter<t2*, void>(filter_type[2], [] ( t2* my_storage) -> void { tbb::tbb_allocator<t2>().destroy(my_storage); // my_storage->~t2(); freeBuffer(my_storage); output_counter++; } ) ); checkCounters(no_pointer_counts); }
void run_function(const char *l1, const char *l2) { ASSERT(!filter_node_count, NULL); REMARK("Testing < %s, %s >", l1, l2 ); #if __TBB_LAMBDAS_PRESENT REMARK( " ( + lambdas)"); #endif REMARK("\n"); const size_t number_of_filters = 3; input_filter<type1> i_filter; middle_filter<type1, type2> m_filter; output_filter<type2> o_filter; unsigned limit = 1; // Test pipeline that contains number_of_filters filters for( unsigned i=0; i<number_of_filters; ++i) limit *= number_of_filter_types; // Iterate over possible filter sequences for( unsigned numeral=0; numeral<limit; ++numeral ) { unsigned temp = numeral; tbb::filter::mode filter_type[number_of_filter_types]; for( unsigned i=0; i<number_of_filters; ++i, temp/=number_of_filter_types ) filter_type[i] = filter_table[temp%number_of_filter_types]; tbb::filter_t<void, type1> filter1( filter_type[0], i_filter ); tbb::filter_t<type1, type2> filter2( filter_type[1], m_filter ); tbb::filter_t<type2, void> filter3( filter_type[2], o_filter ); ASSERT(filter_node_count==3, "some filter nodes left after previous iteration?"); resetCounters(); // Create filters sequence when parallel_pipeline() is being run tbb::parallel_pipeline( n_tokens, filter1 & filter2 & filter3 ); checkCounters(); // Create filters sequence partially outside parallel_pipeline() and also when parallel_pipeline() is being run tbb::filter_t<void, type2> filter12; filter12 = filter1 & filter2; resetCounters(); tbb::parallel_pipeline( n_tokens, filter12 & filter3 ); checkCounters(); tbb::filter_t<void, void> filter123 = filter12 & filter3; // Run pipeline twice with the same filter sequence for( unsigned i = 0; i<2; i++ ) { resetCounters(); tbb::parallel_pipeline( n_tokens, filter123 ); checkCounters(); } // Now copy-construct another filter_t instance, and use it to run pipeline { tbb::filter_t<void, void> copy123( filter123 ); resetCounters(); tbb::parallel_pipeline( n_tokens, copy123 ); checkCounters(); } // Construct filters and create the sequence when parallel_pipeline() is being run resetCounters(); tbb::parallel_pipeline( n_tokens, tbb::make_filter<void, type1>(filter_type[0], i_filter) & tbb::make_filter<type1, type2>(filter_type[1], m_filter) & tbb::make_filter<type2, void>(filter_type[2], o_filter) ); checkCounters(); // Construct filters, make a copy, destroy the original filters, and run with the copy int cnt = filter_node_count; { tbb::filter_t<void, void>* p123 = new tbb::filter_t<void,void> ( tbb::make_filter<void, type1>(filter_type[0], i_filter) & tbb::make_filter<type1, type2>(filter_type[1], m_filter) & tbb::make_filter<type2, void>(filter_type[2], o_filter) ); ASSERT(filter_node_count==cnt+5, "filter node accounting error?"); tbb::filter_t<void, void> copy123( *p123 ); delete p123; ASSERT(filter_node_count==cnt+5, "filter nodes deleted prematurely?"); resetCounters(); tbb::parallel_pipeline( n_tokens, copy123 ); checkCounters(); } // construct a filter with temporaries { tbb::filter_t<void, void> my_filter; fill_chain<type1,type2>( my_filter, filter_type, i_filter, m_filter, o_filter ); resetCounters(); tbb::parallel_pipeline( n_tokens, my_filter ); checkCounters(); } ASSERT(filter_node_count==cnt, "scope ended but filter nodes not deleted?"); #if __TBB_LAMBDAS_PRESENT tbb::atomic<int> counter; counter = max_counter; // Construct filters using lambda-syntax and create the sequence when parallel_pipeline() is being run; resetCounters(); // only need the output_counter reset. tbb::parallel_pipeline( n_tokens, tbb::make_filter<void, type1>(filter_type[0], [&counter]( tbb::flow_control& control ) -> type1 { if( --counter < 0 ) control.stop(); return type1(); } ) & tbb::make_filter<type1, type2>(filter_type[1], []( type1 /*my_storage*/ ) -> type2 { return type2(); } ) & tbb::make_filter<type2, void>(filter_type[2], [] ( type2 ) -> void { output_counter++; } ) ); checkCounters(); #endif } ASSERT(!filter_node_count, "filter_node objects leaked"); }
void run_filter_set( input_filter<t1>& i_filter, middle_filter<t1,t2>& m_filter, output_filter<t2>& o_filter, mode_array *filter_type, final_assert_type my_t) { tbb::filter_t<void, t1> filter1( filter_type[0], i_filter ); tbb::filter_t<t1, t2> filter2( filter_type[1], m_filter ); tbb::filter_t<t2, void> filter3( filter_type[2], o_filter ); ASSERT(filter_node_count==3, "some filter nodes left after previous iteration?"); resetCounters(); // Create filters sequence when parallel_pipeline() is being run tbb::parallel_pipeline( n_tokens, filter1 & filter2 & filter3 ); checkCounters(my_t); // Create filters sequence partially outside parallel_pipeline() and also when parallel_pipeline() is being run tbb::filter_t<void, t2> filter12; filter12 = filter1 & filter2; resetCounters(); tbb::parallel_pipeline( n_tokens, filter12 & filter3 ); checkCounters(my_t); tbb::filter_t<void, void> filter123 = filter12 & filter3; // Run pipeline twice with the same filter sequence for( unsigned i = 0; i<2; i++ ) { resetCounters(); tbb::parallel_pipeline( n_tokens, filter123 ); checkCounters(my_t); } // Now copy-construct another filter_t instance, and use it to run pipeline { tbb::filter_t<void, void> copy123( filter123 ); resetCounters(); tbb::parallel_pipeline( n_tokens, copy123 ); checkCounters(my_t); } // Construct filters and create the sequence when parallel_pipeline() is being run resetCounters(); tbb::parallel_pipeline( n_tokens, tbb::make_filter<void, t1>(filter_type[0], i_filter) & tbb::make_filter<t1, t2>(filter_type[1], m_filter) & tbb::make_filter<t2, void>(filter_type[2], o_filter) ); checkCounters(my_t); // Construct filters, make a copy, destroy the original filters, and run with the copy int cnt = filter_node_count; { tbb::filter_t<void, void>* p123 = new tbb::filter_t<void,void> ( tbb::make_filter<void, t1>(filter_type[0], i_filter) & tbb::make_filter<t1, t2>(filter_type[1], m_filter) & tbb::make_filter<t2, void>(filter_type[2], o_filter) ); ASSERT(filter_node_count==cnt+5, "filter node accounting error?"); tbb::filter_t<void, void> copy123( *p123 ); delete p123; ASSERT(filter_node_count==cnt+5, "filter nodes deleted prematurely?"); resetCounters(); tbb::parallel_pipeline( n_tokens, copy123 ); checkCounters(my_t); } // construct a filter with temporaries { tbb::filter_t<void, void> my_filter; fill_chain<t1,t2>( my_filter, filter_type, i_filter, m_filter, o_filter ); resetCounters(); tbb::parallel_pipeline( n_tokens, my_filter ); checkCounters(my_t); } ASSERT(filter_node_count==cnt, "scope ended but filter nodes not deleted?"); }