diff --git a/CMakeLists.txt b/CMakeLists.txt index cb7c732..a3e26d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,9 +99,9 @@ endif() message(" (set with command line option -DWARNINGS_ARE_ERRORS=ON/OFF)") if (USE_AUTOMATIC_INITIALIZATION STREQUAL ON) - message("-- MTAPI/Tasks automatic initialization enabled (default)") + message("-- MTAPI automatic initialization enabled (default)") else() - message("-- MTAPI/Tasks automatic initialization disabled") + message("-- MTAPI automatic initialization disabled") endif() message(" (set with command line option -DUSE_AUTOMATIC_INITIALIZATION=ON/OFF)") @@ -146,7 +146,6 @@ set(EXPECTED_EMBB_TEST_EXECUTABLES "embb_algorithms_cpp_test" "embb_mtapi_c_test" "embb_mtapi_cpp_test" "embb_mtapi_network_c_test" - "embb_tasks_cpp_test" ) # if opencl is there, we also expect the mtapi opencl test to be generated @@ -189,7 +188,6 @@ add_subdirectory(mtapi_plugins_c/mtapi_network_c) if(BUILD_OPENCL_PLUGIN STREQUAL ON) add_subdirectory(mtapi_plugins_c/mtapi_opencl_c) endif() -add_subdirectory(tasks_cpp) add_subdirectory(mtapi_cpp) add_subdirectory(containers_cpp) add_subdirectory(algorithms_cpp) diff --git a/README.md b/README.md index 9afe806..0d13ae0 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Subscription: Contact: - embb.info@gmail.com or - - tobias.schuele@siemens.com + - tobias.schuele@siemens.com, sebnem.rusitschka@siemens.com License @@ -100,7 +100,6 @@ Currently, EMBĀ² contains the following components: - base: base_c, base_cpp - mtapi: mtapi_c, mtapi_cpp and mtapi_plugins_c (mtapi_network_c and mtapi_opencl_c) - - tasks: tasks_cpp - algorithms: algorithms_cpp - dataflow: dataflow_cpp - containers: containers_cpp @@ -114,10 +113,9 @@ implemented in C. Component base_cpp is mainly a C++ wrapper around the base_c functions. Component mtapi_c is a task scheduler written in C and mtapi_cpp a C++ wrapper for the scheduler (mtapi_network_c and mtapi_opencl_c are scheduler plugins for distributed and OpenCL-based heterogeneous systems, respectively). -To simplify programming of homogeneous systems, tasks_cpp contains abstractions -to the MTAPI interfaces. Component algorithms_cpp provides high-level constructs -for typical parallelization tasks in C++, and dataflow_cpp generic skeletons for -the development of parallel stream-based applications. Finally, containers_cpp +Component algorithms_cpp provides high-level constructs for typical +parallelization tasks in C++, and dataflow_cpp generic skeletons for the +development of parallel stream-based applications. Finally, containers_cpp provides data structures for storing objects in a thread-safe way. @@ -370,6 +368,10 @@ Important Notes performance measurements, explicit initialization is strongly recommended since the measurements will otherwise include the initialization time of MTAPI. +- When using ThreadSanitizer there is a bug that causes the built-in CMake type + size determination to fail which in turn leads to a broken configuration. + Therefore, you have to do a normal build first and then rerun CMake with + flags and libs configured for ThreadSanitizer. Links diff --git a/algorithms_cpp/CMakeLists.txt b/algorithms_cpp/CMakeLists.txt index 5378bd3..8bd7cc4 100644 --- a/algorithms_cpp/CMakeLists.txt +++ b/algorithms_cpp/CMakeLists.txt @@ -17,18 +17,18 @@ include_directories(${EMBB_ALGORITHMS_CPP_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/../base_cpp/include ${CMAKE_CURRENT_BINARY_DIR}/../base_cpp/include ${CMAKE_CURRENT_SOURCE_DIR}/../mtapi_c/include - ${CMAKE_CURRENT_SOURCE_DIR}/../tasks_cpp/include - ${CMAKE_CURRENT_BINARY_DIR}/../tasks_cpp/include) + ${CMAKE_CURRENT_SOURCE_DIR}/../mtapi_cpp/include + ${CMAKE_CURRENT_BINARY_DIR}/../mtapi_cpp/include) add_library(embb_algorithms_cpp ${EMBB_ALGORITHMS_CPP_SOURCES} ${EMBB_ALGORITHMS_CPP_HEADERS}) -target_link_libraries(embb_algorithms_cpp embb_tasks_cpp) +target_link_libraries(embb_algorithms_cpp embb_mtapi_cpp) if (BUILD_TESTS STREQUAL ON) include_directories(${CMAKE_CURRENT_BINARY_DIR}/../partest/include) add_executable (embb_algorithms_cpp_test ${EMBB_ALGORITHMS_CPP_TEST_SOURCES}) target_link_libraries(embb_algorithms_cpp_test embb_algorithms_cpp - embb_tasks_cpp embb_mtapi_c partest embb_base_cpp + embb_mtapi_cpp embb_mtapi_c partest embb_base_cpp embb_base_c ${compiler_libs}) CopyBin(BIN embb_algorithms_cpp_test DEST ${local_install_dir}) endif() @@ -36,3 +36,8 @@ endif() install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/embb DESTINATION include FILES_MATCHING PATTERN "*.h") install(TARGETS embb_algorithms_cpp DESTINATION lib) +if (MSVC) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Debug/embb_algorithms_cpp.pdb + DESTINATION lib + CONFIGURATIONS Debug) +endif() diff --git a/algorithms_cpp/include/embb/algorithms/count.h b/algorithms_cpp/include/embb/algorithms/count.h index 6016687..7bbe581 100644 --- a/algorithms_cpp/include/embb/algorithms/count.h +++ b/algorithms_cpp/include/embb/algorithms/count.h @@ -27,7 +27,7 @@ #ifndef EMBB_ALGORITHMS_COUNT_H_ #define EMBB_ALGORITHMS_COUNT_H_ -#include +#include #include namespace embb { @@ -132,7 +132,7 @@ typename std::iterator_traits::difference_type Count( RAI first, RAI last, const ValueType& value, - const embb::tasks::ExecutionPolicy& policy, + const embb::mtapi::ExecutionPolicy& policy, size_t block_size ); @@ -145,7 +145,7 @@ typename std::iterator_traits::difference_type Count( RAI last, const ValueType& value ) { - return Count(first, last, value, embb::tasks::ExecutionPolicy(), 0); + return Count(first, last, value, embb::mtapi::ExecutionPolicy(), 0); } /** @@ -156,7 +156,7 @@ typename std::iterator_traits::difference_type Count( RAI first, RAI last, const ValueType& value, - const embb::tasks::ExecutionPolicy& policy + const embb::mtapi::ExecutionPolicy& policy ) { return Count(first, last, value, policy, 0); } @@ -169,7 +169,7 @@ typename std::iterator_traits::difference_type CountIf( RAI first, RAI last, ComparisonFunction comparison, - const embb::tasks::ExecutionPolicy& policy, + const embb::mtapi::ExecutionPolicy& policy, size_t block_size ); @@ -182,7 +182,7 @@ typename std::iterator_traits::difference_type CountIf( RAI last, ComparisonFunction comparison ) { - return CountIf(first, last, comparison, embb::tasks::ExecutionPolicy(), 0); + return CountIf(first, last, comparison, embb::mtapi::ExecutionPolicy(), 0); } /** @@ -193,7 +193,7 @@ typename std::iterator_traits::difference_type CountIf( RAI first, RAI last, ComparisonFunction comparison, - const embb::tasks::ExecutionPolicy& policy + const embb::mtapi::ExecutionPolicy& policy ) { return CountIf(first, last, comparison, policy, 0); } diff --git a/algorithms_cpp/include/embb/algorithms/for_each.h b/algorithms_cpp/include/embb/algorithms/for_each.h index 54e57a0..7dc4c65 100644 --- a/algorithms_cpp/include/embb/algorithms/for_each.h +++ b/algorithms_cpp/include/embb/algorithms/for_each.h @@ -27,7 +27,7 @@ #ifndef EMBB_ALGORITHMS_FOR_EACH_H_ #define EMBB_ALGORITHMS_FOR_EACH_H_ -#include +#include namespace embb { namespace algorithms { @@ -88,7 +88,7 @@ void ForEach( RAI first, RAI last, Function unary, - const embb::tasks::ExecutionPolicy& policy, + const embb::mtapi::ExecutionPolicy& policy, size_t block_size ); @@ -101,7 +101,7 @@ void ForEach( RAI last, Function unary ) { - ForEach(first, last, unary, embb::tasks::ExecutionPolicy(), 0); + ForEach(first, last, unary, embb::mtapi::ExecutionPolicy(), 0); } /** @@ -112,7 +112,7 @@ void ForEach( RAI first, RAI last, Function unary, - const embb::tasks::ExecutionPolicy& policy + const embb::mtapi::ExecutionPolicy& policy ) { ForEach(first, last, unary, policy, 0); } diff --git a/algorithms_cpp/include/embb/algorithms/internal/count-inl.h b/algorithms_cpp/include/embb/algorithms/internal/count-inl.h index dd11e38..ffef411 100644 --- a/algorithms_cpp/include/embb/algorithms/internal/count-inl.h +++ b/algorithms_cpp/include/embb/algorithms/internal/count-inl.h @@ -83,7 +83,7 @@ class FunctionComparisonFunction{ template typename std::iterator_traits::difference_type Count(RAI first, RAI last, const ValueType& value, - const embb::tasks::ExecutionPolicy& policy, size_t block_size) { + const embb::mtapi::ExecutionPolicy& policy, size_t block_size) { typedef typename std::iterator_traits::difference_type Difference; return Reduce(first, last, Difference(0), std::plus(), internal::ValueComparisonFunction(value), policy, @@ -93,7 +93,7 @@ typename std::iterator_traits::difference_type template typename std::iterator_traits::difference_type CountIf(RAI first, RAI last, ComparisonFunction comparison, - const embb::tasks::ExecutionPolicy& policy, size_t block_size) { + const embb::mtapi::ExecutionPolicy& policy, size_t block_size) { typedef typename std::iterator_traits::difference_type Difference; return Reduce(first, last, Difference(0), std::plus(), internal::FunctionComparisonFunction diff --git a/algorithms_cpp/include/embb/algorithms/internal/for_each-inl.h b/algorithms_cpp/include/embb/algorithms/internal/for_each-inl.h index 8a4457a..d20ad82 100644 --- a/algorithms_cpp/include/embb/algorithms/internal/for_each-inl.h +++ b/algorithms_cpp/include/embb/algorithms/internal/for_each-inl.h @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include @@ -46,13 +46,13 @@ class ForEachFunctor { * Constructs a for-each functor with arguments. */ ForEachFunctor(size_t chunk_first, size_t chunk_last, Function unary, - const embb::tasks::ExecutionPolicy& policy, + const embb::mtapi::ExecutionPolicy& policy, const BlockSizePartitioner& partitioner) : chunk_first_(chunk_first), chunk_last_(chunk_last), unary_(unary), policy_(policy), partitioner_(partitioner) { } - void Action(embb::tasks::TaskContext&) { + void Action(embb::mtapi::TaskContext&) { if (chunk_first_ == chunk_last_) { // Leaf case, recursed to single chunk. Do work on chunk: ChunkDescriptor chunk = partitioner_[chunk_first_]; @@ -71,14 +71,13 @@ class ForEachFunctor { self_t functor_r(chunk_split_index + 1, chunk_last_, unary_, policy_, partitioner_); - embb::tasks::Task task_l = embb::tasks::Node::GetInstance().Spawn( - embb::tasks::Action( - base::MakeFunction(functor_l, &self_t::Action), - policy_)); - embb::tasks::Task task_r = embb::tasks::Node::GetInstance().Spawn( - embb::tasks::Action( - base::MakeFunction(functor_r, &self_t::Action), - policy_)); + embb::mtapi::Node& node = embb::mtapi::Node::GetInstance(); + embb::mtapi::Task task_l = node.Start( + embb::base::MakeFunction(functor_l, &self_t::Action), + policy_); + embb::mtapi::Task task_r = node.Start( + embb::base::MakeFunction(functor_r, &self_t::Action), + policy_); task_l.Wait(MTAPI_INFINITE); task_r.Wait(MTAPI_INFINITE); } @@ -91,7 +90,7 @@ class ForEachFunctor { size_t chunk_first_; size_t chunk_last_; Function unary_; - const embb::tasks::ExecutionPolicy& policy_; + const embb::mtapi::ExecutionPolicy& policy_; const BlockSizePartitioner& partitioner_; /** @@ -102,7 +101,7 @@ class ForEachFunctor { template void ForEachRecursive(RAI first, RAI last, Function unary, - const embb::tasks::ExecutionPolicy& policy, size_t block_size) { + const embb::mtapi::ExecutionPolicy& policy, size_t block_size) { typedef typename std::iterator_traits::difference_type difference_type; difference_type distance = std::distance(first, last); if (distance == 0) { @@ -114,7 +113,7 @@ void ForEachRecursive(RAI first, RAI last, Function unary, if (num_cores == 0) { EMBB_THROW(embb::base::ErrorException, "No cores in execution policy"); } - embb::tasks::Node& node = embb::tasks::Node::GetInstance(); + embb::mtapi::Node& node = embb::mtapi::Node::GetInstance(); // Determine actually used block size if (block_size == 0) { block_size = (static_cast(distance) / num_cores); @@ -129,19 +128,19 @@ void ForEachRecursive(RAI first, RAI last, Function unary, } BlockSizePartitioner partitioner(first, last, block_size); - ForEachFunctor functor(0, - partitioner.Size() - 1, - unary, policy, partitioner); - embb::tasks::Task task = node.Spawn(embb::tasks::Action( - base::MakeFunction(functor, - &ForEachFunctor::Action), - policy)); + typedef ForEachFunctor functor_t; + functor_t functor(0, + partitioner.Size() - 1, + unary, policy, partitioner); + embb::mtapi::Task task = node.Start( + embb::base::MakeFunction(functor, &functor_t::Action), + policy); task.Wait(MTAPI_INFINITE); } template void ForEachIteratorCheck(RAI first, RAI last, Function unary, - const embb::tasks::ExecutionPolicy& policy, size_t block_size, + const embb::mtapi::ExecutionPolicy& policy, size_t block_size, std::random_access_iterator_tag) { return ForEachRecursive(first, last, unary, policy, block_size); } @@ -150,7 +149,7 @@ void ForEachIteratorCheck(RAI first, RAI last, Function unary, template void ForEach(RAI first, const RAI last, Function unary, - const embb::tasks::ExecutionPolicy& policy, size_t block_size) { + const embb::mtapi::ExecutionPolicy& policy, size_t block_size) { typename std::iterator_traits::iterator_category category; internal::ForEachIteratorCheck(first, last, unary, policy, block_size, category); diff --git a/algorithms_cpp/include/embb/algorithms/internal/merge_sort-inl.h b/algorithms_cpp/include/embb/algorithms/internal/merge_sort-inl.h index f278811..39afd79 100644 --- a/algorithms_cpp/include/embb/algorithms/internal/merge_sort-inl.h +++ b/algorithms_cpp/include/embb/algorithms/internal/merge_sort-inl.h @@ -32,7 +32,7 @@ #include #include -#include +#include #include namespace embb { @@ -50,7 +50,7 @@ class MergeSortFunctor { MergeSortFunctor(size_t chunk_first, size_t chunk_last, RAITemp temporary_first, ComparisonFunction comparison, - const embb::tasks::ExecutionPolicy& policy, + const embb::mtapi::ExecutionPolicy& policy, const BlockSizePartitioner& partitioner, const RAI& global_first, int depth) : chunk_first_(chunk_first), chunk_last_(chunk_last), @@ -59,7 +59,7 @@ class MergeSortFunctor { global_first_(global_first), depth_(depth) { } - void Action(embb::tasks::TaskContext&) { + void Action(embb::mtapi::TaskContext&) { size_t chunk_split_index = (chunk_first_ + chunk_last_) / 2; if (chunk_first_ == chunk_last_) { // Leaf case: recurse into a single chunk's elements: @@ -77,15 +77,13 @@ class MergeSortFunctor { temp_first_, comparison_, policy_, partitioner_, global_first_, depth_ + 1); - embb::tasks::Node& node = embb::tasks::Node::GetInstance(); - embb::tasks::Task task_l = node.Spawn( - embb::tasks::Action( - base::MakeFunction(functor_l, &self_t::Action), - policy_)); - embb::tasks::Task task_r = node.Spawn( - embb::tasks::Action( - base::MakeFunction(functor_r, &self_t::Action), - policy_)); + embb::mtapi::Node& node = embb::mtapi::Node::GetInstance(); + embb::mtapi::Task task_l = node.Start( + base::MakeFunction(functor_l, &self_t::Action), + policy_); + embb::mtapi::Task task_r = node.Start( + base::MakeFunction(functor_r, &self_t::Action), + policy_); task_l.Wait(MTAPI_INFINITE); task_r.Wait(MTAPI_INFINITE); @@ -177,7 +175,7 @@ class MergeSortFunctor { size_t chunk_last_; RAITemp temp_first_; ComparisonFunction comparison_; - const embb::tasks::ExecutionPolicy& policy_; + const embb::mtapi::ExecutionPolicy& policy_; const BlockSizePartitioner& partitioner_; const RAI& global_first_; int depth_; @@ -219,7 +217,7 @@ void MergeSortIteratorCheck( RAI last, RAITemp temporary_first, ComparisonFunction comparison, - const embb::tasks::ExecutionPolicy& policy, + const embb::mtapi::ExecutionPolicy& policy, size_t block_size, std::random_access_iterator_tag ) { @@ -257,10 +255,9 @@ void MergeSortIteratorCheck( partitioner, first, 0); - embb::tasks::Task task = embb::tasks::Node::GetInstance().Spawn( - embb::tasks::Action( - base::MakeFunction(functor, &functor_t::Action), - policy)); + embb::mtapi::Task task = embb::mtapi::Node::GetInstance().Start( + base::MakeFunction(functor, &functor_t::Action), + policy); task.Wait(MTAPI_INFINITE); } @@ -269,7 +266,7 @@ void MergeSortIteratorCheck( template void MergeSort(RAI first, RAI last, RAITemp temporary_first, - ComparisonFunction comparison, const embb::tasks::ExecutionPolicy& policy, + ComparisonFunction comparison, const embb::mtapi::ExecutionPolicy& policy, size_t block_size) { typedef typename std::iterator_traits::iterator_category category; internal::MergeSortIteratorCheck(first, last, temporary_first, comparison, diff --git a/algorithms_cpp/include/embb/algorithms/internal/partition-inl.h b/algorithms_cpp/include/embb/algorithms/internal/partition-inl.h index f1c2bca..61e7cc8 100644 --- a/algorithms_cpp/include/embb/algorithms/internal/partition-inl.h +++ b/algorithms_cpp/include/embb/algorithms/internal/partition-inl.h @@ -93,7 +93,7 @@ ChunkPartitioner::ChunkPartitioner( size_ = amountChunks; } else { // if no concrete chunk size was given, use number of cores - embb::tasks::Node& node = embb::tasks::Node::GetInstance(); + embb::mtapi::Node& node = embb::mtapi::Node::GetInstance(); size_ = node.GetWorkerThreadCount(); } elements_count_ = static_cast(std::distance(first_, last_)); diff --git a/algorithms_cpp/include/embb/algorithms/internal/partition.h b/algorithms_cpp/include/embb/algorithms/internal/partition.h index 948eb28..5688d4f 100644 --- a/algorithms_cpp/include/embb/algorithms/internal/partition.h +++ b/algorithms_cpp/include/embb/algorithms/internal/partition.h @@ -27,7 +27,7 @@ #ifndef EMBB_ALGORITHMS_INTERNAL_PARTITION_H_ #define EMBB_ALGORITHMS_INTERNAL_PARTITION_H_ -#include +#include namespace embb { namespace algorithms { diff --git a/algorithms_cpp/include/embb/algorithms/internal/quick_sort-inl.h b/algorithms_cpp/include/embb/algorithms/internal/quick_sort-inl.h index e87927e..e7cabf8 100644 --- a/algorithms_cpp/include/embb/algorithms/internal/quick_sort-inl.h +++ b/algorithms_cpp/include/embb/algorithms/internal/quick_sort-inl.h @@ -33,7 +33,7 @@ #include #include -#include +#include #include namespace embb { @@ -48,7 +48,7 @@ class QuickSortFunctor { * Constructs a functor. */ QuickSortFunctor(RAI first, RAI last, ComparisonFunction comparison, - const embb::tasks::ExecutionPolicy& policy, size_t block_size) + const embb::mtapi::ExecutionPolicy& policy, size_t block_size) : first_(first), last_(last), comparison_(comparison), policy_(policy), block_size_(block_size) { } @@ -56,7 +56,7 @@ class QuickSortFunctor { /** * MTAPI action function and starting point of the parallel quick sort. */ - void Action(embb::tasks::TaskContext&) { + void Action(embb::mtapi::TaskContext&) { Difference distance = last_ - first_; if (distance <= 1) { return; @@ -68,15 +68,17 @@ class QuickSortFunctor { SerialQuickSort(first_, mid); SerialQuickSort(mid, last_); } else { - embb::tasks::Node& node = embb::tasks::Node::GetInstance(); + embb::mtapi::Node& node = embb::mtapi::Node::GetInstance(); QuickSortFunctor functor_l(first_, mid, comparison_, policy_, block_size_); - embb::tasks::Task task_l = node.Spawn(embb::tasks::Action( - base::MakeFunction(functor_l, &QuickSortFunctor::Action))); + embb::mtapi::Task task_l = node.Start( + base::MakeFunction(functor_l, &QuickSortFunctor::Action), + policy_); QuickSortFunctor functor_r(mid, last_, comparison_, policy_, block_size_); - embb::tasks::Task task_r = node.Spawn(embb::tasks::Action( - base::MakeFunction(functor_r, &QuickSortFunctor::Action))); + embb::mtapi::Task task_r = node.Start( + base::MakeFunction(functor_r, &QuickSortFunctor::Action), + policy_); task_l.Wait(MTAPI_INFINITE); task_r.Wait(MTAPI_INFINITE); } @@ -87,7 +89,7 @@ class QuickSortFunctor { RAI first_; RAI last_; ComparisonFunction comparison_; - const embb::tasks::ExecutionPolicy& policy_; + const embb::mtapi::ExecutionPolicy& policy_; size_t block_size_; typedef typename std::iterator_traits::difference_type Difference; @@ -189,10 +191,10 @@ class QuickSortFunctor { template void QuickSortIteratorCheck(RAI first, RAI last, ComparisonFunction comparison, - const embb::tasks::ExecutionPolicy& policy, + const embb::mtapi::ExecutionPolicy& policy, size_t block_size, std::random_access_iterator_tag) { - embb::tasks::Node& node = embb::tasks::Node::GetInstance(); + embb::mtapi::Node& node = embb::mtapi::Node::GetInstance(); typedef typename std::iterator_traits::difference_type difference_type; difference_type distance = std::distance(first, last); if (distance == 0) { @@ -215,8 +217,10 @@ void QuickSortIteratorCheck(RAI first, RAI last, } QuickSortFunctor functor( first, last, comparison, policy, block_size); - embb::tasks::Task task = node.Spawn(embb::tasks::Action(base::MakeFunction( - functor, &QuickSortFunctor::Action))); + embb::mtapi::Task task = node.Start( + embb::base::MakeFunction(functor, + &QuickSortFunctor::Action), + policy); task.Wait(MTAPI_INFINITE); } @@ -224,7 +228,7 @@ void QuickSortIteratorCheck(RAI first, RAI last, template void QuickSort(RAI first, RAI last, ComparisonFunction comparison, - const embb::tasks::ExecutionPolicy& policy, size_t block_size) { + const embb::mtapi::ExecutionPolicy& policy, size_t block_size) { typedef typename std::iterator_traits::iterator_category category; internal::QuickSortIteratorCheck(first, last, comparison, policy, block_size, category()); diff --git a/algorithms_cpp/include/embb/algorithms/internal/reduce-inl.h b/algorithms_cpp/include/embb/algorithms/internal/reduce-inl.h index 28c35ab..ba9d724 100644 --- a/algorithms_cpp/include/embb/algorithms/internal/reduce-inl.h +++ b/algorithms_cpp/include/embb/algorithms/internal/reduce-inl.h @@ -27,7 +27,7 @@ #ifndef EMBB_ALGORITHMS_INTERNAL_REDUCE_INL_H_ #define EMBB_ALGORITHMS_INTERNAL_REDUCE_INL_H_ -#include +#include #include #include @@ -46,7 +46,7 @@ class ReduceFunctor { ReturnType neutral, ReductionFunction reduction, TransformationFunction transformation, - const embb::tasks::ExecutionPolicy& policy, + const embb::mtapi::ExecutionPolicy& policy, const BlockSizePartitioner& partitioner, ReturnType& result) : chunk_first_(chunk_first), chunk_last_(chunk_last), neutral_(neutral), @@ -54,7 +54,7 @@ class ReduceFunctor { partitioner_(partitioner), result_(result) { } - void Action(embb::tasks::TaskContext&) { + void Action(embb::mtapi::TaskContext&) { if (chunk_first_ == chunk_last_) { // Leaf case, recursed to single chunk. Do work on chunk: ChunkDescriptor chunk = partitioner_[chunk_first_]; @@ -81,16 +81,12 @@ class ReduceFunctor { neutral_, reduction_, transformation_, policy_, partitioner_, result_r); - embb::tasks::Task task_l = embb::tasks::Node::GetInstance().Spawn( - embb::tasks::Action( - base::MakeFunction( - functor_l, &self_t::Action), - policy_)); - embb::tasks::Task task_r = embb::tasks::Node::GetInstance().Spawn( - embb::tasks::Action( - base::MakeFunction( - functor_r, &self_t::Action), - policy_)); + embb::mtapi::Task task_l = embb::mtapi::Node::GetInstance().Start( + base::MakeFunction(functor_l, &self_t::Action), + policy_); + embb::mtapi::Task task_r = embb::mtapi::Node::GetInstance().Start( + base::MakeFunction(functor_r, &self_t::Action), + policy_); task_l.Wait(MTAPI_INFINITE); task_r.Wait(MTAPI_INFINITE); result_ = reduction_(result_l, result_r); @@ -108,7 +104,7 @@ class ReduceFunctor { ReturnType neutral_; ReductionFunction reduction_; TransformationFunction transformation_; - const embb::tasks::ExecutionPolicy& policy_; + const embb::mtapi::ExecutionPolicy& policy_; const BlockSizePartitioner& partitioner_; ReturnType& result_; @@ -124,7 +120,7 @@ template::difference_type difference_type; difference_type distance = std::distance(first, last); @@ -137,7 +133,7 @@ ReturnType ReduceRecursive(RAI first, RAI last, ReturnType neutral, if (num_cores == 0) { EMBB_THROW(embb::base::ErrorException, "No cores in execution policy"); } - embb::tasks::Node& node = embb::tasks::Node::GetInstance(); + embb::mtapi::Node& node = embb::mtapi::Node::GetInstance(); // Determine actually used block size if (block_size == 0) { block_size = (static_cast(distance) / num_cores); @@ -162,9 +158,9 @@ ReturnType ReduceRecursive(RAI first, RAI last, ReturnType neutral, policy, partitioner, result); - embb::tasks::Task task = node.Spawn( - embb::tasks::Action(base::MakeFunction( - functor, &Functor::Action), policy)); + embb::mtapi::Task task = node.Start( + base::MakeFunction(functor, &Functor::Action), + policy); task.Wait(MTAPI_INFINITE); return result; } @@ -174,7 +170,7 @@ template::iterator_category category; return internal::ReduceIteratorCheck(first, last, reduction, transformation, diff --git a/algorithms_cpp/include/embb/algorithms/internal/scan-inl.h b/algorithms_cpp/include/embb/algorithms/internal/scan-inl.h index b81022e..5b11f91 100644 --- a/algorithms_cpp/include/embb/algorithms/internal/scan-inl.h +++ b/algorithms_cpp/include/embb/algorithms/internal/scan-inl.h @@ -29,8 +29,8 @@ #include #include -#include -#include +#include +#include #include namespace embb { @@ -44,7 +44,7 @@ class ScanFunctor { ScanFunctor(size_t chunk_first, size_t chunk_last, RAIOut output_iterator, ReturnType neutral, ScanFunction scan, TransformationFunction transformation, - const embb::tasks::ExecutionPolicy& policy, + const embb::mtapi::ExecutionPolicy& policy, const BlockSizePartitioner& partitioner, ReturnType* tree_values, size_t node_id, bool going_down) @@ -55,7 +55,7 @@ class ScanFunctor { node_id_(node_id), parent_value_(neutral), is_first_pass_(going_down) { } - void Action(embb::tasks::TaskContext&) { + void Action(embb::mtapi::TaskContext&) { if (chunk_first_ == chunk_last_) { ChunkDescriptor chunk = partitioner_[chunk_first_]; RAIIn iter_in = chunk.GetFirst(); @@ -104,15 +104,13 @@ class ScanFunctor { functor_r.parent_value_ = functor_l.GetTreeValue() + parent_value_; } // Spawn tasks to recurse: - embb::tasks::Node& node = embb::tasks::Node::GetInstance(); - embb::tasks::Task task_l = node.Spawn( - embb::tasks::Action( - base::MakeFunction(functor_l, &ScanFunctor::Action), - policy_)); - embb::tasks::Task task_r = node.Spawn( - embb::tasks::Action( - base::MakeFunction(functor_r, &ScanFunctor::Action), - policy_)); + embb::mtapi::Node& node = embb::mtapi::Node::GetInstance(); + embb::mtapi::Task task_l = node.Start( + base::MakeFunction(functor_l, &ScanFunctor::Action), + policy_); + embb::mtapi::Task task_r = node.Start( + base::MakeFunction(functor_r, &ScanFunctor::Action), + policy_); // Wait for tasks to complete: task_l.Wait(MTAPI_INFINITE); task_r.Wait(MTAPI_INFINITE); @@ -131,7 +129,7 @@ class ScanFunctor { private: static const int LEFT = 1; static const int RIGHT = 2; - const embb::tasks::ExecutionPolicy& policy_; + const embb::mtapi::ExecutionPolicy& policy_; size_t chunk_first_; size_t chunk_last_; RAIOut output_iterator_; @@ -168,7 +166,7 @@ typename ScanFunction, typename TransformationFunction> void ScanIteratorCheck(RAIIn first, RAIIn last, RAIOut output_iterator, ReturnType neutral, ScanFunction scan, TransformationFunction transformation, - const embb::tasks::ExecutionPolicy& policy, + const embb::mtapi::ExecutionPolicy& policy, size_t block_size, std::random_access_iterator_tag) { typedef typename std::iterator_traits::difference_type difference_type; @@ -199,14 +197,15 @@ void ScanIteratorCheck(RAIIn first, RAIIn last, RAIOut output_iterator, // it creates the tree. typedef ScanFunctor Functor; - embb::tasks::Node& node = embb::tasks::Node::GetInstance(); + embb::mtapi::Node& node = embb::mtapi::Node::GetInstance(); BlockSizePartitioner partitioner_down(first, last, block_size); Functor functor_down(0, partitioner_down.Size() - 1, output_iterator, neutral, scan, transformation, policy, partitioner_down, values, 0, true); - embb::tasks::Task task_down = node.Spawn(embb::tasks::Action( - base::MakeFunction(functor_down, &Functor::Action), policy)); + embb::mtapi::Task task_down = node.Start( + base::MakeFunction(functor_down, &Functor::Action), + policy); task_down.Wait(MTAPI_INFINITE); // Second pass. Gives to each leaf the part of the prefix missing @@ -214,8 +213,9 @@ void ScanIteratorCheck(RAIIn first, RAIIn last, RAIOut output_iterator, Functor functor_up(0, partitioner_up.Size() - 1, output_iterator, neutral, scan, transformation, policy, partitioner_up, values, 0, false); - embb::tasks::Task task_up = node.Spawn(embb::tasks::Action( - base::MakeFunction(functor_up, &Functor::Action), policy)); + embb::mtapi::Task task_up = node.Start( + base::MakeFunction(functor_up, &Functor::Action), + policy); task_up.Wait(MTAPI_INFINITE); } @@ -225,7 +225,7 @@ template void Scan(RAIIn first, RAIIn last, RAIOut output_iterator, ReturnType neutral, ScanFunction scan, TransformationFunction transformation, - const embb::tasks::ExecutionPolicy& policy, size_t block_size) { + const embb::mtapi::ExecutionPolicy& policy, size_t block_size) { typedef typename std::iterator_traits::iterator_category category; internal::ScanIteratorCheck(first, last, output_iterator, neutral, scan, transformation, policy, block_size, category()); diff --git a/algorithms_cpp/include/embb/algorithms/invoke.h b/algorithms_cpp/include/embb/algorithms/invoke.h index ced924f..75aa2c9 100644 --- a/algorithms_cpp/include/embb/algorithms/invoke.h +++ b/algorithms_cpp/include/embb/algorithms/invoke.h @@ -28,7 +28,7 @@ #define EMBB_ALGORITHMS_INVOKE_H_ #include -#include +#include namespace embb { namespace algorithms { @@ -78,8 +78,8 @@ void Invoke( Function2 func2, /**< [in] Second function object to invoke */ ..., - const embb::tasks::ExecutionPolicy & policy - /**< [in] embb::tasks::ExecutionPolicy to use */ + const embb::mtapi::ExecutionPolicy & policy + /**< [in] embb::mtapi::ExecutionPolicy to use */ ); #else // DOXYGEN @@ -98,11 +98,11 @@ class TaskWrapper { */ explicit TaskWrapper( Function function, - const embb::tasks::ExecutionPolicy& policy) + const embb::mtapi::ExecutionPolicy& policy) : function_(function), task_() { - embb::tasks::Action action(embb::base::MakeFunction( - *this, &TaskWrapper::Run), policy); - task_ = embb::tasks::Node::GetInstance().Spawn(action); + task_ = embb::mtapi::Node::GetInstance().Start( + embb::base::MakeFunction(*this, &TaskWrapper::Run), + policy); } /** @@ -114,9 +114,9 @@ class TaskWrapper { private: Function function_; - embb::tasks::Task task_; + embb::mtapi::Task task_; - void Run(embb::tasks::TaskContext&) { + void Run(embb::mtapi::TaskContext&) { function_(); } }; @@ -126,7 +126,7 @@ template void Invoke( Function1 func1, Function2 func2, - const embb::tasks::ExecutionPolicy& policy) { + const embb::mtapi::ExecutionPolicy& policy) { internal::TaskWrapper wrap1(func1, policy); internal::TaskWrapper wrap2(func2, policy); } @@ -136,7 +136,7 @@ void Invoke( Function1 func1, Function2 func2, Function3 func3, - const embb::tasks::ExecutionPolicy& policy) { + const embb::mtapi::ExecutionPolicy& policy) { internal::TaskWrapper wrap1(func1, policy); internal::TaskWrapper wrap2(func2, policy); internal::TaskWrapper wrap3(func3, policy); @@ -149,7 +149,7 @@ template wrap1(func1, policy); internal::TaskWrapper wrap2(func2, policy); internal::TaskWrapper wrap3(func3, policy); @@ -164,7 +164,7 @@ template wrap1(func1, policy); internal::TaskWrapper wrap2(func2, policy); internal::TaskWrapper wrap3(func3, policy); @@ -181,7 +181,7 @@ template wrap1(func1, policy); internal::TaskWrapper wrap2(func2, policy); internal::TaskWrapper wrap3(func3, policy); @@ -201,7 +201,7 @@ template wrap1(func1, policy); internal::TaskWrapper wrap2(func2, policy); internal::TaskWrapper wrap3(func3, policy); @@ -223,7 +223,7 @@ template wrap1(func1, policy); internal::TaskWrapper wrap2(func2, policy); internal::TaskWrapper wrap3(func3, policy); @@ -247,7 +247,7 @@ template wrap1(func1, policy); internal::TaskWrapper wrap2(func2, policy); internal::TaskWrapper wrap3(func3, policy); @@ -274,7 +274,7 @@ template wrap1(func1, policy); internal::TaskWrapper wrap2(func2, policy); internal::TaskWrapper wrap3(func3, policy); @@ -291,14 +291,14 @@ template void Invoke( Function1 func1, Function2 func2) { - Invoke(func1, func2, embb::tasks::ExecutionPolicy()); + Invoke(func1, func2, embb::mtapi::ExecutionPolicy()); } template void Invoke( Function1 func1, Function2 func2, Function3 func3) { - Invoke(func1, func2, func3, embb::tasks::ExecutionPolicy()); + Invoke(func1, func2, func3, embb::mtapi::ExecutionPolicy()); } template -#include +#include #include namespace embb { @@ -149,7 +149,7 @@ void MergeSort( RAI last, RAITemp temporary_first, ComparisonFunction comparison, - const embb::tasks::ExecutionPolicy& policy, + const embb::mtapi::ExecutionPolicy& policy, size_t block_size ); @@ -161,7 +161,7 @@ void MergeSortAllocate( RAI first, RAI last, ComparisonFunction comparison, - const embb::tasks::ExecutionPolicy& policy, + const embb::mtapi::ExecutionPolicy& policy, size_t block_size ) { typedef base::Allocation Alloc; @@ -200,7 +200,7 @@ void MergeSortAllocate( ) { MergeSortAllocate(first, last, std::less::value_type>(), - embb::tasks::ExecutionPolicy(), 0); + embb::mtapi::ExecutionPolicy(), 0); } /** @@ -212,7 +212,7 @@ void MergeSortAllocate( RAI last, ComparisonFunction comparison ) { - MergeSortAllocate(first, last, comparison, embb::tasks::ExecutionPolicy(), 0); + MergeSortAllocate(first, last, comparison, embb::mtapi::ExecutionPolicy(), 0); } /** @@ -223,7 +223,7 @@ void MergeSortAllocate( RAI first, RAI last, ComparisonFunction comparison, - const embb::tasks::ExecutionPolicy& policy + const embb::mtapi::ExecutionPolicy& policy ) { MergeSortAllocate(first, last, comparison, policy, 0); } @@ -239,7 +239,7 @@ void MergeSort( ) { MergeSort(first, last, temporary_first, std::less::value_type>(), - embb::tasks::ExecutionPolicy(), 0); + embb::mtapi::ExecutionPolicy(), 0); } /** @@ -253,7 +253,7 @@ void MergeSort( ComparisonFunction comparison ) { MergeSort(first, last, temporary_first, comparison, - embb::tasks::ExecutionPolicy(), 0); + embb::mtapi::ExecutionPolicy(), 0); } /** @@ -265,7 +265,7 @@ void MergeSort( RAI last, RAITemp temporary_first, ComparisonFunction comparison, - const embb::tasks::ExecutionPolicy& policy + const embb::mtapi::ExecutionPolicy& policy ) { MergeSort(first, last, temporary_first, comparison, policy, 0); } diff --git a/algorithms_cpp/include/embb/algorithms/quick_sort.h b/algorithms_cpp/include/embb/algorithms/quick_sort.h index adefe09..8aea4a9 100644 --- a/algorithms_cpp/include/embb/algorithms/quick_sort.h +++ b/algorithms_cpp/include/embb/algorithms/quick_sort.h @@ -28,7 +28,7 @@ #define EMBB_ALGORITHMS_QUICK_SORT_H_ #include -#include +#include namespace embb { namespace algorithms { @@ -72,7 +72,7 @@ void QuickSort( \c a appears before an element \c b in the sorted range if comparison(a, b) == true. The default value uses the less-than relation. */ - const embb::tasks::ExecutionPolicy& policy = embb::tasks::ExecutionPolicy(), + const embb::mtapi::ExecutionPolicy& policy = embb::mtapi::ExecutionPolicy(), /**< [IN] embb::mtapi::ExecutionPolicy for the quick sort algorithm */ size_t block_size = 0 /**< [IN] Lower bound for partitioning the range of elements into blocks that @@ -95,7 +95,7 @@ void QuickSort( RAI first, RAI last, ComparisonFunction comparison, - const embb::tasks::ExecutionPolicy& policy, + const embb::mtapi::ExecutionPolicy& policy, size_t block_size ); @@ -109,7 +109,7 @@ void QuickSort( ) { QuickSort(first, last, std::less::value_type>(), - embb::tasks::ExecutionPolicy(), 0); + embb::mtapi::ExecutionPolicy(), 0); } /** @@ -121,7 +121,7 @@ void QuickSort( RAI last, ComparisonFunction comparison ) { - QuickSort(first, last, comparison, embb::tasks::ExecutionPolicy(), 0); + QuickSort(first, last, comparison, embb::mtapi::ExecutionPolicy(), 0); } /** @@ -132,7 +132,7 @@ void QuickSort( RAI first, RAI last, ComparisonFunction comparison, - const embb::tasks::ExecutionPolicy& policy + const embb::mtapi::ExecutionPolicy& policy ) { QuickSort(first, last, comparison, policy, 0); } diff --git a/algorithms_cpp/include/embb/algorithms/reduce.h b/algorithms_cpp/include/embb/algorithms/reduce.h index 1cf5d86..907b2da 100644 --- a/algorithms_cpp/include/embb/algorithms/reduce.h +++ b/algorithms_cpp/include/embb/algorithms/reduce.h @@ -27,7 +27,7 @@ #ifndef EMBB_ALGORITHMS_REDUCE_H_ #define EMBB_ALGORITHMS_REDUCE_H_ -#include +#include #include namespace embb { @@ -113,7 +113,7 @@ ReturnType Reduce( ReturnType neutral, ReductionFunction reduction, TransformationFunction transformation, - const embb::tasks::ExecutionPolicy& policy, + const embb::mtapi::ExecutionPolicy& policy, size_t block_size ); @@ -128,7 +128,7 @@ ReturnType Reduce( ReductionFunction reduction ) { return Reduce(first, last, neutral, reduction, Identity(), - embb::tasks::ExecutionPolicy(), 0); + embb::mtapi::ExecutionPolicy(), 0); } /** @@ -144,7 +144,7 @@ ReturnType Reduce( TransformationFunction transformation ) { return Reduce(first, last, neutral, reduction, transformation, - embb::tasks::ExecutionPolicy(), 0); + embb::mtapi::ExecutionPolicy(), 0); } /** @@ -158,7 +158,7 @@ ReturnType Reduce( ReturnType neutral, ReductionFunction reduction, TransformationFunction transformation, - const embb::tasks::ExecutionPolicy& policy + const embb::mtapi::ExecutionPolicy& policy ) { return Reduce(first, last, neutral, reduction, transformation, policy, 0); } diff --git a/algorithms_cpp/include/embb/algorithms/scan.h b/algorithms_cpp/include/embb/algorithms/scan.h index 11d1315..66fb843 100644 --- a/algorithms_cpp/include/embb/algorithms/scan.h +++ b/algorithms_cpp/include/embb/algorithms/scan.h @@ -27,7 +27,7 @@ #ifndef EMBB_ALGORITHMS_SCAN_H_ #define EMBB_ALGORITHMS_SCAN_H_ -#include +#include #include namespace embb { @@ -121,7 +121,7 @@ void Scan( ReturnType neutral, ScanFunction scan, TransformationFunction transformation, - const embb::tasks::ExecutionPolicy& policy, + const embb::mtapi::ExecutionPolicy& policy, size_t block_size ); @@ -138,7 +138,7 @@ void Scan( ScanFunction scan ) { Scan(first, last, output_iterator, neutral, scan, Identity(), - embb::tasks::ExecutionPolicy(), 0); + embb::mtapi::ExecutionPolicy(), 0); } /** @@ -155,7 +155,7 @@ void Scan( TransformationFunction transformation ) { Scan(first, last, output_iterator, neutral, scan, transformation, - embb::tasks::ExecutionPolicy(), 0); + embb::mtapi::ExecutionPolicy(), 0); } /** @@ -170,7 +170,7 @@ void Scan( ReturnType neutral, ScanFunction scan, TransformationFunction transformation, - const embb::tasks::ExecutionPolicy& policy + const embb::mtapi::ExecutionPolicy& policy ) { Scan(first, last, output_iterator, neutral, scan, transformation, policy, 0); } diff --git a/algorithms_cpp/test/count_test.cc b/algorithms_cpp/test/count_test.cc index 6678383..27395ca 100644 --- a/algorithms_cpp/test/count_test.cc +++ b/algorithms_cpp/test/count_test.cc @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include @@ -122,7 +122,7 @@ void CountTest::TestBlockSizes() { void CountTest::TestPolicy() { using embb::algorithms::Count; - using embb::tasks::ExecutionPolicy; + using embb::mtapi::ExecutionPolicy; int a[] = { 10, 20, 30, 30, 20, 10, 10, 20, 20, 20 }; std::vector vector(a, a + (sizeof a / sizeof a[0])); PT_EXPECT_EQ(Count(vector.begin(), vector.end(), 10, ExecutionPolicy()), 3); @@ -134,7 +134,7 @@ void CountTest::TestPolicy() { void CountTest::StressTest() { using embb::algorithms::Count; - size_t count = embb::tasks::Node::GetInstance().GetCoreCount() * 10; + size_t count = embb::mtapi::Node::GetInstance().GetCoreCount() * 10; std::vector large_vector(count); for (size_t i = 0; i < count; i++) { large_vector[i] = static_cast(0); diff --git a/algorithms_cpp/test/for_each_test.cc b/algorithms_cpp/test/for_each_test.cc index b42179e..28f85e3 100644 --- a/algorithms_cpp/test/for_each_test.cc +++ b/algorithms_cpp/test/for_each_test.cc @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include @@ -166,7 +166,7 @@ void ForEachTest::TestRanges() { void ForEachTest::TestBlockSizes() { using embb::algorithms::ForEach; - using embb::tasks::ExecutionPolicy; + using embb::mtapi::ExecutionPolicy; size_t count = 4; std::vector init(count); std::vector vector(count); @@ -186,7 +186,7 @@ void ForEachTest::TestBlockSizes() { void ForEachTest::TestPolicy() { using embb::algorithms::ForEach; - using embb::tasks::ExecutionPolicy; + using embb::mtapi::ExecutionPolicy; size_t count = 4; std::vector init(count); std::vector vector(count); @@ -240,8 +240,8 @@ void ForEachTest::TestPolicy() { void ForEachTest::StressTest() { using embb::algorithms::ForEach; - using embb::tasks::ExecutionPolicy; - size_t count = embb::tasks::Node::GetInstance().GetCoreCount() * 10; + using embb::mtapi::ExecutionPolicy; + size_t count = embb::mtapi::Node::GetInstance().GetCoreCount() * 10; std::vector large_vector(count); for (size_t i = 0; i < count; i++) { large_vector[i] = static_cast((i + 2) % 1000); diff --git a/algorithms_cpp/test/invoke_test.cc b/algorithms_cpp/test/invoke_test.cc index 2776ed3..a847e67 100644 --- a/algorithms_cpp/test/invoke_test.cc +++ b/algorithms_cpp/test/invoke_test.cc @@ -61,7 +61,7 @@ void InvokeTest::Test() { Invoke(&Invocable1, &Invocable2, &Invocable3, &Invocable4, &Invocable5, &Invocable6, &Invocable7, &Invocable8, &Invocable9, &Invocable10); - embb::tasks::ExecutionPolicy policy; + embb::mtapi::ExecutionPolicy policy; Invoke(&Invocable1, &Invocable2, policy); Invoke(&Invocable1, &Invocable2, &Invocable3, policy); Invoke(&Invocable1, &Invocable2, &Invocable3, &Invocable4, policy); diff --git a/algorithms_cpp/test/main.cc b/algorithms_cpp/test/main.cc index 0951074..7d84b24 100644 --- a/algorithms_cpp/test/main.cc +++ b/algorithms_cpp/test/main.cc @@ -25,7 +25,7 @@ */ #include -#include +#include #include #include @@ -70,7 +70,7 @@ int compute1_() { PT_MAIN("Algorithms") { embb_atomic_initialize(); - embb::tasks::Node::Initialize(THIS_DOMAIN_ID, THIS_NODE_ID); + embb::mtapi::Node::Initialize(THIS_DOMAIN_ID, THIS_NODE_ID); PT_RUN(PartitionerTest); PT_RUN(ForEachTest); @@ -82,7 +82,7 @@ PT_MAIN("Algorithms") { PT_RUN(MergeSortTest); PT_RUN(InvokeTest); - embb::tasks::Node::Finalize(); + embb::mtapi::Node::Finalize(); PT_EXPECT(embb_get_bytes_allocated() == 0); diff --git a/algorithms_cpp/test/merge_sort_test.cc b/algorithms_cpp/test/merge_sort_test.cc index 43c9dc1..cc87ad7 100644 --- a/algorithms_cpp/test/merge_sort_test.cc +++ b/algorithms_cpp/test/merge_sort_test.cc @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include @@ -50,7 +50,7 @@ MergeSortTest::MergeSortTest() { void MergeSortTest::TestDataStructures() { using embb::algorithms::MergeSortAllocate; - using embb::tasks::ExecutionPolicy; + using embb::mtapi::ExecutionPolicy; int array[kCountSize]; std::vector vector(kCountSize); std::deque deque(kCountSize); @@ -75,7 +75,7 @@ void MergeSortTest::TestDataStructures() { void MergeSortTest::TestFunctionPointers() { using embb::algorithms::MergeSortAllocate; - using embb::tasks::ExecutionPolicy; + using embb::mtapi::ExecutionPolicy; std::vector vector(kCountSize); for (size_t i = kCountSize - 1; i > 0; i--) { @@ -158,7 +158,7 @@ void MergeSortTest::TestRanges() { void MergeSortTest::TestBlockSizes() { using embb::algorithms::MergeSortAllocate; - using embb::tasks::ExecutionPolicy; + using embb::mtapi::ExecutionPolicy; size_t count = 4; std::vector init(count); std::vector vector(count); @@ -181,7 +181,7 @@ void MergeSortTest::TestBlockSizes() { void MergeSortTest::TestPolicy() { using embb::algorithms::MergeSortAllocate; - using embb::tasks::ExecutionPolicy; + using embb::mtapi::ExecutionPolicy; size_t count = 4; std::vector init(count); std::vector vector(count); @@ -242,7 +242,7 @@ void MergeSortTest::TestPolicy() { void MergeSortTest::StressTest() { using embb::algorithms::MergeSortAllocate; - size_t count = embb::tasks::Node::GetInstance().GetCoreCount() * 10; + size_t count = embb::mtapi::Node::GetInstance().GetCoreCount() * 10; std::vector large_vector(count); std::vector vector_copy(count); for (size_t i = count - 1; i > 0; i--) { diff --git a/algorithms_cpp/test/quick_sort_test.cc b/algorithms_cpp/test/quick_sort_test.cc index ef1faba..af3496b 100644 --- a/algorithms_cpp/test/quick_sort_test.cc +++ b/algorithms_cpp/test/quick_sort_test.cc @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include @@ -54,7 +54,7 @@ QuickSortTest::QuickSortTest() { void QuickSortTest::TestDataStructures() { using embb::algorithms::QuickSort; - using embb::tasks::ExecutionPolicy; + using embb::mtapi::ExecutionPolicy; int array[kCountSize]; std::vector vector(kCountSize); @@ -163,7 +163,7 @@ void QuickSortTest::TestRanges() { void QuickSortTest::TestBlockSizes() { using embb::algorithms::QuickSort; - using embb::tasks::ExecutionPolicy; + using embb::mtapi::ExecutionPolicy; size_t count = 4; std::vector init(count); @@ -187,7 +187,7 @@ void QuickSortTest::TestBlockSizes() { void QuickSortTest::TestPolicy() { using embb::algorithms::QuickSort; - using embb::tasks::ExecutionPolicy; + using embb::mtapi::ExecutionPolicy; size_t count = 4; std::vector init(count); std::vector vector(count); @@ -248,7 +248,7 @@ void QuickSortTest::TestPolicy() { void QuickSortTest::StressTest() { using embb::algorithms::QuickSort; - size_t count = embb::tasks::Node::GetInstance().GetCoreCount() * 10; + size_t count = embb::mtapi::Node::GetInstance().GetCoreCount() * 10; std::vector large_vector(count); std::vector vector_copy(count); for (size_t i = 0; i < count; i++) { diff --git a/algorithms_cpp/test/reduce_test.cc b/algorithms_cpp/test/reduce_test.cc index cf66a0a..ed2b68b 100644 --- a/algorithms_cpp/test/reduce_test.cc +++ b/algorithms_cpp/test/reduce_test.cc @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include @@ -163,7 +163,7 @@ void ReduceTest::TestBlockSizes() { void ReduceTest::TestPolicy() { using embb::algorithms::Reduce; - using embb::tasks::ExecutionPolicy; + using embb::mtapi::ExecutionPolicy; using embb::algorithms::Identity; size_t count = 4; int sum = 0; @@ -210,9 +210,9 @@ void ReduceTest::TestPolicy() { void ReduceTest::StressTest() { using embb::algorithms::Reduce; - using embb::tasks::ExecutionPolicy; + using embb::mtapi::ExecutionPolicy; using embb::algorithms::Identity; - size_t count = embb::tasks::Node::GetInstance().GetCoreCount() * 10; + size_t count = embb::mtapi::Node::GetInstance().GetCoreCount() * 10; std::vector large_vector(count); mtapi_int32_t expected = 0; for (size_t i = 0; i < count; i++) { diff --git a/algorithms_cpp/test/scan_test.cc b/algorithms_cpp/test/scan_test.cc index ffab634..ffafd62 100644 --- a/algorithms_cpp/test/scan_test.cc +++ b/algorithms_cpp/test/scan_test.cc @@ -228,7 +228,7 @@ void ScanTest::TestRanges() { void ScanTest::TestBlockSizes() { using embb::algorithms::Scan; - using embb::tasks::ExecutionPolicy; + using embb::mtapi::ExecutionPolicy; using embb::algorithms::Identity; size_t count = 4; std::vector init(count); @@ -253,7 +253,7 @@ void ScanTest::TestBlockSizes() { void ScanTest::TestPolicy() { using embb::algorithms::Scan; - using embb::tasks::ExecutionPolicy; + using embb::mtapi::ExecutionPolicy; using embb::algorithms::Identity; size_t count = 4; std::vector init(count); @@ -324,8 +324,8 @@ void ScanTest::TestPolicy() { void ScanTest::StressTest() { using embb::algorithms::Scan; using embb::algorithms::Identity; - using embb::tasks::ExecutionPolicy; - size_t count = embb::tasks::Node::GetInstance().GetCoreCount() *10; + using embb::mtapi::ExecutionPolicy; + size_t count = embb::mtapi::Node::GetInstance().GetCoreCount() *10; std::vector large_vector(count); std::vector large_vector_output(count); for (size_t i = 0; i < count; i++) { diff --git a/algorithms_cpp/test/zip_iterator_test.cc b/algorithms_cpp/test/zip_iterator_test.cc index 2e67e7c..83a31fe 100644 --- a/algorithms_cpp/test/zip_iterator_test.cc +++ b/algorithms_cpp/test/zip_iterator_test.cc @@ -136,7 +136,7 @@ void ZipIteratorTest::TestZipScan() { Scan(embb::algorithms::Zip(vectorA.begin(), vectorB.begin()), embb::algorithms::Zip(vectorA.end(), vectorB.end()), vectorOut.begin(), 0, std::plus(), DotProductFunctor(), - embb::tasks::ExecutionPolicy(), 0); + embb::mtapi::ExecutionPolicy(), 0); long sum = 0; for (size_t i = 0; i < kCountSize; i++) { diff --git a/base_c/CMakeLists.txt b/base_c/CMakeLists.txt index a05179d..6b2f536 100644 --- a/base_c/CMakeLists.txt +++ b/base_c/CMakeLists.txt @@ -122,3 +122,8 @@ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/embb install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/embb DESTINATION include FILES_MATCHING PATTERN "*.h") install(TARGETS embb_base_c DESTINATION lib) +if (MSVC) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Debug/embb_base_c.pdb + DESTINATION lib + CONFIGURATIONS Debug) +endif() diff --git a/base_c/include/embb/base/c/condition_variable.h b/base_c/include/embb/base/c/condition_variable.h index d707c2b..9d247b5 100644 --- a/base_c/include/embb/base/c/condition_variable.h +++ b/base_c/include/embb/base/c/condition_variable.h @@ -110,6 +110,9 @@ int embb_condition_notify_all( * \threadsafe * \see embb_condition_notify_one(), embb_condition_notify_all(), * embb_condition_wait_until(), embb_condition_wait_for() + * \note It is strongly recommended checking the condition in a loop in order + * to deal with spurious wakeups and situations where another thread has + * locked the mutex between notification and wakeup. */ int embb_condition_wait( embb_condition_t* condition_var, @@ -131,6 +134,9 @@ int embb_condition_wait( * \threadsafe * \see embb_condition_notify_one(), embb_condition_notify_all(), * embb_condition_wait(), embb_condition_wait_for() + * \note It is strongly recommended checking the condition in a loop in order + * to deal with spurious wakeups and situations where another thread has + * locked the mutex between notification and wakeup. */ int embb_condition_wait_until( embb_condition_t* condition_var, @@ -154,6 +160,9 @@ int embb_condition_wait_until( * \threadsafe * \see embb_condition_notify_one(), embb_condition_notify_all(), * embb_condition_wait(), embb_condition_wait_until() + * \note It is strongly recommended checking the condition in a loop in order + * to deal with spurious wakeups and situations where another thread has + * locked the mutex between notification and wakeup. */ int embb_condition_wait_for( embb_condition_t* condition_var, diff --git a/base_cpp/CMakeLists.txt b/base_cpp/CMakeLists.txt index e7cfd27..020e0b4 100644 --- a/base_cpp/CMakeLists.txt +++ b/base_cpp/CMakeLists.txt @@ -46,3 +46,8 @@ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/embb install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/embb DESTINATION include FILES_MATCHING PATTERN "*.h") install(TARGETS embb_base_cpp DESTINATION lib) +if (MSVC) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Debug/embb_base_cpp.pdb + DESTINATION lib + CONFIGURATIONS Debug) +endif() diff --git a/base_cpp/include/embb/base/condition_variable.h b/base_cpp/include/embb/base/condition_variable.h index 50dd37a..42e6c20 100644 --- a/base_cpp/include/embb/base/condition_variable.h +++ b/base_cpp/include/embb/base/condition_variable.h @@ -99,6 +99,10 @@ class ConditionVariable { * \threadsafe * * \see NotifyOne(), NotifyAll() + * + * \note It is strongly recommended checking the condition in a loop in order + * to deal with spurious wakeups and situations where another thread has + * locked the mutex between notification and wakeup. */ void Wait( UniqueLock& lock @@ -118,6 +122,10 @@ class ConditionVariable { * \throws embb::base::ErrorException if an error occurred * * \threadsafe + * + * \note It is strongly recommended checking the condition in a loop in order + * to deal with spurious wakeups and situations where another thread has + * locked the mutex between notification and wakeup. */ bool WaitUntil( UniqueLock& lock, @@ -141,6 +149,10 @@ class ConditionVariable { * \threadsafe * * \tparam Tick Type of tick of the duration. See Duration. + * + * \note It is strongly recommended checking the condition in a loop in order + * to deal with spurious wakeups and situations where another thread has + * locked the mutex between notification and wakeup. */ template bool WaitFor( diff --git a/containers_cpp/CMakeLists.txt b/containers_cpp/CMakeLists.txt index 014d2d3..fdfca25 100644 --- a/containers_cpp/CMakeLists.txt +++ b/containers_cpp/CMakeLists.txt @@ -31,3 +31,8 @@ endif() install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/embb DESTINATION include FILES_MATCHING PATTERN "*.h") install(TARGETS embb_containers_cpp DESTINATION lib) +if (MSVC) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Debug/embb_containers_cpp.pdb + DESTINATION lib + CONFIGURATIONS Debug) +endif() diff --git a/containers_cpp/test/hazard_pointer_test.cc b/containers_cpp/test/hazard_pointer_test.cc index 03d428a..b3c3c94 100644 --- a/containers_cpp/test/hazard_pointer_test.cc +++ b/containers_cpp/test/hazard_pointer_test.cc @@ -74,7 +74,7 @@ int* IntObjectTestPool::Allocate() { } void IntObjectTestPool::Release(int* object_pointer) { - int cell = object_pointer - simplePoolObjects; + int cell = static_cast(object_pointer - simplePoolObjects); simplePool[cell].Store(FREE_MARKER); } diff --git a/containers_cpp/test/main.cc b/containers_cpp/test/main.cc index ce3822a..36bb02f 100644 --- a/containers_cpp/test/main.cc +++ b/containers_cpp/test/main.cc @@ -24,6 +24,15 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include + +#ifdef EMBB_PLATFORM_COMPILER_MSVC +// Suppress warning generated by malloc.h(160): expression before comma +// has no effect: expected expression with side effect +#pragma warning(push) +#pragma warning(disable : 4548) +#endif + #include #include #include @@ -33,6 +42,10 @@ #include #include +#ifdef EMBB_PLATFORM_COMPILER_MSVC +#pragma warning(pop) // Reset warning 4548 +#endif + #include #include diff --git a/dataflow_cpp/CMakeLists.txt b/dataflow_cpp/CMakeLists.txt index 657d4bd..e63f2bf 100644 --- a/dataflow_cpp/CMakeLists.txt +++ b/dataflow_cpp/CMakeLists.txt @@ -17,16 +17,16 @@ include_directories(${EMBB_DATAFLOW_CPP_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/../base_cpp/include ${CMAKE_CURRENT_BINARY_DIR}/../base_cpp/include ${CMAKE_CURRENT_SOURCE_DIR}/../mtapi_c/include - ${CMAKE_CURRENT_SOURCE_DIR}/../tasks_cpp/include - ${CMAKE_CURRENT_BINARY_DIR}/../tasks_cpp/include) + ${CMAKE_CURRENT_SOURCE_DIR}/../mtapi_cpp/include + ${CMAKE_CURRENT_BINARY_DIR}/../mtapi_cpp/include) add_library (embb_dataflow_cpp ${EMBB_DATAFLOW_CPP_SOURCES} ${EMBB_DATAFLOW_CPP_HEADERS}) -target_link_libraries(embb_dataflow_cpp embb_tasks_cpp embb_base_cpp embb_mtapi_c embb_base_c) +target_link_libraries(embb_dataflow_cpp embb_mtapi_cpp embb_base_cpp embb_mtapi_c embb_base_c) if (BUILD_TESTS STREQUAL ON) include_directories(${CMAKE_CURRENT_BINARY_DIR}/../partest/include) add_executable (embb_dataflow_cpp_test ${EMBB_DATAFLOW_CPP_TEST_SOURCES}) - target_link_libraries(embb_dataflow_cpp_test embb_dataflow_cpp embb_tasks_cpp embb_mtapi_c partest + target_link_libraries(embb_dataflow_cpp_test embb_dataflow_cpp embb_mtapi_cpp embb_mtapi_c partest embb_base_cpp embb_base_c ${compiler_libs}) CopyBin(BIN embb_dataflow_cpp_test DEST ${local_install_dir}) endif() @@ -34,3 +34,8 @@ endif() install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include FILES_MATCHING PATTERN "*.h") install(TARGETS embb_dataflow_cpp DESTINATION lib) +if (MSVC) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Debug/embb_dataflow_cpp.pdb + DESTINATION lib + CONFIGURATIONS Debug) +endif() diff --git a/dataflow_cpp/include/embb/dataflow/internal/action.h b/dataflow_cpp/include/embb/dataflow/internal/action.h index 61f4cfa..4b6d0b7 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/action.h +++ b/dataflow_cpp/include/embb/dataflow/internal/action.h @@ -29,7 +29,7 @@ #include -#include +#include #include @@ -46,7 +46,7 @@ class Action { node_->Run(clock_); } - void RunMTAPI(embb::tasks::TaskContext & /*context*/) { + void RunMTAPI(embb::mtapi::TaskContext & /*context*/) { node_->Run(clock_); } diff --git a/dataflow_cpp/include/embb/dataflow/internal/process.h b/dataflow_cpp/include/embb/dataflow/internal/process.h index 7f0f538..ad373b4 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/process.h +++ b/dataflow_cpp/include/embb/dataflow/internal/process.h @@ -158,7 +158,7 @@ class Process< Serial, Inputs, } else { const int idx = clock % slices_; action_[idx] = Action(this, clock); - sched_->Spawn(action_[idx]); + sched_->Start(action_[idx]); } } diff --git a/dataflow_cpp/include/embb/dataflow/internal/scheduler.h b/dataflow_cpp/include/embb/dataflow/internal/scheduler.h index dbf5556..61aaa6a 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/scheduler.h +++ b/dataflow_cpp/include/embb/dataflow/internal/scheduler.h @@ -37,7 +37,7 @@ class Scheduler { public: Scheduler() {} virtual ~Scheduler() {} - virtual void Spawn(Action & action) = 0; + virtual void Start(Action & action) = 0; virtual void Enqueue(int process_id, Action & action) = 0; virtual void WaitForSlice(int slice) = 0; virtual int GetSlices() = 0; diff --git a/dataflow_cpp/include/embb/dataflow/internal/scheduler_mtapi.h b/dataflow_cpp/include/embb/dataflow/internal/scheduler_mtapi.h index 4870767..a7eee70 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/scheduler_mtapi.h +++ b/dataflow_cpp/include/embb/dataflow/internal/scheduler_mtapi.h @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include @@ -38,11 +38,13 @@ namespace embb { namespace dataflow { namespace internal { +#define EMBB_DATAFLOW_JOB_ID 1 + class SchedulerMTAPI : public Scheduler { public: explicit SchedulerMTAPI(int slices) : slices_(slices) { - embb::tasks::Node & node = embb::tasks::Node::GetInstance(); + embb::mtapi::Node & node = embb::mtapi::Node::GetInstance(); int tl = std::min( static_cast(node.GetTaskLimit()), @@ -51,60 +53,85 @@ class SchedulerMTAPI : public Scheduler { slices_ = tl; } - group_ = reinterpret_cast( + job_ = node.GetJob(EMBB_DATAFLOW_JOB_ID); + action_ = node.CreateAction(EMBB_DATAFLOW_JOB_ID, + SchedulerMTAPI::action_func); + + group_ = reinterpret_cast( embb::base::Allocation::Allocate( - sizeof(embb::tasks::Group*)*slices_)); + sizeof(embb::mtapi::Group)*slices_)); for (int ii = 0; ii < slices_; ii++) { - embb::tasks::Group & group = node.CreateGroup(); - group_[ii] = &group; + group_[ii] = node.CreateGroup(); } queue_count_ = std::min( static_cast(node.GetQueueCount()), static_cast(node.GetWorkerThreadCount()) ); - queue_ = reinterpret_cast( + queue_ = reinterpret_cast( embb::base::Allocation::Allocate( - sizeof(embb::tasks::Queue*)*queue_count_)); + sizeof(embb::mtapi::Queue)*queue_count_)); + embb::mtapi::QueueAttributes queue_attr; + queue_attr + .SetPriority(0) + .SetOrdered(true); for (int ii = 0; ii < queue_count_; ii++) { - embb::tasks::Queue & queue = node.CreateQueue(0, true); - queue_[ii] = &queue; + queue_[ii] = node.CreateQueue(job_, queue_attr); } } virtual ~SchedulerMTAPI() { - if (embb::tasks::Node::IsInitialized()) { + if (embb::mtapi::Node::IsInitialized()) { // only destroy groups and queues if there still is an instance - embb::tasks::Node & node = embb::tasks::Node::GetInstance(); for (int ii = 0; ii < slices_; ii++) { - group_[ii]->WaitAll(MTAPI_INFINITE); - node.DestroyGroup(*group_[ii]); + group_[ii].WaitAll(MTAPI_INFINITE); + group_[ii].Delete(); } for (int ii = 0; ii < queue_count_; ii++) { - node.DestroyQueue(*queue_[ii]); + queue_[ii].Delete(); } + // delete action as well + action_.Delete(); } embb::base::Allocation::Free(group_); embb::base::Allocation::Free(queue_); } - virtual void Spawn(Action & action) { + virtual void Start(Action & action) { const int idx = action.GetClock() % slices_; - group_[idx]->Spawn(embb::base::MakeFunction(action, &Action::RunMTAPI)); + group_[idx].Start(job_, &action, static_cast(NULL)); } virtual void Enqueue(int process_id, Action & action) { const int idx = action.GetClock() % slices_; const int queue_id = process_id % queue_count_; - queue_[queue_id]->Spawn(group_[idx], - embb::base::MakeFunction(action, &Action::RunMTAPI)); + queue_[queue_id].Enqueue(&action, static_cast(NULL), group_[idx]); } virtual void WaitForSlice(int slice) { - group_[slice]->WaitAll(MTAPI_INFINITE); + group_[slice].WaitAll(MTAPI_INFINITE); + // group is invalid now, recreate + embb::mtapi::Node & node = embb::mtapi::Node::GetInstance(); + group_[slice] = node.CreateGroup(); } virtual int GetSlices() { return slices_; } private: - embb::tasks::Group ** group_; - embb::tasks::Queue ** queue_; + static void action_func( + const void* args, + mtapi_size_t /*args_size*/, + void* /*result_buffer*/, + mtapi_size_t /*result_buffer_size*/, + const void* /*node_local_data*/, + mtapi_size_t /*node_local_data_size*/, + mtapi_task_context_t * context) { + Action * action = + reinterpret_cast(const_cast(args)); + embb::mtapi::TaskContext task_context(context); + action->RunMTAPI(task_context); + } + + embb::mtapi::Action action_; + embb::mtapi::Job job_; + embb::mtapi::Group * group_; + embb::mtapi::Queue * queue_; int queue_count_; int slices_; }; diff --git a/dataflow_cpp/include/embb/dataflow/internal/scheduler_sequential.h b/dataflow_cpp/include/embb/dataflow/internal/scheduler_sequential.h index c9c4b9d..500d41a 100644 --- a/dataflow_cpp/include/embb/dataflow/internal/scheduler_sequential.h +++ b/dataflow_cpp/include/embb/dataflow/internal/scheduler_sequential.h @@ -38,7 +38,7 @@ class SchedulerSequential : public Scheduler { public: SchedulerSequential() {} virtual ~SchedulerSequential() {} - virtual void Spawn(Action & action) { + virtual void Start(Action & action) { action.RunSequential(); } virtual void Enqueue(int, Action & action) { diff --git a/dataflow_cpp/test/dataflow_cpp_test_simple.cc b/dataflow_cpp/test/dataflow_cpp_test_simple.cc index c73a0f1..c0b56db 100644 --- a/dataflow_cpp/test/dataflow_cpp_test_simple.cc +++ b/dataflow_cpp/test/dataflow_cpp_test_simple.cc @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include @@ -153,15 +153,14 @@ SimpleTest::SimpleTest() { void SimpleTest::TestBasic() { // All available cores embb::base::CoreSet core_set(true); - embb::tasks::Node::Initialize( + embb::mtapi::NodeAttributes node_attr; + node_attr + .SetCoreAffinity(core_set) + .SetMaxQueues(2); + embb::mtapi::Node::Initialize( MTAPI_DOMAIN_ID, MTAPI_NODE_ID, - core_set, - 1024, // max tasks (default: 1024) - 128, // max groups (default: 128) - 2, // max queues (default: 16) - 1024, // queue capacity (default: 1024) - 4); // num priorities (default: 4) + node_attr); for (int ii = 0; ii < 10000; ii++) { ArraySink asink; @@ -221,7 +220,7 @@ void SimpleTest::TestBasic() { PT_EXPECT(asink.Check()); } - embb::tasks::Node::Finalize(); + embb::mtapi::Node::Finalize(); PT_EXPECT(embb_get_bytes_allocated() == 0); } diff --git a/doc/examples/CMakeLists.txt b/doc/examples/CMakeLists.txt index 31c07d2..9926e36 100644 --- a/doc/examples/CMakeLists.txt +++ b/doc/examples/CMakeLists.txt @@ -14,8 +14,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_c/src ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_plugins_c/mtapi_network_c/include ${CMAKE_CURRENT_SOURCE_DIR}/../../mtapi_cpp/include - ${CMAKE_CURRENT_SOURCE_DIR}/../../tasks_cpp/include - ${CMAKE_CURRENT_BINARY_DIR}/../../tasks_cpp/include + ${CMAKE_CURRENT_BINARY_DIR}/../../mtapi_cpp/include ${CMAKE_CURRENT_SOURCE_DIR}/../../containers_cpp/include ${CMAKE_CURRENT_SOURCE_DIR}/../../algorithms_cpp/include ${CMAKE_CURRENT_SOURCE_DIR}/../../dataflow_cpp/include @@ -46,7 +45,7 @@ IF(MSVC) ENDIF() add_executable(examples ${EXAMPLES_SOURCES}) -target_link_libraries(examples embb_dataflow_cpp embb_algorithms_cpp embb_tasks_cpp embb_mtapi_cpp +target_link_libraries(examples embb_dataflow_cpp embb_algorithms_cpp embb_mtapi_cpp embb_mtapi_network_c ${EMBB_MTAPI_OPENCL_C_CONDITIONAL} embb_mtapi_c embb_base_cpp embb_base_c embb_containers_cpp ${EXTRA_LIBS} ${compiler_libs}) diff --git a/doc/examples/main.cc b/doc/examples/main.cc index 80b9c3c..218bb44 100644 --- a/doc/examples/main.cc +++ b/doc/examples/main.cc @@ -34,7 +34,6 @@ void RunMTAPI_C_Network(); void RunMTAPI_C_OpenCL(); #endif void RunMTAPI_CPP(); -void RunTasks(); void RunDataflowLinear(); void RunDataflowNonLinear(); void RunSTLForEach(); @@ -78,10 +77,6 @@ int main() { RunMTAPI_CPP(); std::cout << "RunMTAPI_CPP() ... done" << std::endl; - std::cout << "RunTasks() ..." << std::endl; - RunTasks(); - std::cout << "RunTasks() ... done" << std::endl; - std::cout << "RunDataflowLinear() ..." << std::endl; RunDataflowLinear(); std::cout << "RunDataflowLinear() ... done" << std::endl; diff --git a/doc/examples/mtapi/mtapi_cpp-fragmented.cc b/doc/examples/mtapi/mtapi_cpp-fragmented.cc index 427039e..8754087 100644 --- a/doc/examples/mtapi/mtapi_cpp-fragmented.cc +++ b/doc/examples/mtapi/mtapi_cpp-fragmented.cc @@ -51,8 +51,8 @@ static static int fibonacci(int n) { #include "mtapi/mtapi_cpp_initialize-snippet.h" -#include "mtapi/mtapi_cpp_register_action-snippet.h" #include "mtapi/mtapi_cpp_get_node-snippet.h" +#include "mtapi/mtapi_cpp_register_action-snippet.h" /* start calculation */ #include "mtapi/mtapi_cpp_start_task-snippet.h" /* wait for task completion */ diff --git a/doc/examples/mtapi/mtapi_cpp_register_action-snippet.h b/doc/examples/mtapi/mtapi_cpp_register_action-snippet.h index beeea5a..b1bb615 100644 --- a/doc/examples/mtapi/mtapi_cpp_register_action-snippet.h +++ b/doc/examples/mtapi/mtapi_cpp_register_action-snippet.h @@ -1,9 +1,9 @@ /* create action */ - embb::mtapi::Action fibonacciAction( + embb::mtapi::Action fibonacciAction = node.CreateAction( FIBONACCI_JOB, /* action ID, defined by the application */ (fibonacciActionFunction) /* action function */ ); /* get job */ - fibonacciJob = embb::mtapi::Job(FIBONACCI_JOB, THIS_DOMAIN_ID); + fibonacciJob = node.GetJob(FIBONACCI_JOB, THIS_DOMAIN_ID); diff --git a/doc/examples/mtapi/mtapi_cpp_simple_action_signature-snippet.h b/doc/examples/mtapi/mtapi_cpp_simple_action_signature-snippet.h new file mode 100644 index 0000000..c3b72cf --- /dev/null +++ b/doc/examples/mtapi/mtapi_cpp_simple_action_signature-snippet.h @@ -0,0 +1,5 @@ +void simpleActionFunction( + TaskContext & task_context +) { + // something useful +} diff --git a/doc/examples/mtapi/mtapi_cpp_simple_start_task-snippet.h b/doc/examples/mtapi/mtapi_cpp_simple_start_task-snippet.h new file mode 100644 index 0000000..77c7856 --- /dev/null +++ b/doc/examples/mtapi/mtapi_cpp_simple_start_task-snippet.h @@ -0,0 +1,2 @@ + int result; + embb::mtapi::Task task = node.Start(simpleActionFunction); diff --git a/doc/examples/mtapi/mtapi_cpp_wait_task-snippet.h b/doc/examples/mtapi/mtapi_cpp_wait_task-snippet.h index 9f1f9d7..923fea2 100644 --- a/doc/examples/mtapi/mtapi_cpp_wait_task-snippet.h +++ b/doc/examples/mtapi/mtapi_cpp_wait_task-snippet.h @@ -1,5 +1,5 @@ - mtapi_status_t status = task.Wait(MTAPI_INFINITE); - if (status != MTAPI_SUCCESS) { - printf("task failed with error: %d\n\n", status); - exit(status); + mtapi_status_t task_status = task.Wait(MTAPI_INFINITE); + if (task_status != MTAPI_SUCCESS) { + printf("task failed with error: %d\n\n", task_status); + exit(task_status); } diff --git a/doc/examples/tasks/tasks_cpp-fragmented.cc b/doc/examples/tasks/tasks_cpp-fragmented.cc deleted file mode 100644 index 5443760..0000000 --- a/doc/examples/tasks/tasks_cpp-fragmented.cc +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include "mtapi/mtapi_check_status-snippet.h" - -static -#include "tasks/tasks_cpp_action_signature-snippet.h" - /* get the node instance */ -#include "tasks/tasks_cpp_get_node-snippet.h" - /* calculate */ -#include "mtapi/mtapi_terminating_condition-snippet.h" - /* first recursive call spawned as task (x = fib(n - 1);) */ -#include "tasks/tasks_cpp_calc_task-snippet.h" - /* second recursive call can be called directly (y = fib(n - 2);) */ -#include "tasks/tasks_cpp_calc_direct-snippet.h" - /* wait for completion */ -#include "tasks/tasks_cpp_wait_task-snippet.h" - /* add the two preceeding numbers */ -#include "mtapi/mtapi_write_back-snippet.h" - -static -int fibonacci(int n) { - /* get the node instance, the node is initialized automatically */ - embb::tasks::Node& node = embb::tasks::Node::GetInstance(); - /* start calculation */ -#include "tasks/tasks_cpp_start_task-snippet.h" - /* wait for task completion */ - mtapi_status_t status = task.Wait(MTAPI_INFINITE); - MTAPI_CHECK_STATUS(status); - - return result; -} - -void RunTasks() { - int result = fibonacci(6); - std::cout << "result: " << result << std::endl; -} diff --git a/doc/examples/tasks/tasks_cpp_action_signature-snippet.h b/doc/examples/tasks/tasks_cpp_action_signature-snippet.h deleted file mode 100644 index 24aa989..0000000 --- a/doc/examples/tasks/tasks_cpp_action_signature-snippet.h +++ /dev/null @@ -1,5 +0,0 @@ -void fibonacciActionFunction( - int n, - int* result, - embb::tasks::TaskContext & task_context - ) { diff --git a/doc/examples/tasks/tasks_cpp_calc_direct-snippet.h b/doc/examples/tasks/tasks_cpp_calc_direct-snippet.h deleted file mode 100644 index eb08e75..0000000 --- a/doc/examples/tasks/tasks_cpp_calc_direct-snippet.h +++ /dev/null @@ -1,6 +0,0 @@ - int b = n - 2; - int y; - fibonacciActionFunction( - b, - &y, - task_context); diff --git a/doc/examples/tasks/tasks_cpp_calc_task-snippet.h b/doc/examples/tasks/tasks_cpp_calc_task-snippet.h deleted file mode 100644 index cfe5664..0000000 --- a/doc/examples/tasks/tasks_cpp_calc_task-snippet.h +++ /dev/null @@ -1,10 +0,0 @@ - int a = n - 1; - int x; - embb::tasks::Task task = node.Spawn( - embb::base::Bind( - embb::base::MakeFunction(fibonacciActionFunction), - a, /* argument */ - &x, /* result */ - embb::base::Placeholder::_1 - ) - ); diff --git a/doc/examples/tasks/tasks_cpp_get_node-snippet.h b/doc/examples/tasks/tasks_cpp_get_node-snippet.h deleted file mode 100644 index f644ec5..0000000 --- a/doc/examples/tasks/tasks_cpp_get_node-snippet.h +++ /dev/null @@ -1 +0,0 @@ - embb::tasks::Node& node = embb::tasks::Node::GetInstance(); diff --git a/doc/examples/tasks/tasks_cpp_start_task-snippet.h b/doc/examples/tasks/tasks_cpp_start_task-snippet.h deleted file mode 100644 index 507e634..0000000 --- a/doc/examples/tasks/tasks_cpp_start_task-snippet.h +++ /dev/null @@ -1,9 +0,0 @@ - int result; - embb::tasks::Task task = node.Spawn( - embb::base::Bind( - embb::base::MakeFunction(fibonacciActionFunction), - n, - &result, - embb::base::Placeholder::_1 - ) - ); diff --git a/doc/examples/tasks/tasks_cpp_wait_task-snippet.h b/doc/examples/tasks/tasks_cpp_wait_task-snippet.h deleted file mode 100644 index 21637fd..0000000 --- a/doc/examples/tasks/tasks_cpp_wait_task-snippet.h +++ /dev/null @@ -1,2 +0,0 @@ - mtapi_status_t status = task.Wait(MTAPI_INFINITE); - MTAPI_CHECK_STATUS(status); diff --git a/doc/reference/Doxyfile.in b/doc/reference/Doxyfile.in index c240844..760d09e 100644 --- a/doc/reference/Doxyfile.in +++ b/doc/reference/Doxyfile.in @@ -148,7 +148,6 @@ INPUT = "@CMAKE_SOURCE_DIR@/doc/reference/embb.dox" \ "@CMAKE_SOURCE_DIR@/containers_cpp/include" \ "@CMAKE_SOURCE_DIR@/dataflow_cpp/include" \ "@CMAKE_SOURCE_DIR@/algorithms_cpp/include" \ - "@CMAKE_SOURCE_DIR@/tasks_cpp/include" \ "@CMAKE_SOURCE_DIR@/mtapi_cpp/include" \ "@CMAKE_SOURCE_DIR@/base_cpp/include" \ "@CMAKE_SOURCE_DIR@/mtapi_c/include" \ diff --git a/doc/tutorial/content/mtapi.tex b/doc/tutorial/content/mtapi.tex index 4b940ce..1ac8c2b 100644 --- a/doc/tutorial/content/mtapi.tex +++ b/doc/tutorial/content/mtapi.tex @@ -152,7 +152,11 @@ After everything is done, the action is deleted (\lstinline|mtapi_action_delete( \section{C++ Interface} \label{sec:mtapi_cpp_interface} -\embb provides C++ wrappers for the MTAPI C interface. The signature of the action function for the C++ interface is the same as in the C interface: +\embb provides C++ wrappers for the MTAPI C interface. The full interface provides functions for all MTAPI releated tasks and supports heterogeneous systems. For ease of use a simpler version for SMP systems is provided. + +\subsection{Full Interface} + +The signature of the action function for the C++ interface is the same as in the C interface: % \\\inputlisting{../examples/mtapi/mtapi_c_action_signature-snippet.h} % @@ -193,7 +197,7 @@ After that, the action function needs to be associated to a job. By instancing a % \\\inputlisting{../examples/mtapi/mtapi_cpp_register_action-snippet.h} % -Not that the action is registered and the job is initialized, the root task can be started: +Now that the action is registered and the job is initialized, the root task can be started: % \\\inputlisting{../examples/mtapi/mtapi_cpp_start_task-snippet.h} % @@ -203,6 +207,19 @@ The registered action will be unregistered when it goes out of scope. The runtime needs to be shut down by calling: \\\inputlisting{../examples/mtapi/mtapi_cpp_finalize-snippet.h} +\subsection{Simplified Interface for SMP actions} + +MTAPI CPP provides a simpler version of the MTAPI interface for SMP actions. The signature of the +action function for the simplified API looks like this: +% +\\\inputlisting{../examples/mtapi/mtapi_cpp_simple_action_signature-snippet.h} +% +The action function does not need to be registered with a job. Instead a preregistered job is used that expects a \lstinline|embb::base::Function| object. Therefore a task can be scheduled directly using only the function above: +% +\\\inputlisting{../examples/mtapi/mtapi_cpp_simple_start_task-snippet.h} +% + + \section{Plugins} The \embb implementation of MTAPI provides an extension to allow for custom actions that are not executed by the scheduler for software actions as detailed in the previous sections. diff --git a/doc/tutorial/content/tasks.tex b/doc/tutorial/content/tasks.tex deleted file mode 100644 index 45770bc..0000000 --- a/doc/tutorial/content/tasks.tex +++ /dev/null @@ -1,45 +0,0 @@ -\chapter{Tasks} -\label{cha:tasks} - -\embb provides a simple task management wrapper for the MTAPI interface. Using the example from the previous section, the signature of the action function for the tasks interface looks like this: -% -\\\inputlisting{../examples/tasks/tasks_cpp_action_signature-snippet.h} -% -First, the node instance needs to be obtained. If the node is not initialized yet, this function will do it. -% -\\\inputlisting{../examples/tasks/tasks_cpp_get_node-snippet.h} -% -\emph{\textbf{Note:} Automatic initialization allows for easy usage of the \emph{Algorithms} and \emph{Dataflow} building blocks. For performance measurements however, explicit initialization by calling \lstinline|embb::tasks::Node::Initialize| is imperative since the measurements will otherwise include the initialization time of MTAPI.} - -Checking the arguments and the result buffer is not necessary, since everything is safely typed. However, the terminating condition of the recursion still needs to be checked: -% -\\\inputlisting{../examples/mtapi/mtapi_terminating_condition-snippet.h} -% -After that, the first part of the computation is launched as an MTAPI task using \lstinline|embb::tasks::Node::Spawn()| (registering an action function with a job is done automatically): -% -\\\inputlisting{../examples/tasks/tasks_cpp_calc_task-snippet.h} -% -The second part can be executed directly: -% -\\\inputlisting{../examples/tasks/tasks_cpp_calc_direct-snippet.h} -% -Then, completion of the MTAPI task has to be waited for using \lstinline|embb::tasks::Task::Wait()|: -% -\\\inputlisting{../examples/tasks/tasks_cpp_wait_task-snippet.h} -% -Finally, the two parts can be added and written into the result buffer: -% -\\\inputlisting{../examples/mtapi/mtapi_write_back-snippet.h} -% - -The \lstinline|fibonacci()| function also gets simpler compared to the C version. The MTAPI runtime is initialized automatically, only the node instance has to be fetched: -% -\\\inputlisting{../examples/tasks/tasks_cpp_get_node-snippet.h} -% -The root task can be started using \lstinline|embb::tasks::Node::Spawn()| directly, registering with a job is done automatically: -% -\\\inputlisting{../examples/tasks/tasks_cpp_start_task-snippet.h} -% -Again, the started task has to be waited for (using \lstinline|embb::tasks::Task::Wait()|) before the result can be returned. The runtime is shut down automatically in an \lstinline|atexit()| handler. - -\emph{\textbf{Note:} If the node was initialized explicitly by calling \lstinline|embb::tasks::Node::Initialize|, the runtime must also be shut down explicitly by calling \lstinline|embb::tasks::Node::Finalize|.} diff --git a/doc/tutorial/tutorial.tex b/doc/tutorial/tutorial.tex index 39e3c12..bd07bc3 100644 --- a/doc/tutorial/tutorial.tex +++ b/doc/tutorial/tutorial.tex @@ -114,7 +114,6 @@ % \input{content/preface} \input{content/introduction} \input{content/mtapi} -\input{content/tasks} \input{content/algorithms} \input{content/dataflow} \input{content/containers} diff --git a/mtapi_c/CMakeLists.txt b/mtapi_c/CMakeLists.txt index 0e147b1..5c3bc16 100644 --- a/mtapi_c/CMakeLists.txt +++ b/mtapi_c/CMakeLists.txt @@ -39,3 +39,8 @@ endif() install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include FILES_MATCHING PATTERN "*.h") install(TARGETS embb_mtapi_c DESTINATION lib) +if (MSVC) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Debug/embb_mtapi_c.pdb + DESTINATION lib + CONFIGURATIONS Debug) +endif() diff --git a/mtapi_c/src/embb_mtapi_action_t.c b/mtapi_c/src/embb_mtapi_action_t.c index dff3606..c4d1714 100644 --- a/mtapi_c/src/embb_mtapi_action_t.c +++ b/mtapi_c/src/embb_mtapi_action_t.c @@ -289,10 +289,12 @@ void mtapi_action_delete( embb_mtapi_thread_context_t * context = NULL; embb_duration_t wait_duration; + embb_time_t start_time; embb_time_t end_time; if (MTAPI_INFINITE < timeout) { embb_duration_set_milliseconds( &wait_duration, (unsigned long long)timeout); + embb_time_now(&start_time); embb_time_in(&end_time, &wait_duration); } @@ -309,6 +311,12 @@ void mtapi_action_delete( if (MTAPI_INFINITE < timeout) { embb_time_t current_time; embb_time_now(¤t_time); + if (embb_time_compare(¤t_time, &start_time) < 0) { + /* time has moved backwards, maybe a wraparound or jitter + move end_time backward to avoid endeless loop */ + start_time = current_time; + embb_time_in(&end_time, &wait_duration); + } if (embb_time_compare(¤t_time, &end_time) > 0) { /* timeout! */ local_status = MTAPI_TIMEOUT; @@ -362,10 +370,12 @@ void mtapi_action_disable( embb_mtapi_thread_context_t * context = NULL; embb_duration_t wait_duration; + embb_time_t start_time; embb_time_t end_time; if (MTAPI_INFINITE < timeout) { embb_duration_set_milliseconds( &wait_duration, (unsigned long long)timeout); + embb_time_now(&start_time); embb_time_in(&end_time, &wait_duration); } @@ -382,6 +392,12 @@ void mtapi_action_disable( if (MTAPI_INFINITE < timeout) { embb_time_t current_time; embb_time_now(¤t_time); + if (embb_time_compare(¤t_time, &start_time) < 0) { + /* time has moved backwards, maybe a wraparound or jitter + move end_time backward to avoid endeless loop */ + start_time = current_time; + embb_time_in(&end_time, &wait_duration); + } if (embb_time_compare(¤t_time, &end_time) > 0) { /* timeout! */ local_status = MTAPI_TIMEOUT; diff --git a/mtapi_c/src/embb_mtapi_group_t.c b/mtapi_c/src/embb_mtapi_group_t.c index c0d4082..10c41b8 100644 --- a/mtapi_c/src/embb_mtapi_group_t.c +++ b/mtapi_c/src/embb_mtapi_group_t.c @@ -213,10 +213,12 @@ void mtapi_group_wait_all( node->group_pool, group); embb_duration_t wait_duration; + embb_time_t start_time; embb_time_t end_time; if (MTAPI_INFINITE < timeout) { embb_duration_set_milliseconds( &wait_duration, (unsigned long long)timeout); + embb_time_now(&start_time); embb_time_in(&end_time, &wait_duration); } @@ -232,6 +234,12 @@ void mtapi_group_wait_all( if (MTAPI_INFINITE < timeout) { embb_time_t current_time; embb_time_now(¤t_time); + if (embb_time_compare(¤t_time, &start_time) < 0) { + /* time has moved backwards, maybe a wraparound or jitter + move end_time backward to avoid endeless loop */ + start_time = current_time; + embb_time_in(&end_time, &wait_duration); + } if (embb_time_compare(¤t_time, &end_time) > 0) { /* timeout! */ local_status = MTAPI_TIMEOUT; @@ -300,10 +308,12 @@ void mtapi_group_wait_any( embb_mtapi_thread_context_t * context = NULL; embb_duration_t wait_duration; + embb_time_t start_time; embb_time_t end_time; if (MTAPI_INFINITE < timeout) { embb_duration_set_milliseconds( &wait_duration, (unsigned long long)timeout); + embb_time_now(&start_time); embb_time_in(&end_time, &wait_duration); } @@ -318,6 +328,12 @@ void mtapi_group_wait_any( if (MTAPI_INFINITE < timeout) { embb_time_t current_time; embb_time_now(¤t_time); + if (embb_time_compare(¤t_time, &start_time) < 0) { + /* time has moved backwards, maybe a wraparound or jitter + move end_time backward to avoid endeless loop */ + start_time = current_time; + embb_time_in(&end_time, &wait_duration); + } if (embb_time_compare(¤t_time, &end_time) > 0) { /* timeout! */ local_status = MTAPI_TIMEOUT; diff --git a/mtapi_c/src/embb_mtapi_queue_t.c b/mtapi_c/src/embb_mtapi_queue_t.c index 5e9599f..be85611 100644 --- a/mtapi_c/src/embb_mtapi_queue_t.c +++ b/mtapi_c/src/embb_mtapi_queue_t.c @@ -360,10 +360,12 @@ void mtapi_queue_delete( embb_mtapi_thread_context_t * context = NULL; embb_duration_t wait_duration; + embb_time_t start_time; embb_time_t end_time; if (MTAPI_INFINITE < timeout) { embb_duration_set_milliseconds( &wait_duration, (unsigned long long)timeout); + embb_time_now(&start_time); embb_time_in(&end_time, &wait_duration); } @@ -381,6 +383,12 @@ void mtapi_queue_delete( if (MTAPI_INFINITE < timeout) { embb_time_t current_time; embb_time_now(¤t_time); + if (embb_time_compare(¤t_time, &start_time) < 0) { + /* time has moved backwards, maybe a wraparound or jitter + move end_time backward to avoid endeless loop */ + start_time = current_time; + embb_time_in(&end_time, &wait_duration); + } if (embb_time_compare(¤t_time, &end_time) > 0) { /* timeout! */ local_status = MTAPI_TIMEOUT; @@ -435,10 +443,12 @@ void mtapi_queue_disable( embb_mtapi_scheduler_get_current_thread_context(node->scheduler); embb_duration_t wait_duration; + embb_time_t start_time; embb_time_t end_time; if (MTAPI_INFINITE < timeout) { embb_duration_set_milliseconds( &wait_duration, (unsigned long long)timeout); + embb_time_now(&start_time); embb_time_in(&end_time, &wait_duration); } @@ -448,6 +458,12 @@ void mtapi_queue_disable( if (MTAPI_INFINITE < timeout) { embb_time_t current_time; embb_time_now(¤t_time); + if (embb_time_compare(¤t_time, &start_time) < 0) { + /* time has moved backwards, maybe a wraparound or jitter + move end_time backward to avoid endeless loop */ + start_time = current_time; + embb_time_in(&end_time, &wait_duration); + } if (embb_time_compare(¤t_time, &end_time) > 0) { /* timeout! */ local_status = MTAPI_TIMEOUT; diff --git a/mtapi_c/src/embb_mtapi_scheduler_t.c b/mtapi_c/src/embb_mtapi_scheduler_t.c index d7549c6..7e4052c 100644 --- a/mtapi_c/src/embb_mtapi_scheduler_t.c +++ b/mtapi_c/src/embb_mtapi_scheduler_t.c @@ -407,6 +407,7 @@ mtapi_boolean_t embb_mtapi_scheduler_wait_for_task( embb_mtapi_node_t* node = embb_mtapi_node_get_instance(); embb_mtapi_thread_context_t * context = NULL; embb_duration_t wait_duration; + embb_time_t start_time; embb_time_t end_time; assert(MTAPI_NULL != node); @@ -414,6 +415,7 @@ mtapi_boolean_t embb_mtapi_scheduler_wait_for_task( if (MTAPI_INFINITE < timeout) { embb_duration_set_milliseconds(&wait_duration, (unsigned long long)timeout); + embb_time_now(&start_time); embb_time_in(&end_time, &wait_duration); } @@ -431,6 +433,12 @@ mtapi_boolean_t embb_mtapi_scheduler_wait_for_task( if (MTAPI_INFINITE < timeout) { embb_time_t current_time; embb_time_now(¤t_time); + if (embb_time_compare(¤t_time, &start_time) < 0) { + /* time has moved backwards, maybe a wraparound or jitter + move end_time backward to avoid endeless loop */ + start_time = current_time; + embb_time_in(&end_time, &wait_duration); + } if (embb_time_compare(¤t_time, &end_time) > 0) { /* timeout! */ return MTAPI_FALSE; diff --git a/mtapi_c/src/embb_mtapi_thread_context_t.c b/mtapi_c/src/embb_mtapi_thread_context_t.c index e791824..56077ac 100644 --- a/mtapi_c/src/embb_mtapi_thread_context_t.c +++ b/mtapi_c/src/embb_mtapi_thread_context_t.c @@ -54,7 +54,8 @@ mtapi_boolean_t embb_mtapi_thread_context_initialize_with_node_worker_and_core( that->core_num = core_num; that->priorities = node->attributes.max_priorities; that->is_initialized = MTAPI_FALSE; - that->is_main_thread = (worker_index == 0) ? node->attributes.reuse_main_thread : MTAPI_FALSE; + that->is_main_thread = (worker_index == 0) ? + node->attributes.reuse_main_thread : MTAPI_FALSE; embb_atomic_store_int(&that->run, 0); that->queue = (embb_mtapi_task_queue_t**)embb_mtapi_alloc_allocate( diff --git a/mtapi_cpp/CMakeLists.txt b/mtapi_cpp/CMakeLists.txt index 3a343f2..74878c9 100644 --- a/mtapi_cpp/CMakeLists.txt +++ b/mtapi_cpp/CMakeLists.txt @@ -10,6 +10,9 @@ else() set(MTAPI_CPP_AUTOMATIC_INITIALIZE 0) endif() +configure_file("include/embb/mtapi/internal/cmake_config.h.in" + "include/embb/mtapi/internal/cmake_config.h") + # Execute the GroupSources macro include(${CMAKE_SOURCE_DIR}/CMakeCommon/GroupSourcesMSVC.cmake) GroupSourcesMSVC(include) @@ -18,6 +21,7 @@ GroupSourcesMSVC(test) set (EMBB_MTAPI_CPP_INCLUDE_DIRS "include" "src" "test") include_directories(${EMBB_MTAPI_CPP_INCLUDE_DIRS} + ${CMAKE_CURRENT_BINARY_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/../base_c/include ${CMAKE_CURRENT_BINARY_DIR}/../base_c/include ${CMAKE_CURRENT_SOURCE_DIR}/../base_cpp/include @@ -38,3 +42,8 @@ endif() install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include FILES_MATCHING PATTERN "*.h") install(TARGETS embb_mtapi_cpp DESTINATION lib) +if (MSVC) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Debug/embb_mtapi_cpp.pdb + DESTINATION lib + CONFIGURATIONS Debug) +endif() diff --git a/mtapi_cpp/include/embb/mtapi/action.h b/mtapi_cpp/include/embb/mtapi/action.h index 564ab49..28ef3c7 100644 --- a/mtapi_cpp/include/embb/mtapi/action.h +++ b/mtapi_cpp/include/embb/mtapi/action.h @@ -43,60 +43,26 @@ class Action { public: /** * Constructs an Action. + * The Action object will be invalid. */ - Action( - mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ - mtapi_action_function_t func, /**< The action function */ - const void * node_local_data, /**< Node local data available to all - Tasks using this Action */ - mtapi_size_t node_local_data_size, /**< Size of node local data */ - ActionAttributes const & attributes - /**< Attributes of the Action */ - ) { - Create(job_id, func, node_local_data, node_local_data_size, - &attributes.GetInternal()); + Action() { + handle_.id = 0; + handle_.tag = 0; } - /** - * Constructs an Action. - */ - Action( - mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ - mtapi_action_function_t func, /**< The action function */ - const void * node_local_data, /**< Node local data available to all - Tasks using this Action */ - mtapi_size_t node_local_data_size /**< Size of node local data */ - ) { - Create(job_id, func, node_local_data, node_local_data_size, - MTAPI_DEFAULT_ACTION_ATTRIBUTES); - } - - /** - * Constructs an Action. - */ - Action( - mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ - mtapi_action_function_t func, /**< The action function */ - ActionAttributes const & attributes - /**< Attributes of the Action */ - ) { - Create(job_id, func, MTAPI_NULL, 0, &attributes.GetInternal()); + Action(Action const & other) : handle_(other.handle_) { + // empty } - /** - * Constructs an Action. - */ - Action( - mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ - mtapi_action_function_t func /**< The action function */ - ) { - Create(job_id, func, MTAPI_NULL, 0, MTAPI_DEFAULT_ACTION_ATTRIBUTES); + Action & operator=(Action const & other) { + handle_ = other.handle_; + return *this; } /** - * Destroys an Action. + * Deletes an Action. */ - ~Action() { + void Delete() { mtapi_action_delete(handle_, MTAPI_INFINITE, MTAPI_NULL); } @@ -111,20 +77,20 @@ class Action { return handle_; } - private: - // no default constructor - Action(); - - // not copyable - Action(Action const & other); - void operator=(Action const & other); + friend class Node; - void Create( - mtapi_job_id_t job_id, - mtapi_action_function_t func, - const void * node_local_data, - mtapi_size_t node_local_data_size, + private: + /** + * Constructs an Action. + */ + Action( + mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ + mtapi_action_function_t func, /**< The action function */ + const void * node_local_data, /**< Node local data available to all + Tasks using this Action */ + mtapi_size_t node_local_data_size, /**< Size of node local data */ mtapi_action_attributes_t const * attributes + /**< Attributes of the Action */ ) { mtapi_status_t status; handle_ = mtapi_action_create(job_id, func, diff --git a/tasks_cpp/include/embb/tasks/execution_policy.h b/mtapi_cpp/include/embb/mtapi/execution_policy.h similarity index 92% rename from tasks_cpp/include/embb/tasks/execution_policy.h rename to mtapi_cpp/include/embb/mtapi/execution_policy.h index 5248900..19d53ef 100644 --- a/tasks_cpp/include/embb/tasks/execution_policy.h +++ b/mtapi_cpp/include/embb/mtapi/execution_policy.h @@ -24,13 +24,14 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef EMBB_TASKS_EXECUTION_POLICY_H_ -#define EMBB_TASKS_EXECUTION_POLICY_H_ +#ifndef EMBB_MTAPI_EXECUTION_POLICY_H_ +#define EMBB_MTAPI_EXECUTION_POLICY_H_ #include +#include namespace embb { -namespace tasks { +namespace mtapi { /** * Describes the execution policy of a parallel algorithm. @@ -42,7 +43,7 @@ namespace tasks { * max_priorities - 1 as given during initialization using Node::Initialize(). * The default value of max_priorities is 4. * - * \ingroup CPP_TASKS + * \ingroup CPP_MTAPI */ class ExecutionPolicy{ public: @@ -118,7 +119,7 @@ class ExecutionPolicy{ * * \return the affinity */ - const mtapi_affinity_t &GetAffinity() const; + mtapi_affinity_t GetAffinity() const; /** Returns the priority * @@ -147,7 +148,7 @@ class ExecutionPolicy{ mtapi_uint_t priority_; }; -} // namespace tasks +} // namespace mtapi } // namespace embb -#endif // EMBB_TASKS_EXECUTION_POLICY_H_ +#endif // EMBB_MTAPI_EXECUTION_POLICY_H_ diff --git a/mtapi_cpp/include/embb/mtapi/group.h b/mtapi_cpp/include/embb/mtapi/group.h index 6d47598..8810d5f 100644 --- a/mtapi_cpp/include/embb/mtapi/group.h +++ b/mtapi_cpp/include/embb/mtapi/group.h @@ -51,49 +51,19 @@ namespace mtapi { */ class Group { public: - /** - * Constructs a Group object with default attributes. - * Requires an initialized Node. - */ - Group() { - Create(MTAPI_GROUP_ID_NONE, MTAPI_DEFAULT_GROUP_ATTRIBUTES); + Group(Group const & other) : handle_(other.handle_) { + // empty } - /** - * Constructs a Group object using the given Attributes. - * Requires an initialized Node. - */ - Group( - GroupAttributes const & attr /**< The GroupAttributes to use. */ - ) { - Create(MTAPI_GROUP_ID_NONE, &attr.GetInternal()); + Group & operator=(Group const & other) { + handle_ = other.handle_; + return *this; } /** - * Constructs a Group object with default attributes and the given ID. - * Requires an initialized Node. + * Deletes a Group object. */ - Group( - mtapi_group_id_t id /**< A user defined ID of the Group. */ - ) { - Create(id, MTAPI_DEFAULT_GROUP_ATTRIBUTES); - } - - /** - * Constructs a Group object with given attributes and ID. - * Requires an initialized Node. - */ - Group( - mtapi_group_id_t id, /**< A user defined ID of the Group. */ - GroupAttributes const & attr /**< The GroupAttributes to use. */ - ) { - Create(id, &attr.GetInternal()); - } - - /** - * Destroys a Group object. - */ - ~Group() { + void Delete() { // delete the group, ignore status mtapi_group_delete(handle_, MTAPI_NULL); } @@ -194,7 +164,6 @@ class Group { ) { mtapi_status_t status; mtapi_group_wait_any(handle_, result, timeout, &status); - needs_delete_ = status != MTAPI_GROUP_COMPLETED; return status; } @@ -245,7 +214,6 @@ class Group { ) { mtapi_status_t status; mtapi_group_wait_all(handle_, timeout, &status); - needs_delete_ = status != MTAPI_SUCCESS; return status; } @@ -271,21 +239,21 @@ class Group { } friend class embb::base::Allocation; + friend class Node; private: - // not copyable - Group(Group const & other); - void operator=(Group const & other); - - void Create( - mtapi_group_id_t group_id, + /** + * Constructs a Group object with given attributes and ID. + * Requires an initialized Node. + */ + Group( + mtapi_group_id_t id, /**< A user defined ID of the Group. */ mtapi_group_attributes_t const * attributes + /**< The GroupAttributes to use. */ ) { - needs_delete_ = false; mtapi_status_t status; - handle_ = mtapi_group_create(group_id, attributes, &status); + handle_ = mtapi_group_create(id, attributes, &status); internal::CheckStatus(status); - needs_delete_ = true; } Task Start( @@ -307,7 +275,6 @@ class Group { } mtapi_group_hndl_t handle_; - bool needs_delete_; }; } // namespace mtapi diff --git a/tasks_cpp/include/embb/tasks/internal/cmake_config.h.in b/mtapi_cpp/include/embb/mtapi/internal/cmake_config.h.in similarity index 89% rename from tasks_cpp/include/embb/tasks/internal/cmake_config.h.in rename to mtapi_cpp/include/embb/mtapi/internal/cmake_config.h.in index bb4ead5..6c78f59 100644 --- a/tasks_cpp/include/embb/tasks/internal/cmake_config.h.in +++ b/mtapi_cpp/include/embb/mtapi/internal/cmake_config.h.in @@ -24,8 +24,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef EMBB_TASKS_INTERNAL_CMAKE_CONFIG_H_ -#define EMBB_TASKS_INTERNAL_CMAKE_CONFIG_H_ +#ifndef EMBB_MTAPI_INTERNAL_CMAKE_CONFIG_H_ +#define EMBB_MTAPI_INTERNAL_CMAKE_CONFIG_H_ /* This file is used as input for CMake. CMake creates a file cmake_config.h in its current build directory under the path builddir/embb/tasks/internal/. From @@ -36,6 +36,6 @@ /** * Is used to enable automatic initialization of the MTAPI node */ -#define TASKS_CPP_AUTOMATIC_INITIALIZE ${TASKS_CPP_AUTOMATIC_INITIALIZE} +#define MTAPI_CPP_AUTOMATIC_INITIALIZE ${MTAPI_CPP_AUTOMATIC_INITIALIZE} -#endif // EMBB_TASKS_INTERNAL_CMAKE_CONFIG_H_ +#endif // EMBB_MTAPI_INTERNAL_CMAKE_CONFIG_H_ diff --git a/mtapi_cpp/include/embb/mtapi/job.h b/mtapi_cpp/include/embb/mtapi/job.h index 7b4c0f9..8a2fd54 100644 --- a/mtapi_cpp/include/embb/mtapi/job.h +++ b/mtapi_cpp/include/embb/mtapi/job.h @@ -50,19 +50,6 @@ class Job { } /** - * Constructs a Job with the given \c job_id and \c domain_id. - * Requires an initialized Node. - */ - Job( - mtapi_job_id_t job_id, /**< Job ID to use. */ - mtapi_domain_t domain_id /**< Domain ID to use. */ - ) { - mtapi_status_t status; - handle_ = mtapi_job_get(job_id, domain_id, &status); - internal::CheckStatus(status); - } - - /** * Copies a Job object. */ Job( @@ -91,7 +78,22 @@ class Job { return handle_; } + friend class Node; + private: + /** + * Constructs a Job with the given \c job_id and \c domain_id. + * Requires an initialized Node. + */ + Job( + mtapi_job_id_t job_id, /**< Job ID to use. */ + mtapi_domain_t domain_id /**< Domain ID to use. */ + ) { + mtapi_status_t status; + handle_ = mtapi_job_get(job_id, domain_id, &status); + internal::CheckStatus(status); + } + mtapi_job_hndl_t handle_; }; diff --git a/mtapi_cpp/include/embb/mtapi/mtapi.h b/mtapi_cpp/include/embb/mtapi/mtapi.h index 35e6d26..eba5572 100644 --- a/mtapi_cpp/include/embb/mtapi/mtapi.h +++ b/mtapi_cpp/include/embb/mtapi/mtapi.h @@ -35,6 +35,7 @@ * \ingroup CPP */ +#include #include #include #include diff --git a/mtapi_cpp/include/embb/mtapi/node.h b/mtapi_cpp/include/embb/mtapi/node.h index 115e48c..75ead82 100644 --- a/mtapi_cpp/include/embb/mtapi/node.h +++ b/mtapi_cpp/include/embb/mtapi/node.h @@ -28,12 +28,28 @@ #define EMBB_MTAPI_NODE_H_ #include +#include #include +#include #include #include +#include +#include #include #include #include +#include +#include + +#ifdef GetJob +#undef GetJob +#endif + +#ifdef MTAPI_CPP_AUTOMATIC_INITIALIZE +#define MTAPI_CPP_AUTOMATIC_DOMAIN_ID 1 +#define MTAPI_CPP_AUTOMATIC_NODE_ID 1 +#endif +#define EMBB_MTAPI_FUNCTION_JOB_ID 2 namespace embb { @@ -52,6 +68,8 @@ namespace mtapi { */ class Node { public: + typedef embb::base::Function SMPFunction; + /** * Initializes the runtime singleton using default values: * - all available cores will be used @@ -69,16 +87,7 @@ class Node { static void Initialize( mtapi_domain_t domain_id, /**< [in] The domain id to use */ mtapi_node_t node_id /**< [in] The node id to use */ - ) { - if (IsInitialized()) { - EMBB_THROW(StatusException, - "MTAPI: node was already initialized."); - } else { - NodeAttributes attributes; // default attributes - node_instance_ = embb::base::Allocation::New( - domain_id, node_id, attributes); - } - } + ); /** * Initializes the runtime singleton. @@ -91,15 +100,7 @@ class Node { mtapi_domain_t domain_id, /**< [in] The domain id to use */ mtapi_node_t node_id, /**< [in] The node id to use */ NodeAttributes const & attributes /**< [in] Attributes to use */ - ) { - if (IsInitialized()) { - EMBB_THROW(StatusException, - "MTAPI: node was already initialized."); - } else { - node_instance_ = embb::base::Allocation::New( - domain_id, node_id, attributes); - } - } + ); /** * Checks if runtime is initialized. @@ -116,29 +117,14 @@ class Node { * \return Reference to the Node singleton * \threadsafe */ - static Node & GetInstance() { - if (IsInitialized()) { - return *node_instance_; - } else { - EMBB_THROW(StatusException, - "MTAPI: node is not initialized."); - } - } + static Node & GetInstance(); /** * Shuts the runtime system down. * \throws ErrorException if the singleton is not initialized. * \notthreadsafe */ - static void Finalize() { - if (IsInitialized()) { - embb::base::Allocation::Delete(node_instance_); - node_instance_ = NULL; - } else { - EMBB_THROW(StatusException, - "MTAPI: node is not initialized."); - } - } + static void Finalize(); /** * Returns the number of available cores. @@ -159,6 +145,67 @@ class Node { } /** + * Returns the number of available queues. + * \return The number of available queues + * \waitfree + */ + mtapi_uint_t GetQueueCount() const { + return queue_count_; + } + + /** + * Returns the number of available groups. + * \return The number of available groups + * \waitfree + */ + mtapi_uint_t GetGroupCount() const { + return group_count_; + } + + /** + * Returns the number of available tasks. + * \return The number of available tasks + * \waitfree + */ + mtapi_uint_t GetTaskLimit() const { + return task_limit_; + } + + /** + * Starts a new Task. + * + * \returns The handle to the started Task. + * \threadsafe + */ + Task Start( + SMPFunction const & func /**< Function to use for the task. */ + ) { + Job job = GetJob(EMBB_MTAPI_FUNCTION_JOB_ID); + void * res = NULL; + return Start( + job, embb::base::Allocation::New(func), res); + } + + /** + * Starts a new Task with a given affinity and priority. + * + * \returns The handle to the started Task. + * \threadsafe + */ + Task Start( + SMPFunction const & func, /**< Function to use for the task. */ + ExecutionPolicy const & policy /**< Affinity and priority of the + task. */ + ) { + Job job = GetJob(EMBB_MTAPI_FUNCTION_JOB_ID); + void * res = NULL; + TaskAttributes task_attr; + task_attr.SetPolicy(policy); + return Start( + job, embb::base::Allocation::New(func), res, task_attr); + } + + /** * Starts a new Task. * * \returns The handle to the started Task. @@ -238,6 +285,119 @@ class Node { MTAPI_DEFAULT_TASK_ATTRIBUTES); } + Job GetJob(mtapi_job_id_t job_id) { + return Job(job_id, domain_id_); + } + + Job GetJob(mtapi_job_id_t job_id, mtapi_domain_t domain_id) { + return Job(job_id, domain_id); + } + + /** + * Constructs an Action. + */ + Action CreateAction( + mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ + mtapi_action_function_t func, /**< The action function */ + const void * node_local_data, /**< Node local data available to all + Tasks using this Action */ + mtapi_size_t node_local_data_size, /**< Size of node local data */ + ActionAttributes const & attributes + /**< Attributes of the Action */ + ) { + return Action(job_id, func, node_local_data, node_local_data_size, + &attributes.GetInternal()); + } + + /** + * Constructs an Action. + */ + Action CreateAction( + mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ + mtapi_action_function_t func, /**< The action function */ + const void * node_local_data, /**< Node local data available to all + Tasks using this Action */ + mtapi_size_t node_local_data_size /**< Size of node local data */ + ) { + return Action(job_id, func, node_local_data, node_local_data_size, + MTAPI_DEFAULT_ACTION_ATTRIBUTES); + } + + /** + * Constructs an Action. + */ + Action CreateAction( + mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ + mtapi_action_function_t func, /**< The action function */ + ActionAttributes const & attributes + /**< Attributes of the Action */ + ) { + return Action(job_id, func, MTAPI_NULL, 0, &attributes.GetInternal()); + } + + /** + * Constructs an Action. + */ + Action CreateAction( + mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ + mtapi_action_function_t func /**< The action function */ + ) { + return Action(job_id, func, MTAPI_NULL, 0, MTAPI_DEFAULT_ACTION_ATTRIBUTES); + } + + /** + * Constructs a Group object with default attributes. + */ + Group CreateGroup() { + return Group(MTAPI_GROUP_ID_NONE, MTAPI_DEFAULT_GROUP_ATTRIBUTES); + } + + /** + * Constructs a Group object with default attributes and the given ID. + */ + Group CreateGroup( + mtapi_group_id_t id /**< A user defined ID of the Group. */ + ) { + return Group(id, MTAPI_DEFAULT_GROUP_ATTRIBUTES); + } + + /** + * Constructs a Group object using the given Attributes. + */ + Group CreateGroup( + GroupAttributes const & group_attr) { + return Group(MTAPI_GROUP_ID_NONE, &group_attr.GetInternal()); + } + + /** + * Constructs a Group object with given attributes and ID. + */ + Group CreateGroup( + mtapi_group_id_t id, /**< A user defined ID of the Group. */ + GroupAttributes const & group_attr /**< The GroupAttributes to use. */ + ) { + return Group(id, &group_attr.GetInternal()); + } + + /** + * Constructs a Queue with the given Job and default attributes. + */ + Queue CreateQueue( + Job & job /**< The Job to use for the Queue. */ + ) { + return Queue(MTAPI_QUEUE_ID_NONE, job, MTAPI_DEFAULT_QUEUE_ATTRIBUTES); + } + + /** + * Constructs a Queue with the given Job and QueueAttributes. + */ + Queue CreateQueue( + Job const & job, /**< The Job to use for the Queue. */ + QueueAttributes const & attr /**< The attributes to use. */ + ) { + return Queue(MTAPI_QUEUE_ID_NONE, job, &attr.GetInternal()); + } + friend class embb::base::Allocation; private: @@ -251,21 +411,17 @@ class Node { NodeAttributes const & attr) { mtapi_status_t status; mtapi_info_t info; + queue_count_ = attr.GetInternal().max_queues; + group_count_ = attr.GetInternal().max_groups; + task_limit_ = attr.GetInternal().max_tasks; mtapi_initialize(domain_id, node_id, &attr.GetInternal(), &info, &status); - needs_finalize_ = status == MTAPI_SUCCESS; internal::CheckStatus(status); core_count_ = info.hardware_concurrency; worker_thread_count_ = embb_core_set_count( &attr.GetInternal().core_affinity); - } - ~Node() { - if (needs_finalize_) { - mtapi_status_t status; - mtapi_finalize(&status); - internal::CheckStatus(status); - } + domain_id_ = domain_id; } Task Start( @@ -286,11 +442,31 @@ class Node { return Task(task_hndl); } + static void ActionFunction( + const void* args, + mtapi_size_t /*args_size*/, + void* /*result_buffer*/, + mtapi_size_t /*result_buffer_size*/, + const void* /*node_local_data*/, + mtapi_size_t /*node_local_data_size*/, + mtapi_task_context_t * context) { + TaskContext task_context(context); + embb::base::Function * func = + reinterpret_cast*>( + const_cast(args)); + (*func)(task_context); + embb::base::Allocation::Delete(func); + } + static embb::mtapi::Node * node_instance_; + mtapi_domain_t domain_id_; mtapi_uint_t core_count_; mtapi_uint_t worker_thread_count_; - bool needs_finalize_; + mtapi_uint_t queue_count_; + mtapi_uint_t group_count_; + mtapi_uint_t task_limit_; + Action function_action_; }; } // namespace mtapi diff --git a/mtapi_cpp/include/embb/mtapi/queue.h b/mtapi_cpp/include/embb/mtapi/queue.h index 718fac3..5f372b2 100644 --- a/mtapi_cpp/include/embb/mtapi/queue.h +++ b/mtapi_cpp/include/embb/mtapi/queue.h @@ -51,31 +51,19 @@ namespace mtapi { */ class Queue { public: - /** - * Constructs a Queue with the given Job and default attributes. - * Requires an initialized Node. - */ - Queue( - Job const & job /**< The Job to use for the Queue. */ - ) { - Create(MTAPI_QUEUE_ID_NONE, job, MTAPI_DEFAULT_QUEUE_ATTRIBUTES); + Queue(Queue const & other) : handle_(other.handle_) { + // empty } - /** - * Constructs a Queue with the given Job and QueueAttributes. - * Requires an initialized Node. - */ - Queue( - Job const & job, /**< The Job to use for the Queue. */ - QueueAttributes const & attr /**< The attributes to use. */ - ) { - Create(MTAPI_QUEUE_ID_NONE, job, &attr.GetInternal()); + Queue & operator=(Queue const & other) { + handle_ = other.handle_; + return *this; } /** - * Destroys a Queue object. + * Deletes a Queue object. */ - ~Queue() { + void Delete() { mtapi_queue_delete(handle_, MTAPI_INFINITE, MTAPI_NULL); } @@ -272,16 +260,13 @@ class Queue { } friend class embb::base::Allocation; + friend class Node; private: // no default constructor Queue(); - // not copyable - Queue(Queue const & other); - void operator=(Queue const & other); - - void Create( + Queue( mtapi_queue_id_t queue_id, Job const & job, mtapi_queue_attributes_t const * attributes diff --git a/mtapi_cpp/include/embb/mtapi/task_attributes.h b/mtapi_cpp/include/embb/mtapi/task_attributes.h index 7c16094..2e7a305 100644 --- a/mtapi_cpp/include/embb/mtapi/task_attributes.h +++ b/mtapi_cpp/include/embb/mtapi/task_attributes.h @@ -29,6 +29,7 @@ #include #include +#include namespace embb { namespace mtapi { @@ -86,6 +87,31 @@ class TaskAttributes { } /** + * Sets the affinity of a Task. + * The affinity influences on which worker the Task will be executed. + * + * \returns Reference to this object. + * \notthreadsafe + */ + TaskAttributes & SetAffinity( + mtapi_affinity_t affinity /**< The affinity to set. */ + ) { + mtapi_status_t status; + mtapi_taskattr_set(&attributes_, MTAPI_TASK_AFFINITY, + &affinity, sizeof(affinity), &status); + internal::CheckStatus(status); + return *this; + } + + TaskAttributes & SetPolicy( + ExecutionPolicy const & policy + ) { + SetPriority(policy.GetPriority()); + SetAffinity(policy.GetAffinity()); + return *this; + } + + /** * Sets the number of instances in a Task. * The Task will be launched \c instances times. In the action function, * the number of instances and the current instance can be queried from diff --git a/tasks_cpp/src/execution_policy.cc b/mtapi_cpp/src/execution_policy.cc similarity index 91% rename from tasks_cpp/src/execution_policy.cc rename to mtapi_cpp/src/execution_policy.cc index b7e9b96..8923f18 100644 --- a/tasks_cpp/src/execution_policy.cc +++ b/mtapi_cpp/src/execution_policy.cc @@ -24,18 +24,18 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include -#include +#include +#include #include #include #include namespace embb { -namespace tasks { +namespace mtapi { ExecutionPolicy::ExecutionPolicy() : priority_(DefaultPriority) { -#if TASKS_CPP_AUTOMATIC_INITIALIZE +#if MTAPI_CPP_AUTOMATIC_INITIALIZE Node::GetInstance(); // MTAPI has to be initialized #endif mtapi_status_t status; @@ -48,7 +48,7 @@ ExecutionPolicy::ExecutionPolicy() : ExecutionPolicy::ExecutionPolicy(bool initial_affinity, mtapi_uint_t priority) :priority_(priority) { -#if TASKS_CPP_AUTOMATIC_INITIALIZE +#if MTAPI_CPP_AUTOMATIC_INITIALIZE Node::GetInstance(); // MTAPI has to be initialized #endif mtapi_status_t status; @@ -62,7 +62,7 @@ ExecutionPolicy::ExecutionPolicy(bool initial_affinity, mtapi_uint_t priority) ExecutionPolicy::ExecutionPolicy(mtapi_uint_t priority) :priority_(priority) { -#if TASKS_CPP_AUTOMATIC_INITIALIZE +#if MTAPI_CPP_AUTOMATIC_INITIALIZE Node::GetInstance(); // MTAPI has to be initialized #endif mtapi_status_t status; @@ -75,7 +75,7 @@ ExecutionPolicy::ExecutionPolicy(mtapi_uint_t priority) ExecutionPolicy::ExecutionPolicy(bool initial_affinity) :priority_(DefaultPriority) { -#if TASKS_CPP_AUTOMATIC_INITIALIZE +#if MTAPI_CPP_AUTOMATIC_INITIALIZE Node::GetInstance(); // MTAPI has to be initialized #endif mtapi_status_t status; @@ -110,7 +110,7 @@ unsigned int ExecutionPolicy::GetCoreCount() const { return embb_bitset_count(&affinity_); } -const mtapi_affinity_t &ExecutionPolicy::GetAffinity() const { +mtapi_affinity_t ExecutionPolicy::GetAffinity() const { return affinity_; } @@ -120,5 +120,5 @@ mtapi_uint_t ExecutionPolicy::GetPriority() const { const mtapi_uint_t ExecutionPolicy::DefaultPriority = 0; -} // namespace tasks +} // namespace mtapi } // namespace embb diff --git a/mtapi_cpp/src/node.cc b/mtapi_cpp/src/node.cc index 9b77f2c..e8dbedc 100644 --- a/mtapi_cpp/src/node.cc +++ b/mtapi_cpp/src/node.cc @@ -25,11 +25,79 @@ */ #include +#include namespace embb { namespace mtapi { embb::mtapi::Node * embb::mtapi::Node::node_instance_ = NULL; +#if MTAPI_CPP_AUTOMATIC_INITIALIZE +static embb_spinlock_t init_mutex = { { 0 } }; +#endif + +void Node::Initialize( + mtapi_domain_t domain_id, + mtapi_node_t node_id + ) { + if (IsInitialized()) { + EMBB_THROW(StatusException, + "MTAPI: node was already initialized."); + } else { + NodeAttributes attributes; // default attributes + node_instance_ = embb::base::Allocation::New( + domain_id, node_id, attributes); + node_instance_->function_action_ = + node_instance_->CreateAction(EMBB_MTAPI_FUNCTION_JOB_ID, ActionFunction); + } +} + +void Node::Initialize( + mtapi_domain_t domain_id, + mtapi_node_t node_id, + NodeAttributes const & attributes + ) { + if (IsInitialized()) { + EMBB_THROW(StatusException, + "MTAPI: node was already initialized."); + } else { + node_instance_ = embb::base::Allocation::New( + domain_id, node_id, attributes); + } +} + +Node & Node::GetInstance() { +#if MTAPI_CPP_AUTOMATIC_INITIALIZE + if (!IsInitialized()) { + embb_spin_lock(&init_mutex); + if (!IsInitialized()) { + Node::Initialize( + MTAPI_CPP_AUTOMATIC_DOMAIN_ID, MTAPI_CPP_AUTOMATIC_NODE_ID); + atexit(Node::Finalize); + } + embb_spin_unlock(&init_mutex); + } + return *node_instance_; +#else + if (IsInitialized()) { + return *node_instance_; + } else { + EMBB_THROW(StatusException, + "MTAPI: node is not initialized."); + } +#endif +} + +void Node::Finalize() { + if (IsInitialized()) { + node_instance_->function_action_.Delete(); + mtapi_finalize(MTAPI_NULL); + embb::base::Allocation::Delete(node_instance_); + node_instance_ = NULL; + } else { + EMBB_THROW(StatusException, + "MTAPI: node is not initialized."); + } +} } // namespace mtapi } // namespace embb diff --git a/mtapi_cpp/test/mtapi_cpp_test_group.cc b/mtapi_cpp/test/mtapi_cpp_test_group.cc index 1378311..b89bdf8 100644 --- a/mtapi_cpp/test/mtapi_cpp_test_group.cc +++ b/mtapi_cpp/test/mtapi_cpp_test_group.cc @@ -61,12 +61,14 @@ GroupTest::GroupTest() { void GroupTest::TestBasic() { embb::mtapi::Node::Initialize(THIS_DOMAIN_ID, THIS_NODE_ID); + embb::mtapi::Node & node = embb::mtapi::Node::GetInstance(); - embb::mtapi::Job job(JOB_TEST_GROUP, THIS_DOMAIN_ID); - embb::mtapi::Action action(JOB_TEST_GROUP, testGroupAction); + embb::mtapi::Job job = node.GetJob(JOB_TEST_GROUP); + embb::mtapi::Action action = + node.CreateAction(JOB_TEST_GROUP, testGroupAction); { - embb::mtapi::Group group; + embb::mtapi::Group group = node.CreateGroup(); result_example_t buffer[TASK_COUNT]; for (int ii = 0; ii < TASK_COUNT; ii++) { @@ -86,7 +88,7 @@ void GroupTest::TestBasic() { } { - embb::mtapi::Group group; + embb::mtapi::Group group = node.CreateGroup(); result_example_t buffer[TASK_COUNT]; for (int ii = 0; ii < 4; ii++) { @@ -107,6 +109,7 @@ void GroupTest::TestBasic() { PT_EXPECT_EQ(status, MTAPI_GROUP_COMPLETED); } + action.Delete(); embb::mtapi::Node::Finalize(); PT_EXPECT_EQ(embb_get_bytes_allocated(), 0u); diff --git a/mtapi_cpp/test/mtapi_cpp_test_queue.cc b/mtapi_cpp/test/mtapi_cpp_test_queue.cc index 8e17abf..8b77601 100644 --- a/mtapi_cpp/test/mtapi_cpp_test_queue.cc +++ b/mtapi_cpp/test/mtapi_cpp_test_queue.cc @@ -54,13 +54,14 @@ QueueTest::QueueTest() { void QueueTest::TestBasic() { embb::mtapi::Node::Initialize(THIS_DOMAIN_ID, THIS_NODE_ID); + embb::mtapi::Node & node = embb::mtapi::Node::GetInstance(); - embb::mtapi::Job job(JOB_TEST_QUEUE, THIS_DOMAIN_ID); - embb::mtapi::Action action(JOB_TEST_QUEUE, testQueueAction, - MTAPI_NULL, 0); + embb::mtapi::Job job = node.GetJob(JOB_TEST_QUEUE); + embb::mtapi::Action action = node.CreateAction( + JOB_TEST_QUEUE, testQueueAction, MTAPI_NULL, 0); { - embb::mtapi::Queue queue(job); + embb::mtapi::Queue queue = node.CreateQueue(job); int result = 0; embb::mtapi::Task task = queue.Enqueue(MTAPI_NULL, &result); @@ -72,6 +73,7 @@ void QueueTest::TestBasic() { PT_EXPECT_EQ(result, 1); } + action.Delete(); embb::mtapi::Node::Finalize(); PT_EXPECT_EQ(embb_get_bytes_allocated(), 0u); diff --git a/mtapi_cpp/test/mtapi_cpp_test_task.cc b/mtapi_cpp/test/mtapi_cpp_test_task.cc index fa3de4e..9712c26 100644 --- a/mtapi_cpp/test/mtapi_cpp_test_task.cc +++ b/mtapi_cpp/test/mtapi_cpp_test_task.cc @@ -96,9 +96,10 @@ void TaskTest::TestBasic() { } { - embb::mtapi::Job job_task(JOB_TEST_TASK, THIS_DOMAIN_ID); + embb::mtapi::Job job_task = node.GetJob(JOB_TEST_TASK); - embb::mtapi::Action action_task(JOB_TEST_TASK, testTaskAction); + embb::mtapi::Action action_task = + node.CreateAction(JOB_TEST_TASK, testTaskAction); std::string test; embb::mtapi::Task task = node.Start(job_task, "simple", &test); @@ -106,19 +107,23 @@ void TaskTest::TestBasic() { mtapi_status_t status = task.Wait(); PT_EXPECT_EQ(status, MTAPI_SUCCESS); PT_EXPECT(test == "simple"); + + action_task.Delete(); } { - embb::mtapi::Job job_error(JOB_TEST_ERROR, THIS_DOMAIN_ID); + embb::mtapi::Job job_error = node.GetJob(JOB_TEST_ERROR); - embb::mtapi::Action action_error(JOB_TEST_ERROR, testErrorAction, - embb::mtapi::ActionAttributes()); + embb::mtapi::Action action_error = + node.CreateAction(JOB_TEST_ERROR, testErrorAction); std::string test; embb::mtapi::Task task = node.Start(job_error, "simple", &test); testDoSomethingElse(); mtapi_status_t status = task.Wait(); PT_EXPECT_EQ(status, MTAPI_ERR_ACTION_FAILED); + + action_error.Delete(); } embb::mtapi::Node::Finalize(); diff --git a/mtapi_plugins_c/mtapi_network_c/CMakeLists.txt b/mtapi_plugins_c/mtapi_network_c/CMakeLists.txt index a23a903..8c4b63b 100644 --- a/mtapi_plugins_c/mtapi_network_c/CMakeLists.txt +++ b/mtapi_plugins_c/mtapi_network_c/CMakeLists.txt @@ -45,3 +45,8 @@ endif() install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include FILES_MATCHING PATTERN "*.h") install(TARGETS embb_mtapi_network_c DESTINATION lib) +if (MSVC) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Debug/embb_mtapi_network_c.pdb + DESTINATION lib + CONFIGURATIONS Debug) +endif() diff --git a/mtapi_plugins_c/mtapi_opencl_c/CMakeLists.txt b/mtapi_plugins_c/mtapi_opencl_c/CMakeLists.txt index 7dd94de..91b8f87 100644 --- a/mtapi_plugins_c/mtapi_opencl_c/CMakeLists.txt +++ b/mtapi_plugins_c/mtapi_opencl_c/CMakeLists.txt @@ -45,3 +45,8 @@ endif() install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include FILES_MATCHING PATTERN "*.h") install(TARGETS embb_mtapi_opencl_c DESTINATION lib) +if (MSVC) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Debug/embb_mtapi_opencl_c.pdb + DESTINATION lib + CONFIGURATIONS Debug) +endif() diff --git a/scripts/run_cpplint.sh b/scripts/run_cpplint.sh index cec5393..106d6e4 100755 --- a/scripts/run_cpplint.sh +++ b/scripts/run_cpplint.sh @@ -79,7 +79,7 @@ retval=0 ##Excluded files RAND_FILES=( embb_mtapi_test_group.cc embb_mtapi_test_queue.cc embb_mtapi_test_task.cc queue_test-inl.h ) -for project in base_c mtapi_c mtapi_plugins_c/mtapi_network_c mtapi_plugins_c/mtapi_opencl_c base_cpp mtapi_cpp tasks_cpp algorithms_cpp containers_cpp dataflow_cpp +for project in base_c mtapi_c mtapi_plugins_c/mtapi_network_c mtapi_plugins_c/mtapi_opencl_c base_cpp mtapi_cpp algorithms_cpp containers_cpp dataflow_cpp do echo "-> Doing project: $project" dir=$d/$project diff --git a/tasks_cpp/CMakeLists.txt b/tasks_cpp/CMakeLists.txt deleted file mode 100644 index 397be86..0000000 --- a/tasks_cpp/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -project (project_tasks_cpp) - -file(GLOB_RECURSE EMBB_TASKS_CPP_SOURCES "src/*.cc" "src/*.h") -file(GLOB_RECURSE EMBB_TASKS_CPP_HEADERS "include/*.h") -file(GLOB_RECURSE EMBB_TASKS_CPP_TEST_SOURCES "test/*.cc" "test/*.h") - -if (USE_AUTOMATIC_INITIALIZATION STREQUAL ON) - set(TASKS_CPP_AUTOMATIC_INITIALIZE 1) -else() - set(TASKS_CPP_AUTOMATIC_INITIALIZE 0) -endif() - -configure_file("include/embb/tasks/internal/cmake_config.h.in" - "include/embb/tasks/internal/cmake_config.h") - -# Execute the GroupSources macro -include(${CMAKE_SOURCE_DIR}/CMakeCommon/GroupSourcesMSVC.cmake) -GroupSourcesMSVC(include) -GroupSourcesMSVC(src) -GroupSourcesMSVC(test) - -set (EMBB_TASKS_CPP_INCLUDE_DIRS "include" "src" "test") -include_directories(${EMBB_TASKS_CPP_INCLUDE_DIRS} - ${CMAKE_CURRENT_BINARY_DIR}/include - ${CMAKE_CURRENT_SOURCE_DIR}/../base_c/include - ${CMAKE_CURRENT_BINARY_DIR}/../base_c/include - ${CMAKE_CURRENT_SOURCE_DIR}/../base_cpp/include - ${CMAKE_CURRENT_BINARY_DIR}/../base_cpp/include - ${CMAKE_CURRENT_SOURCE_DIR}/../mtapi_c/include) - -add_library (embb_tasks_cpp ${EMBB_TASKS_CPP_SOURCES} ${EMBB_TASKS_CPP_HEADERS}) -target_link_libraries(embb_tasks_cpp embb_mtapi_c) - -if (BUILD_TESTS STREQUAL ON) - include_directories(${CMAKE_CURRENT_BINARY_DIR}/../partest/include) - add_executable (embb_tasks_cpp_test ${EMBB_TASKS_CPP_TEST_SOURCES}) - target_link_libraries(embb_tasks_cpp_test embb_tasks_cpp embb_mtapi_c partest - embb_base_cpp embb_base_c ${compiler_libs}) - CopyBin(BIN embb_tasks_cpp_test DEST ${local_install_dir}) -endif() - -install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ - DESTINATION include FILES_MATCHING PATTERN "*.h") -install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/ - DESTINATION include FILES_MATCHING PATTERN "*.h") -install(TARGETS embb_tasks_cpp DESTINATION lib) diff --git a/tasks_cpp/include/embb/tasks/action.h b/tasks_cpp/include/embb/tasks/action.h deleted file mode 100644 index e034cbf..0000000 --- a/tasks_cpp/include/embb/tasks/action.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef EMBB_TASKS_ACTION_H_ -#define EMBB_TASKS_ACTION_H_ - -#include -#include -#include - -namespace embb { -namespace tasks { - -/** - * A function to be spawned as a Task. - * - * \ingroup CPP_TASKS - */ -class Action { - public: - /** - * Constructs an empty Action. - */ - Action() - : function_() - , execution_policy_() { - // empty - } - - /** - * Constructs an Action from a function object. - * - * \tparam Function Function object - */ - template - Action( - Function func /**< [in] Function object */ - ) - : function_(func) - , execution_policy_() { - // empty - } - - /** - * Constructs an Action from a function object and an Affinity. - * - * \tparam Function Function object - */ - template - Action( - Function func, /**< [in] Function object */ - ExecutionPolicy execution_policy /**< [in] Execution policy */ - ) - : function_(func) - , execution_policy_(execution_policy) { - // empty - } - - /** - * Executes the Action in a given TaskContext. - */ - void operator() ( - TaskContext & context /**< [in, out] Context the operator - is executed in */ - ) { - function_(context); - } - - /** - * Returns the ExecutionPolicy specified during creation. - * \return The ExecutionPolicy of the Action - * \waitfree - */ - ExecutionPolicy GetExecutionPolicy() const { - return execution_policy_; - } - - private: - embb::base::Function function_; - ExecutionPolicy execution_policy_; -}; - -} // namespace tasks -} // namespace embb - -#endif // EMBB_TASKS_ACTION_H_ diff --git a/tasks_cpp/include/embb/tasks/continuation.h b/tasks_cpp/include/embb/tasks/continuation.h deleted file mode 100644 index 30c2922..0000000 --- a/tasks_cpp/include/embb/tasks/continuation.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef EMBB_TASKS_CONTINUATION_H_ -#define EMBB_TASKS_CONTINUATION_H_ - -#include -#include -#include -#include - -namespace embb { -namespace tasks { - -/** - * Helper struct for Continuation. - * - * \ingroup CPP_TASKS - */ -struct ContinuationStage; - -/** - * A Continuation encapsulates a chain of \link Action Actions \endlink to be - * executed consecutively. - * - * \ingroup CPP_TASKS - */ -class Continuation { - public: - /** - * Copies a Continuation. - */ - Continuation( - Continuation const & cont /**< [in] The Continuation to copy. */ - ); - - /** - * Destroys a Continuation. - */ - ~Continuation(); - - /** - * Appends an Action to the Continuation chain. - * \returns A reference to this Continuation chain. - * \notthreadsafe - */ - Continuation & Then( - Action action /**< [in] The Action to append to the - continuation */ - ); - - /** - * Runs the Continuation chain. - * \returns The Task representing the Continuation chain. - * \notthreadsafe - */ - Task Spawn(); - - /** - * Runs the Continuation chain with the specified execution_policy. - * \returns The Task representing the Continuation chain. - * \notthreadsafe - */ - Task Spawn( - ExecutionPolicy execution_policy /**< [in] The execution policy to use */ - ); - - friend class Node; - - private: - explicit Continuation(Action action); - - void ExecuteContinuation(TaskContext & context); - - ContinuationStage * first_; - ContinuationStage * last_; -}; - -} // namespace tasks -} // namespace embb - -#endif // EMBB_TASKS_CONTINUATION_H_ diff --git a/tasks_cpp/include/embb/tasks/group.h b/tasks_cpp/include/embb/tasks/group.h deleted file mode 100644 index 700f09e..0000000 --- a/tasks_cpp/include/embb/tasks/group.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef EMBB_TASKS_GROUP_H_ -#define EMBB_TASKS_GROUP_H_ - -#include -#include -#include - -namespace embb { - -namespace base { - -class Allocation; - -} // namespace base - -namespace tasks { - -/** - * Represents a facility to wait for multiple related - * \link Task Tasks\endlink. - * - * \ingroup CPP_TASKS - */ -class Group { - public: - /** - * Runs an Action within the Group. - * \return A Task identifying the Action to run - * \throws ErrorException if the Task object could not be constructed. - * \threadsafe - */ - Task Spawn( - Action action /**< [in] The Action to run */ - ); - - /** - * Runs an Action within the Group. The \c id is returned by WaitAny(). - * \return A Task identifying the Action to run - * \throws ErrorException if the Task object could not be constructed. - * \threadsafe - */ - Task Spawn( - mtapi_task_id_t id, /**< [in] The id to return by - WaitAny() */ - Action action /**< [in] The Action to run */ - ); - - /** - * Waits for any Task in the Group to finish for \c timeout milliseconds. - * \return The status of the Task that finished execution - * \threadsafe - */ - mtapi_status_t WaitAny( - mtapi_timeout_t timeout /**< [in] Timeout duration in - milliseconds */ - ); - - /** - * Waits for any Task in the Group to finish for \c timeout milliseconds and - * retrieves the id given in Spawn(). - * \return The status of the Task that finished execution, \c MTAPI_TIMEOUT - * or \c MTAPI_ERR_* - * \threadsafe - */ - mtapi_status_t WaitAny( - mtapi_timeout_t timeout, /**< [in] Timeout duration in - milliseconds */ - mtapi_task_id_t & id /**< [out] The id given to Spawn() */ - ); - - /** - * Waits for all Task in the Group to finish for \c timeout milliseconds. - * \return \c MTAPI_SUCCESS, \c MTAPI_TIMEOUT, \c MTAPI_ERR_* or the status - * of any failed Task - * \threadsafe - */ - mtapi_status_t WaitAll( - mtapi_timeout_t timeout /**< [in] Timeout duration in - milliseconds */ - ); - - friend class embb::base::Allocation; - friend class Node; - friend class Queue; - - private: - Group(Group const & group); - Group(); - ~Group(); - - void Create(); - - mtapi_group_hndl_t handle_; -}; - -} // namespace tasks -} // namespace embb - -#endif // EMBB_TASKS_GROUP_H_ diff --git a/tasks_cpp/include/embb/tasks/node.h b/tasks_cpp/include/embb/tasks/node.h deleted file mode 100644 index 1695f54..0000000 --- a/tasks_cpp/include/embb/tasks/node.h +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef EMBB_TASKS_NODE_H_ -#define EMBB_TASKS_NODE_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace embb { - -namespace base { - -class Allocation; - -} // namespace base - -namespace tasks { - -/** - * A singleton representing the MTAPI runtime. - * - * \ingroup CPP_TASKS - */ -class Node { - public: - /** - * Initializes the runtime singleton using default values: - * - all available cores will be used - * - maximum number of tasks is 1024 - * - maximum number of groups is 128 - * - maximum number of queues is 16 - * - maximum queue capacity is 1024 - * - maximum number of priorities is 4. - * - * \notthreadsafe - * \throws ErrorException if the singleton was already initialized or the - * Node could not be initialized. - * \memory Allocates about 200kb of memory. - */ - static void Initialize( - mtapi_domain_t domain_id, /**< [in] The domain id to use */ - mtapi_node_t node_id /**< [in] The node id to use */ - ); - - /** - * Initializes the runtime singleton. - * \notthreadsafe - * \throws ErrorException if the singleton was already initialized or the - * Node could not be initialized. - * \memory Allocates some memory depending on the values given. - */ - static void Initialize( - mtapi_domain_t domain_id, /**< [in] The domain id to use */ - mtapi_node_t node_id, /**< [in] The node id to use */ - embb::base::CoreSet const & core_set, - /**< [in] A set of cores MTAPI should - use for its worker threads */ - mtapi_uint_t max_tasks, /**< [in] Maximum number of concurrent - \link Task Tasks \endlink */ - mtapi_uint_t max_groups, /**< [in] Maximum number of concurrent - \link Group Groups \endlink */ - mtapi_uint_t max_queues, /**< [in] Maximum number of concurrent - \link Queue Queues \endlink */ - mtapi_uint_t queue_limit, /**< [in] Maximum Queue capacity */ - mtapi_uint_t max_priorities /**< [in] Maximum number of priorities, - priorities will be between 0 and - max_priorities-1 */ - ); - - /** - * Checks if runtime is initialized. - * \return \c true if the Node singleton is already initialized, false - * otherwise - * \waitfree - */ - static bool IsInitialized(); - - /** - * Gets the instance of the runtime system. - * \return Reference to the Node singleton - * \threadsafe - */ - static Node & GetInstance(); - - /** - * Shuts the runtime system down. - * \throws ErrorException if the singleton is not initialized. - * \notthreadsafe - */ - static void Finalize(); - - /** - * Returns the number of available queues. - * \return The number of available queues - * \waitfree - */ - mtapi_uint_t GetQueueCount() const { - return queue_count_; - } - - /** - * Returns the number of available groups. - * \return The number of available groups - * \waitfree - */ - mtapi_uint_t GetGroupCount() const { - return group_count_; - } - - /** - * Returns the number of available tasks. - * \return The number of available tasks - * \waitfree - */ - mtapi_uint_t GetTaskLimit() const { - return task_limit_; - } - - /** - * Returns the number of available cores. - * \return The number of available cores - * \waitfree - */ - mtapi_uint_t GetCoreCount() const { - return core_count_; - } - - /** - * Returns the number of worker threads. - * \return The number of worker threads. - * \waitfree - */ - mtapi_uint_t GetWorkerThreadCount() const { - return worker_thread_count_; - } - - /** - * Creates a Group to launch \link Task Tasks \endlink in. - * \return A reference to the created Group - * \throws ErrorException if the Group object could not be constructed. - * \threadsafe - * \memory Allocates some memory depending on the configuration of the - * runtime. - */ - Group & CreateGroup(); - - /** - * Destroys a Group. \link Task Tasks \endlink running in the Group will - * finish execution. - * \threadsafe - */ - void DestroyGroup( - Group & group /**< [in,out] The Group to destroy */ - ); - - /** - * Creates a Queue for stream processing. The queue might execute its - * \link Task Tasks \endlink either in order or unordered. - * \return A reference to the new Queue - * \throws ErrorException if the Queue object could not be constructed. - * \threadsafe - * \memory Allocates some memory depending on the configuration of the - * runtime. - */ - Queue & CreateQueue( - mtapi_uint_t priority, /**< [in] Priority of the Queue */ - bool ordered /**< [in] \c true if the Queue should be - ordered, otherwise \c false */ - ); - - /** - * Destroys a Queue. Running \link Task Tasks \endlink will be canceled. - * \threadsafe - */ - void DestroyQueue( - Queue & queue /**< [in,out] The Queue to destroy */ - ); - - /** - * Runs an Action. - * \return A Task identifying the Action to run - * \throws ErrorException if the Task object could not be constructed. - * \threadsafe - */ - Task Spawn( - Action action /**< [in] The Action to execute */ - ); - - /** - * Creates a Continuation. - * \return A Continuation chain - * \threadsafe - */ - Continuation First( - Action action /**< [in] The first Action of the - Continuation chain */ - ); - - friend class embb::base::Allocation; - - private: - Node(Node const & node); - Node( - mtapi_domain_t domain_id, - mtapi_node_t node_id, - mtapi_node_attributes_t * attr); - ~Node(); - - static void action_func( - const void* args, - mtapi_size_t args_size, - void* result_buffer, - mtapi_size_t result_buffer_size, - const void* node_local_data, - mtapi_size_t node_local_data_size, - mtapi_task_context_t * context); - - mtapi_uint_t queue_count_; - mtapi_uint_t group_count_; - mtapi_uint_t task_limit_; - mtapi_uint_t core_count_; - mtapi_uint_t worker_thread_count_; - mtapi_action_hndl_t action_handle_; - std::list queues_; - std::list groups_; - embb::base::Spinlock queue_lock_; - embb::base::Spinlock group_lock_; -}; - -} // namespace tasks -} // namespace embb - -#endif // EMBB_TASKS_NODE_H_ diff --git a/tasks_cpp/include/embb/tasks/queue.h b/tasks_cpp/include/embb/tasks/queue.h deleted file mode 100644 index a4f1479..0000000 --- a/tasks_cpp/include/embb/tasks/queue.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef EMBB_TASKS_QUEUE_H_ -#define EMBB_TASKS_QUEUE_H_ - -#include -#include -#include -#include - -namespace embb { - -namespace base { - -class Allocation; - -} // namespace base - -namespace tasks { - -/** - * Allows for stream processing, either ordered or unordered. - * - * \ingroup CPP_TASKS - */ -class Queue { - public: - /** - * Enables the Queue. \link Task Tasks \endlink enqueued while the Queue was - * disabled are executed. - * \waitfree - */ - void Enable(); - - /** - * Disables the Queue. Running \link Task Tasks \endlink are canceled. - * \waitfree - */ - void Disable(); - - /** - * Runs an Action. - * \return A Task identifying the Action to run - * \throws ErrorException if the Task object could not be constructed. - * \threadsafe - */ - Task Spawn( - Action action /**< [in] The Action to run */ - ); - - /** - * Runs an Action in the specified Group - * \return A Task identifying the Action to run - * \throws ErrorException if the Task object could not be constructed. - * \threadsafe - */ - Task Spawn( - Group const * group, /**< [in] The Group to run the Action - in */ - Action action /**< [in] The Action to run */ - ); - - /** - * Runs an Action in the specified Group. The \c id is returned by - * Group::WaitAny(). - * \return A Task identifying the Action to run - * \throws ErrorException if the Task object could not be constructed. - * \threadsafe - */ - Task Spawn( - mtapi_task_id_t id, /**< [in] The id to return in - Group::WaitAny() */ - Group const * group, /**< [in] The Group to run the Action - in */ - Action action /**< [in] The Action to run */ - ); - - friend class embb::base::Allocation; - friend class Node; - - private: - Queue(Queue const & taskqueue); - Queue(mtapi_uint_t priority, bool ordered); - ~Queue(); - - mtapi_queue_hndl_t handle_; -}; - -} // namespace tasks -} // namespace embb - -#endif // EMBB_TASKS_QUEUE_H_ diff --git a/tasks_cpp/include/embb/tasks/task.h b/tasks_cpp/include/embb/tasks/task.h deleted file mode 100644 index c78d6d1..0000000 --- a/tasks_cpp/include/embb/tasks/task.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef EMBB_TASKS_TASK_H_ -#define EMBB_TASKS_TASK_H_ - -#include -#include - -namespace embb { -namespace tasks { - -/** - * A Task represents a running Action. - * - * \ingroup CPP_TASKS - */ -class Task { - public: - /** - * Constructs an empty Task - */ - Task(); - - /** - * Copies a Task - */ - Task( - Task const & task /**< The task to copy. */ - ); - - /** - * Destroys a Task - */ - ~Task(); - - /** - * Waits for Task to finish for \c timeout milliseconds. - * \return The status of the finished Task, \c MTAPI_TIMEOUT or - * \c MTAPI_ERR_* - * \threadsafe - */ - mtapi_status_t Wait( - mtapi_timeout_t timeout /**< [in] Timeout duration in - milliseconds */ - ); - - /** - * Signals the Task to cancel computation. - * \waitfree - */ - void Cancel(); - - friend class Group; - friend class Queue; - friend class Node; - - private: - Task( - Action action); - - Task( - Action action, - mtapi_group_hndl_t group); - - Task( - mtapi_task_id_t id, - Action action, - mtapi_group_hndl_t group); - - Task( - Action action, - mtapi_queue_hndl_t queue); - - Task( - Action action, - mtapi_queue_hndl_t queue, - mtapi_group_hndl_t group); - - Task( - mtapi_task_id_t id, - Action action, - mtapi_queue_hndl_t queue, - mtapi_group_hndl_t group); - - mtapi_task_hndl_t handle_; -}; - -} // namespace tasks -} // namespace embb - -#endif // EMBB_TASKS_TASK_H_ diff --git a/tasks_cpp/include/embb/tasks/task_context.h b/tasks_cpp/include/embb/tasks/task_context.h deleted file mode 100644 index 9aaa663..0000000 --- a/tasks_cpp/include/embb/tasks/task_context.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef EMBB_TASKS_TASK_CONTEXT_H_ -#define EMBB_TASKS_TASK_CONTEXT_H_ - -#include - -namespace embb { -namespace tasks { - -/** - * Provides information about the status of the currently running Task. - * - * \ingroup CPP_TASKS - */ -class TaskContext { - public: - /** - * Queries whether the Task running in the TaskContext should finish. - * \return \c true if the Task should finish, otherwise \c false - * \notthreadsafe - */ - bool ShouldCancel(); - - /** - * Queries the index of the worker thread the Task is running on. - * \return The worker thread index the Task is running on - * \notthreadsafe - */ - mtapi_uint_t GetCurrentCoreNumber(); - - /** - * Sets the return status of the running Task. This will be returned by - * Task::Wait() and is set to \c MTAPI_SUCCESS by default. - * \notthreadsafe - */ - void SetStatus( - mtapi_status_t error_code /**< [in] The status to return by - Task::Wait(), Group::WaitAny(), - Group::WaitAll() */ - ); - - friend class Node; - - private: - explicit TaskContext(mtapi_task_context_t * task_context); - - mtapi_task_context_t * context_; -}; - -} // namespace tasks -} // namespace embb - -#endif // EMBB_TASKS_TASK_CONTEXT_H_ diff --git a/tasks_cpp/include/embb/tasks/tasks.h b/tasks_cpp/include/embb/tasks/tasks.h deleted file mode 100644 index bb3e3d5..0000000 --- a/tasks_cpp/include/embb/tasks/tasks.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef EMBB_TASKS_TASKS_H_ -#define EMBB_TASKS_TASKS_H_ - -/** - * \defgroup CPP_TASKS Tasks - * Simple task management based on MTAPI. - * \ingroup CPP - */ - -#include - -#define TASKS_CPP_JOB 1 -#if TASKS_CPP_AUTOMATIC_INITIALIZE -#define TASKS_CPP_AUTOMATIC_DOMAIN_ID 1 -#define TASKS_CPP_AUTOMATIC_NODE_ID 1 -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#endif // EMBB_TASKS_TASKS_H_ diff --git a/tasks_cpp/src/continuation.cc b/tasks_cpp/src/continuation.cc deleted file mode 100644 index 330fae3..0000000 --- a/tasks_cpp/src/continuation.cc +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include -#include - -#include - -namespace embb { -namespace tasks { - -Continuation::Continuation(Action action) { - first_ = last_ = embb::base::Allocation::New(); - first_->action = action; - first_->next = NULL; -} - -Continuation::Continuation(Continuation const & cont) - : first_(cont.first_) - , last_(cont.last_) { -} - -Continuation::~Continuation() { -} - -void Continuation::ExecuteContinuation(TaskContext &) { - ContinuationStage * stage = first_; - Node & node = Node::GetInstance(); - while (NULL != stage) { - Task task = node.Spawn(stage->action); - task.Wait(MTAPI_INFINITE); - stage = stage->next; - } - - // delete stages - stage = first_; - while (NULL != stage) { - ContinuationStage * next = stage->next; - embb::base::Allocation::Delete(stage); - stage = next; - } -} - -Continuation & Continuation::Then(Action action) { - ContinuationStage * cur = embb::base::Allocation::New(); - cur->action = action; - cur->next = NULL; - - last_->next = cur; - last_ = cur; - - return *this; -} - -Task Continuation::Spawn() { - return Spawn(ExecutionPolicy()); -} - -Task Continuation::Spawn(ExecutionPolicy execution_policy) { - Node & node = Node::GetInstance(); - return node.Spawn( - Action( - embb::base::MakeFunction(*this, &Continuation::ExecuteContinuation), - ExecutionPolicy(execution_policy))); -} - -} // namespace tasks -} // namespace embb diff --git a/tasks_cpp/src/continuationstage.h b/tasks_cpp/src/continuationstage.h deleted file mode 100644 index 79d260f..0000000 --- a/tasks_cpp/src/continuationstage.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TASKS_CPP_SRC_CONTINUATIONSTAGE_H_ -#define TASKS_CPP_SRC_CONTINUATIONSTAGE_H_ - -#include - -namespace embb { -namespace tasks { - -struct ContinuationStage { - Action action; - ContinuationStage * next; -}; - -} // namespace tasks -} // namespace embb - -#endif // TASKS_CPP_SRC_CONTINUATIONSTAGE_H_ diff --git a/tasks_cpp/src/group.cc b/tasks_cpp/src/group.cc deleted file mode 100644 index 04971a8..0000000 --- a/tasks_cpp/src/group.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include - -namespace embb { -namespace tasks { - -Group::Group() { - Create(); -} - -Group::~Group() { - mtapi_status_t status; - mtapi_group_delete(handle_, &status); - assert(MTAPI_SUCCESS == status); -} - -void Group::Create() { - mtapi_status_t status; - handle_ = mtapi_group_create(MTAPI_GROUP_ID_NONE, MTAPI_NULL, &status); - if (MTAPI_SUCCESS != status) { - EMBB_THROW(embb::base::ErrorException, - "mtapi::Group could not be constructed"); - } -} - -Task Group::Spawn(Action action) { - return Task(action, handle_); -} - -Task Group::Spawn(mtapi_task_id_t id, Action action) { - return Task(id, action, handle_); -} - -mtapi_status_t Group::WaitAny(mtapi_timeout_t timeout) { - mtapi_status_t status; - mtapi_group_wait_any(handle_, MTAPI_NULL, timeout, &status); - if (MTAPI_GROUP_COMPLETED == status) { - // group has been deleted, so recreate it for simplicity - Create(); - } - return status; -} - -mtapi_status_t Group::WaitAny( - mtapi_timeout_t timeout, - mtapi_task_id_t & result) { - mtapi_status_t status; - void * res; - mtapi_group_wait_any(handle_, &res, timeout, &status); - memcpy(&result, &res, sizeof(result)); - if (MTAPI_GROUP_COMPLETED == status) { - // group has been deleted, so recreate it for simplicity - Create(); - } - return status; -} - -mtapi_status_t Group::WaitAll(mtapi_timeout_t timeout) { - mtapi_status_t status; - mtapi_group_wait_all(handle_, timeout, &status); - // group has been deleted, so recreate it for simplicity - Create(); - return status; -} - -} // namespace tasks -} // namespace embb diff --git a/tasks_cpp/src/node.cc b/tasks_cpp/src/node.cc deleted file mode 100644 index 6d92e9c..0000000 --- a/tasks_cpp/src/node.cc +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#if TASKS_CPP_AUTOMATIC_INITIALIZE -#include -#endif - -namespace { - -static embb::tasks::Node * node_instance = NULL; -#if TASKS_CPP_AUTOMATIC_INITIALIZE -static embb_spinlock_t init_mutex = { { 0 } }; -#endif - -} - -namespace embb { -namespace tasks { - -void Node::action_func( - const void* args, - mtapi_size_t /*args_size*/, - void* /*result_buffer*/, - mtapi_size_t /*result_buffer_size*/, - const void* /*node_local_data*/, - mtapi_size_t /*node_local_data_size*/, - mtapi_task_context_t * context) { - Action * action = - reinterpret_cast(const_cast(args)); - TaskContext task_context(context); - (*action)(task_context); - embb::base::Allocation::Delete(action); -} - -Node::Node( - mtapi_domain_t domain_id, - mtapi_node_t node_id, - mtapi_node_attributes_t * attr) { - mtapi_status_t status; - mtapi_info_t info; - mtapi_initialize(domain_id, node_id, attr, &info, &status); - if (MTAPI_SUCCESS != status) { - EMBB_THROW(embb::base::ErrorException, - "mtapi::Node could not initialize mtapi"); - } - mtapi_node_get_attribute(node_id, MTAPI_NODE_MAX_QUEUES, &queue_count_, - sizeof(queue_count_), &status); - assert(MTAPI_SUCCESS == status); - mtapi_node_get_attribute(node_id, MTAPI_NODE_MAX_GROUPS, &group_count_, - sizeof(group_count_), &status); - assert(MTAPI_SUCCESS == status); - mtapi_node_get_attribute(node_id, MTAPI_NODE_MAX_TASKS, &task_limit_, - sizeof(queue_count_), &status); - assert(MTAPI_SUCCESS == status); - core_count_ = info.hardware_concurrency; - worker_thread_count_ = embb_core_set_count(&attr->core_affinity); - action_handle_ = mtapi_action_create(TASKS_CPP_JOB, action_func, - MTAPI_NULL, 0, MTAPI_NULL, &status); - if (MTAPI_SUCCESS != status) { - EMBB_THROW(embb::base::ErrorException, - "mtapi::Node could not create an action"); - } -} - -Node::~Node() { - for (std::list::iterator ii = queues_.begin(); - ii != queues_.end(); - ++ii) { - embb::base::Allocation::Delete(*ii); - } - queues_.clear(); - - for (std::list::iterator ii = groups_.begin(); - ii != groups_.end(); - ++ii) { - embb::base::Allocation::Delete(*ii); - } - groups_.clear(); - - mtapi_status_t status; - mtapi_action_delete(action_handle_, MTAPI_INFINITE, &status); - assert(MTAPI_SUCCESS == status); - mtapi_finalize(&status); - assert(MTAPI_SUCCESS == status); -} - -void Node::Initialize( - mtapi_domain_t domain_id, - mtapi_node_t node_id) { - if (IsInitialized()) { - EMBB_THROW(embb::base::ErrorException, - "mtapi::Node was already initialized"); - } else { - mtapi_status_t status; - mtapi_node_attributes_t attr; - mtapi_uint_t tmp; - mtapi_nodeattr_init(&attr, &status); - assert(MTAPI_SUCCESS == status); - tmp = 4; - mtapi_nodeattr_set(&attr, MTAPI_NODE_MAX_ACTIONS, - &tmp, sizeof(tmp), &status); - assert(MTAPI_SUCCESS == status); - // tmp = 4; - mtapi_nodeattr_set(&attr, MTAPI_NODE_MAX_JOBS, - &tmp, sizeof(tmp), &status); - assert(MTAPI_SUCCESS == status); - tmp = 1; - mtapi_nodeattr_set(&attr, MTAPI_NODE_MAX_ACTIONS_PER_JOB, - &tmp, sizeof(tmp), &status); - assert(MTAPI_SUCCESS == status); - node_instance = embb::base::Allocation::New( - domain_id, node_id, &attr); - } -} - -void Node::Initialize( - mtapi_domain_t domain_id, - mtapi_node_t node_id, - embb::base::CoreSet const & core_set, - mtapi_uint_t max_tasks, - mtapi_uint_t max_groups, - mtapi_uint_t max_queues, - mtapi_uint_t queue_limit, - mtapi_uint_t max_priorities) { - if (IsInitialized()) { - EMBB_THROW(embb::base::ErrorException, - "mtapi::Node was already initialized"); - } else { - mtapi_status_t status; - mtapi_node_attributes_t attr; - mtapi_uint_t tmp; - mtapi_nodeattr_init(&attr, &status); - assert(MTAPI_SUCCESS == status); - embb_core_set_t cs; - embb_core_set_init(&cs, 0); - for (unsigned int ii = 0; embb_core_set_count(&cs) < core_set.Count(); - ii++) { - if (core_set.IsContained(ii)) { - embb_core_set_add(&cs, ii); - } - } - mtapi_nodeattr_set(&attr, MTAPI_NODE_CORE_AFFINITY, - &cs, sizeof(cs), &status); - assert(MTAPI_SUCCESS == status); - mtapi_nodeattr_set(&attr, MTAPI_NODE_MAX_TASKS, - &max_tasks, sizeof(max_tasks), &status); - assert(MTAPI_SUCCESS == status); - tmp = 4; - mtapi_nodeattr_set(&attr, MTAPI_NODE_MAX_ACTIONS, - &tmp, sizeof(tmp), &status); - assert(MTAPI_SUCCESS == status); - mtapi_nodeattr_set(&attr, MTAPI_NODE_MAX_GROUPS, - &max_groups, sizeof(max_groups), &status); - assert(MTAPI_SUCCESS == status); - mtapi_nodeattr_set(&attr, MTAPI_NODE_MAX_QUEUES, - &max_queues, sizeof(max_queues), &status); - assert(MTAPI_SUCCESS == status); - mtapi_nodeattr_set(&attr, MTAPI_NODE_QUEUE_LIMIT, - &queue_limit, sizeof(queue_limit), &status); - assert(MTAPI_SUCCESS == status); - tmp = 4; - mtapi_nodeattr_set(&attr, MTAPI_NODE_MAX_JOBS, - &tmp, sizeof(tmp), &status); - assert(MTAPI_SUCCESS == status); - tmp = 1; - mtapi_nodeattr_set(&attr, MTAPI_NODE_MAX_ACTIONS_PER_JOB, - &tmp, sizeof(tmp), &status); - assert(MTAPI_SUCCESS == status); - mtapi_nodeattr_set(&attr, MTAPI_NODE_MAX_PRIORITIES, - &max_priorities, sizeof(max_priorities), &status); - assert(MTAPI_SUCCESS == status); - node_instance = embb::base::Allocation::New( - domain_id, node_id, &attr); - } -} - -bool Node::IsInitialized() { - return NULL != node_instance; -} - -Node & Node::GetInstance() { -#if TASKS_CPP_AUTOMATIC_INITIALIZE - if (!IsInitialized()) { - embb_spin_lock(&init_mutex); - if (!IsInitialized()) { - Node::Initialize( - TASKS_CPP_AUTOMATIC_DOMAIN_ID, TASKS_CPP_AUTOMATIC_NODE_ID); - atexit(Node::Finalize); - } - embb_spin_unlock(&init_mutex); - } - return *node_instance; -#else - if (IsInitialized()) { - return *node_instance; - } else { - EMBB_THROW(embb::base::ErrorException, - "embb::tasks::Node is not initialized"); - } -#endif -} - -void Node::Finalize() { - if (IsInitialized()) { - embb::base::Allocation::Delete(node_instance); - node_instance = NULL; - } else { - EMBB_THROW(embb::base::ErrorException, - "embb::tasks::Node is not initialized"); - } -} - -Group & Node::CreateGroup() { - Group * group = embb::base::Allocation::New(); - while (!group_lock_.TryLock(1024)) { - embb::base::Thread::CurrentYield(); - } - groups_.push_back(group); - group_lock_.Unlock(); - return *group; -} - -void Node::DestroyGroup(Group & group) { - std::list::iterator ii = - std::find(groups_.begin(), groups_.end(), &group); - if (ii != groups_.end()) { - embb::base::Allocation::Delete(*ii); - groups_.erase(ii); - } -} - -Queue & Node::CreateQueue(mtapi_uint_t priority, bool ordered) { - Queue * queue = embb::base::Allocation::New(priority, ordered); - while (!queue_lock_.TryLock(1024)) { - embb::base::Thread::CurrentYield(); - } - queues_.push_back(queue); - queue_lock_.Unlock(); - return *queue; -} - -void Node::DestroyQueue(Queue & queue) { - std::list::iterator ii = - std::find(queues_.begin(), queues_.end(), &queue); - if (ii != queues_.end()) { - embb::base::Allocation::Delete(*ii); - queues_.erase(ii); - } -} - -Task Node::Spawn(Action action) { - return Task(action); -} - -Continuation Node::First(Action action) { - return Continuation(action); -} - -} // namespace tasks -} // namespace embb diff --git a/tasks_cpp/src/queue.cc b/tasks_cpp/src/queue.cc deleted file mode 100644 index efc574a..0000000 --- a/tasks_cpp/src/queue.cc +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include - -namespace embb { -namespace tasks { - -Queue::Queue(mtapi_uint_t priority, bool ordered) { - mtapi_status_t status; - mtapi_queue_attributes_t attr; - mtapi_boolean_t bb; - mtapi_queueattr_init(&attr, &status); - assert(MTAPI_SUCCESS == status); - mtapi_queueattr_set(&attr, MTAPI_QUEUE_PRIORITY, - &priority, sizeof(priority), &status); - assert(MTAPI_SUCCESS == status); - bb = ordered ? MTAPI_TRUE : MTAPI_FALSE; - mtapi_queueattr_set(&attr, MTAPI_QUEUE_ORDERED, - &bb, sizeof(bb), &status); - assert(MTAPI_SUCCESS == status); - bb = MTAPI_TRUE; - mtapi_queueattr_set(&attr, MTAPI_QUEUE_RETAIN, - &bb, sizeof(bb), &status); - assert(MTAPI_SUCCESS == status); - mtapi_domain_t domain_id = mtapi_domain_id_get(&status); - assert(MTAPI_SUCCESS == status); - mtapi_job_hndl_t job = mtapi_job_get(TASKS_CPP_JOB, domain_id, &status); - assert(MTAPI_SUCCESS == status); - handle_ = mtapi_queue_create(MTAPI_QUEUE_ID_NONE, job, &attr, &status); - // Handle MTAPI error status in appropriate exceptions - if (status == MTAPI_SUCCESS) { - return; - } else if (status == MTAPI_ERR_QUEUE_LIMIT) { - EMBB_THROW(embb::base::ErrorException, - "mtapi::Queue could not be constructed, " - "maximum number of queues exceeded"); - } else if (status == MTAPI_ERR_JOB_INVALID) { - EMBB_THROW(embb::base::ErrorException, - "mtapi::Queue could not be constructed, " - "invalid job"); - } else { - EMBB_THROW(embb::base::ErrorException, - "mtapi::Queue could not be constructed"); - } -} - -Queue::~Queue() { - mtapi_status_t status; - mtapi_queue_delete(handle_, MTAPI_INFINITE, &status); - assert(MTAPI_SUCCESS == status); -} - -void Queue::Enable() { - mtapi_status_t status; - mtapi_queue_enable(handle_, &status); - assert(MTAPI_SUCCESS == status); -} - -void Queue::Disable() { - mtapi_status_t status; - mtapi_queue_disable(handle_, MTAPI_INFINITE, &status); - assert(MTAPI_SUCCESS == status); -} - -Task Queue::Spawn(Action action) { - return Task(action, handle_); -} - -Task Queue::Spawn(Group const * group, Action action) { - return Task(action, handle_, group->handle_); -} - -} // namespace tasks -} // namespace embb diff --git a/tasks_cpp/src/task.cc b/tasks_cpp/src/task.cc deleted file mode 100644 index 518b637..0000000 --- a/tasks_cpp/src/task.cc +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include -#include -#include - -namespace embb { -namespace tasks { - -Task::Task() { - handle_.id = 0; - handle_.tag = 0; -} - -Task::Task(Task const & task) - : handle_(task.handle_) { - // empty -} - -Task::Task( - Action action) { - mtapi_status_t status; - mtapi_task_attributes_t attr; - ExecutionPolicy policy = action.GetExecutionPolicy(); - mtapi_taskattr_init(&attr, &status); - assert(MTAPI_SUCCESS == status); - mtapi_taskattr_set(&attr, MTAPI_TASK_PRIORITY, - &policy.priority_, sizeof(policy.priority_), &status); - assert(MTAPI_SUCCESS == status); - mtapi_taskattr_set(&attr, MTAPI_TASK_AFFINITY, - &policy.affinity_, sizeof(policy.affinity_), &status); - assert(MTAPI_SUCCESS == status); - mtapi_domain_t domain_id = mtapi_domain_id_get(&status); - assert(MTAPI_SUCCESS == status); - mtapi_job_hndl_t job = mtapi_job_get(TASKS_CPP_JOB, domain_id, &status); - assert(MTAPI_SUCCESS == status); - Action* holder = embb::base::Allocation::New(action); - handle_ = mtapi_task_start(MTAPI_TASK_ID_NONE, job, - holder, sizeof(Action), MTAPI_NULL, 0, &attr, MTAPI_GROUP_NONE, &status); - if (MTAPI_SUCCESS != status) { - EMBB_THROW(embb::base::ErrorException, - "mtapi::Task could not be started"); - } -} - -Task::Task( - Action action, - mtapi_group_hndl_t group) { - mtapi_status_t status; - mtapi_task_attributes_t attr; - ExecutionPolicy policy = action.GetExecutionPolicy(); - mtapi_taskattr_init(&attr, &status); - assert(MTAPI_SUCCESS == status); - mtapi_taskattr_set(&attr, MTAPI_TASK_PRIORITY, - &policy.priority_, sizeof(policy.priority_), &status); - assert(MTAPI_SUCCESS == status); - mtapi_taskattr_set(&attr, MTAPI_TASK_AFFINITY, - &policy.affinity_, sizeof(policy.affinity_), &status); - assert(MTAPI_SUCCESS == status); - mtapi_domain_t domain_id = mtapi_domain_id_get(&status); - assert(MTAPI_SUCCESS == status); - mtapi_job_hndl_t job = mtapi_job_get(TASKS_CPP_JOB, domain_id, &status); - assert(MTAPI_SUCCESS == status); - Action* holder = embb::base::Allocation::New(action); - handle_ = mtapi_task_start(MTAPI_TASK_ID_NONE, job, - holder, sizeof(Action), MTAPI_NULL, 0, &attr, group, &status); - if (MTAPI_SUCCESS != status) { - EMBB_THROW(embb::base::ErrorException, - "mtapi::Task could not be started"); - } -} - -Task::Task( - mtapi_task_id_t id, - Action action, - mtapi_group_hndl_t group) { - mtapi_status_t status; - mtapi_task_attributes_t attr; - ExecutionPolicy policy = action.GetExecutionPolicy(); - mtapi_taskattr_init(&attr, &status); - assert(MTAPI_SUCCESS == status); - mtapi_taskattr_set(&attr, MTAPI_TASK_PRIORITY, - &policy.priority_, sizeof(policy.priority_), &status); - assert(MTAPI_SUCCESS == status); - mtapi_taskattr_set(&attr, MTAPI_TASK_AFFINITY, - &policy.affinity_, sizeof(policy.affinity_), &status); - assert(MTAPI_SUCCESS == status); - mtapi_domain_t domain_id = mtapi_domain_id_get(&status); - assert(MTAPI_SUCCESS == status); - mtapi_job_hndl_t job = mtapi_job_get(TASKS_CPP_JOB, domain_id, &status); - assert(MTAPI_SUCCESS == status); - Action* holder = embb::base::Allocation::New(action); - void * idptr = MTAPI_NULL; - memcpy(&idptr, &id, sizeof(id)); - handle_ = mtapi_task_start(id, job, - holder, sizeof(Action), idptr, 0, &attr, group, &status); - if (MTAPI_SUCCESS != status) { - EMBB_THROW(embb::base::ErrorException, - "mtapi::Task could not be started"); - } -} - -Task::Task( - Action action, - mtapi_queue_hndl_t queue) { - mtapi_status_t status; - mtapi_task_attributes_t attr; - ExecutionPolicy policy = action.GetExecutionPolicy(); - mtapi_taskattr_init(&attr, &status); - assert(MTAPI_SUCCESS == status); - mtapi_taskattr_set(&attr, MTAPI_TASK_PRIORITY, - &policy.priority_, sizeof(policy.priority_), &status); - assert(MTAPI_SUCCESS == status); - mtapi_taskattr_set(&attr, MTAPI_TASK_AFFINITY, - &policy.affinity_, sizeof(policy.affinity_), &status); - assert(MTAPI_SUCCESS == status); - Action* holder = embb::base::Allocation::New(action); - handle_ = mtapi_task_enqueue(MTAPI_TASK_ID_NONE, queue, - holder, sizeof(Action), MTAPI_NULL, 0, &attr, MTAPI_GROUP_NONE, &status); - if (MTAPI_SUCCESS != status) { - EMBB_THROW(embb::base::ErrorException, - "mtapi::Task could not be started"); - } -} - -Task::Task( - Action action, - mtapi_queue_hndl_t queue, - mtapi_group_hndl_t group) { - mtapi_status_t status; - mtapi_task_attributes_t attr; - ExecutionPolicy policy = action.GetExecutionPolicy(); - mtapi_taskattr_init(&attr, &status); - assert(MTAPI_SUCCESS == status); - mtapi_taskattr_set(&attr, MTAPI_TASK_PRIORITY, - &policy.priority_, sizeof(policy.priority_), &status); - assert(MTAPI_SUCCESS == status); - mtapi_taskattr_set(&attr, MTAPI_TASK_AFFINITY, - &policy.affinity_, sizeof(policy.affinity_), &status); - assert(MTAPI_SUCCESS == status); - Action* holder = embb::base::Allocation::New(action); - handle_ = mtapi_task_enqueue(MTAPI_TASK_ID_NONE, queue, - holder, sizeof(Action), MTAPI_NULL, 0, &attr, group, &status); - if (MTAPI_SUCCESS != status) { - EMBB_THROW(embb::base::ErrorException, - "mtapi::Task could not be started"); - } -} - -Task::Task( - mtapi_task_id_t id, - Action action, - mtapi_queue_hndl_t queue, - mtapi_group_hndl_t group) { - mtapi_status_t status; - mtapi_task_attributes_t attr; - ExecutionPolicy policy = action.GetExecutionPolicy(); - mtapi_taskattr_init(&attr, &status); - assert(MTAPI_SUCCESS == status); - mtapi_taskattr_set(&attr, MTAPI_TASK_PRIORITY, - &policy.priority_, sizeof(policy.priority_), &status); - assert(MTAPI_SUCCESS == status); - mtapi_taskattr_set(&attr, MTAPI_TASK_AFFINITY, - &policy.affinity_, sizeof(policy.affinity_), &status); - assert(MTAPI_SUCCESS == status); - Action* holder = embb::base::Allocation::New(action); - void * idptr = MTAPI_NULL; - memcpy(&idptr, &id, sizeof(id)); - handle_ = mtapi_task_enqueue(id, queue, - holder, sizeof(Action), idptr, 0, &attr, group, &status); - if (MTAPI_SUCCESS != status) { - EMBB_THROW(embb::base::ErrorException, - "mtapi::Task could not be started"); - } -} - -Task::~Task() { -} - -mtapi_status_t Task::Wait(mtapi_timeout_t timeout) { - mtapi_status_t status; - mtapi_task_wait(handle_, timeout, &status); - return status; -} - -void Task::Cancel() { - mtapi_status_t status; - mtapi_task_cancel(handle_, &status); - assert(MTAPI_SUCCESS == status); -} - -} // namespace tasks -} // namespace embb diff --git a/tasks_cpp/src/task_context.cc b/tasks_cpp/src/task_context.cc deleted file mode 100644 index f863715..0000000 --- a/tasks_cpp/src/task_context.cc +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -namespace embb { -namespace tasks { - -TaskContext::TaskContext(mtapi_task_context_t * task_context) - : context_(task_context) { -} - -bool TaskContext::ShouldCancel() { - mtapi_status_t status; - bool result = - MTAPI_TASK_CANCELLED == mtapi_context_taskstate_get(context_, &status); - assert(MTAPI_SUCCESS == status); - return result; -} - -mtapi_uint_t TaskContext::GetCurrentCoreNumber() { - mtapi_status_t status; - mtapi_uint_t result = - mtapi_context_corenum_get(context_, &status); - assert(MTAPI_SUCCESS == status); - return result; -} - -void TaskContext::SetStatus(mtapi_status_t error_code) { - mtapi_status_t status; - mtapi_context_status_set(context_, error_code, &status); - assert(MTAPI_SUCCESS == status); -} - -} // namespace tasks -} // namespace embb diff --git a/tasks_cpp/test/main.cc b/tasks_cpp/test/main.cc deleted file mode 100644 index 56f38c0..0000000 --- a/tasks_cpp/test/main.cc +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include - -#include -#include -#include - -#include - - -PT_MAIN("TASKS") { - embb_atomic_initialize(); - - PT_RUN(TaskTest); - PT_RUN(GroupTest); - PT_RUN(QueueTest); - - embb_atomic_finalize(); -} diff --git a/tasks_cpp/test/tasks_cpp_test_config.h b/tasks_cpp/test/tasks_cpp_test_config.h deleted file mode 100644 index cae2208..0000000 --- a/tasks_cpp/test/tasks_cpp_test_config.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TASKS_CPP_TEST_TASKS_CPP_TEST_CONFIG_H_ -#define TASKS_CPP_TEST_TASKS_CPP_TEST_CONFIG_H_ - -#include -#include - -#define THIS_DOMAIN_ID 1 -#define THIS_NODE_ID 1 - -#endif // TASKS_CPP_TEST_TASKS_CPP_TEST_CONFIG_H_ diff --git a/tasks_cpp/test/tasks_cpp_test_group.cc b/tasks_cpp/test/tasks_cpp_test_group.cc deleted file mode 100644 index 75cab3a..0000000 --- a/tasks_cpp/test/tasks_cpp_test_group.cc +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include - -#include - -struct result_example_struct { - mtapi_uint_t value1; - mtapi_uint_t value2; -}; - -typedef struct result_example_struct result_example_t; - -static void testGroupAction(embb::tasks::TaskContext & /*context*/) { - // emtpy -} - -static void testDoSomethingElse() { -} - -GroupTest::GroupTest() { - CreateUnit("tasks_cpp group test").Add(&GroupTest::TestBasic, this); -} - -void GroupTest::TestBasic() { - embb::tasks::Node::Initialize(THIS_DOMAIN_ID, THIS_NODE_ID); - - embb::tasks::Node & node = embb::tasks::Node::GetInstance(); - embb::tasks::Group & group = node.CreateGroup(); - embb::tasks::Task task; - - for (int ii = 0; ii < 4; ii++) { - task = group.Spawn(testGroupAction); - } - testDoSomethingElse(); - group.WaitAll(MTAPI_INFINITE); - - for (int ii = 0; ii < 4; ii++) { - task = group.Spawn(mtapi_task_id_t(ii + 1), testGroupAction); - } - testDoSomethingElse(); - mtapi_status_t status; - mtapi_task_id_t result; - while (MTAPI_SUCCESS == (status = group.WaitAny(MTAPI_INFINITE, result))) { - // empty - } - - node.DestroyGroup(group); - - embb::tasks::Node::Finalize(); - - PT_EXPECT_EQ(embb_get_bytes_allocated(), 0u); -} diff --git a/tasks_cpp/test/tasks_cpp_test_group.h b/tasks_cpp/test/tasks_cpp_test_group.h deleted file mode 100644 index fe212ea..0000000 --- a/tasks_cpp/test/tasks_cpp_test_group.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TASKS_CPP_TEST_TASKS_CPP_TEST_GROUP_H_ -#define TASKS_CPP_TEST_TASKS_CPP_TEST_GROUP_H_ - -#include - -class GroupTest : public partest::TestCase { - public: - GroupTest(); - - private: - void TestBasic(); -}; - -#endif // TASKS_CPP_TEST_TASKS_CPP_TEST_GROUP_H_ diff --git a/tasks_cpp/test/tasks_cpp_test_queue.cc b/tasks_cpp/test/tasks_cpp_test_queue.cc deleted file mode 100644 index eb6bc87..0000000 --- a/tasks_cpp/test/tasks_cpp_test_queue.cc +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include - -#include - -#define JOB_TEST_TASK 42 -#define TASK_TEST_ID 23 -#define QUEUE_TEST_ID 17 - -static void testQueueAction(embb::tasks::TaskContext & /*context*/) { - // empty -} - -static void testDoSomethingElse() { -} - -QueueTest::QueueTest() { - CreateUnit("tasks_cpp queue test").Add(&QueueTest::TestBasic, this); -} - -void QueueTest::TestBasic() { - embb::tasks::Node::Initialize(THIS_DOMAIN_ID, THIS_NODE_ID); - - embb::tasks::Node & node = embb::tasks::Node::GetInstance(); - embb::tasks::Queue & queue = node.CreateQueue(0, false); - - embb::tasks::Task task = queue.Spawn(testQueueAction); - - testDoSomethingElse(); - - task.Wait(MTAPI_INFINITE); - - node.DestroyQueue(queue); - - embb::tasks::Node::Finalize(); - - PT_EXPECT_EQ(embb_get_bytes_allocated(), 0u); -} diff --git a/tasks_cpp/test/tasks_cpp_test_queue.h b/tasks_cpp/test/tasks_cpp_test_queue.h deleted file mode 100644 index 5c86795..0000000 --- a/tasks_cpp/test/tasks_cpp_test_queue.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TASKS_CPP_TEST_TASKS_CPP_TEST_QUEUE_H_ -#define TASKS_CPP_TEST_TASKS_CPP_TEST_QUEUE_H_ - -#include - -class QueueTest : public partest::TestCase { - public: - QueueTest(); - - private: - void TestBasic(); -}; - -#endif // TASKS_CPP_TEST_TASKS_CPP_TEST_QUEUE_H_ diff --git a/tasks_cpp/test/tasks_cpp_test_task.cc b/tasks_cpp/test/tasks_cpp_test_task.cc deleted file mode 100644 index 69c56db..0000000 --- a/tasks_cpp/test/tasks_cpp_test_task.cc +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#include -#include - -#include - -#define JOB_TEST_TASK 42 -#define TASK_TEST_ID 23 - -static void testTaskAction( - char const * msg, - std::string * output, - embb::tasks::TaskContext & /*context*/) { - *output = msg; -} - -static void testRecursiveTaskAction( - int * value, - embb::tasks::TaskContext & /*context*/) { - embb::tasks::Node & node = embb::tasks::Node::GetInstance(); - *value = *value + 1; - if (*value < 1000) { - embb::tasks::Task task = node.Spawn( - embb::base::Bind( - testRecursiveTaskAction, value, embb::base::Placeholder::_1)); - task.Wait(MTAPI_INFINITE); - } - PT_EXPECT(*value == 1000); -} - -static void testErrorTaskAction(embb::tasks::TaskContext & context) { - context.SetStatus(MTAPI_ERR_ACTION_FAILED); -} - -static void testDoSomethingElse() { -} - -TaskTest::TaskTest() { - CreateUnit("tasks_cpp task test").Add(&TaskTest::TestBasic, this); -} - -void TaskTest::TestBasic() { - embb::tasks::Node::Initialize(THIS_DOMAIN_ID, THIS_NODE_ID); - - embb::tasks::Node & node = embb::tasks::Node::GetInstance(); - - embb::tasks::ExecutionPolicy policy(false); - PT_EXPECT_EQ(policy.GetAffinity(), 0u); - PT_EXPECT_EQ(policy.GetPriority(), 0u); - policy.AddWorker(0u); - PT_EXPECT_EQ(policy.GetAffinity(), 1u); - - if (policy.GetCoreCount() > 1) { - policy.AddWorker(1u); - PT_EXPECT_EQ(policy.GetAffinity(), 3u); - } - - policy.RemoveWorker(0u); - PT_EXPECT_EQ(policy.IsSetWorker(0), false); - - if (policy.GetCoreCount() > 1) { - PT_EXPECT_EQ(policy.GetAffinity(), 2u); - PT_EXPECT_EQ(policy.IsSetWorker(1), true); - } - std::string test; - embb::tasks::Task task = node.Spawn( - embb::base::Bind( - testTaskAction, "simple", &test, embb::base::Placeholder::_1)); - testDoSomethingElse(); - task.Wait(MTAPI_INFINITE); - PT_EXPECT(test == "simple"); - - std::string test1, test2, test3; - task = node.First( - embb::base::Bind( - testTaskAction, "first", &test1, embb::base::Placeholder::_1)). - Then(embb::base::Bind( - testTaskAction, "second", &test2, embb::base::Placeholder::_1)). - Then(embb::base::Bind( - testTaskAction, "third", &test3, embb::base::Placeholder::_1)). - Spawn(); - testDoSomethingElse(); - task.Wait(MTAPI_INFINITE); - PT_EXPECT(test1 == "first"); - PT_EXPECT(test2 == "second"); - PT_EXPECT(test3 == "third"); - - int value = 0; - task = node.Spawn( - embb::base::Bind( - testRecursiveTaskAction, &value, embb::base::Placeholder::_1)); - task.Wait(MTAPI_INFINITE); - PT_EXPECT(value == 1000); - - mtapi_status_t status; - task = node.Spawn(testErrorTaskAction); - testDoSomethingElse(); - status = task.Wait(MTAPI_INFINITE); - PT_EXPECT(MTAPI_ERR_ACTION_FAILED == status); - - embb::tasks::Node::Finalize(); - - PT_EXPECT(embb_get_bytes_allocated() == 0); -} diff --git a/tasks_cpp/test/tasks_cpp_test_task.h b/tasks_cpp/test/tasks_cpp_test_task.h deleted file mode 100644 index 16f683b..0000000 --- a/tasks_cpp/test/tasks_cpp_test_task.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2014-2016, Siemens AG. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TASKS_CPP_TEST_TASKS_CPP_TEST_TASK_H_ -#define TASKS_CPP_TEST_TASKS_CPP_TEST_TASK_H_ - -#include - -class TaskTest : public partest::TestCase { - public: - TaskTest(); - - private: - void TestBasic(); -}; - -#endif // TASKS_CPP_TEST_TASKS_CPP_TEST_TASK_H_