/* VIM: let b:lcppflags="-std=c++11 -O2 -pthread" VIM: let b:wcppflags="/O2 /EHsc /DWIN32" VIM: let b:cppflags=g:Iboost.g:Itbb VIM: let b:ldflags=g:Lboost.g:LtbbD VIM: let b:ldlibpath=g:Bboost.g:Btbb VIM: let b:argv="" */ #include #include #include #include #include #include /* * Conclusion: * The first task_sheduler_init is configuring number of threads in * the thread pool. If the task scheduler initialised implicitly then * the number of threads is the number of cores. To ensure uncomment * the commented line below. */ class ChildTask : public tbb::task { tbb::task * execute() { std::printf( "ChildTask is running.\n" ); return nullptr; } }; class ContTask : public tbb::task { tbb::task * execute() { std::printf( "ContTask is running.\n" ); return nullptr; } }; tbb::task * t; struct RootTask : public tbb::task { tbb::task * execute() { std::printf( "RootTask is running.\n" ); auto& c = *new( allocate_continuation()) ContTask(); t = &c; tbb::task& ctask1 = *new( c.allocate_child() ) ChildTask(); tbb::task& ctask2 = *new( c.allocate_child() ) ChildTask(); c.set_ref_count( 3 ); spawn( ctask1 ); spawn( ctask2 ); std::printf( "RootTask is done.\n" ); return nullptr; } }; int main ( void ) {try{ auto& rtask = *new( tbb::task::allocate_root()) RootTask(); tbb::task::enqueue( rtask ); std::this_thread::sleep_for( std::chrono::seconds(1) ); std::printf( "After sleep.\n" ); tbb::task::spawn( *new (t->allocate_child()) tbb::empty_task() ); std::this_thread::sleep_for( std::chrono::seconds(1) ); std::printf( "After second sleep.\n" ); return 0; } catch ( const std::exception& e ) { std::cerr << std::endl << "std::exception(\"" << e.what() << "\")." << std::endl; return 2; } catch ( ... ) { std::cerr << std::endl << "unknown exception." << std::endl; return 1; }}