/* * Copyright (c) 2014-2015, 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_ALGORITHMS_INVOKE_H_ #define EMBB_ALGORITHMS_INVOKE_H_ #include #include namespace embb { namespace algorithms { /** * \defgroup CPP_ALGORITHMS_INVOKE Invoke * Parallel invocation of functions. * \ingroup CPP_ALGORITHMS */ /** * Function type used by Invoke. * \ingroup CPP_ALGORITHMS_INVOKE */ typedef embb::base::Function InvokeFunctionType; #ifdef DOXYGEN /** * Spawns two to ten function objects at once and runs them in parallel. * * Blocks until all of them are done. * * \ingroup CPP_ALGORITHMS_INVOKE */ template void Invoke( Function1 func1, /**< [in] First function object to invoke */ Function2 func2, /**< [in] Second function object to invoke */ ...); /** * Spawns two to ten function objects at once and runs them in parallel using the * given embb::mtapi::ExecutionPolicy. * * Blocks until all of them are done. * * \ingroup CPP_ALGORITHMS_INVOKE */ template void Invoke( Function1 func1, /**< [in] Function object to invoke */ Function2 func2, /**< [in] Second function object to invoke */ ..., const embb::tasks::ExecutionPolicy & policy /**< [in] embb::tasks::ExecutionPolicy to use */ ); #else // DOXYGEN namespace internal { /** * Spawns an MTAPI task on construction and waits for it on destruction. */ template class TaskWrapper { public: /** * Wraps the function into an embb::tasks::Action and spawns an * embb::tasks::Task. */ explicit TaskWrapper( Function function, const embb::tasks::ExecutionPolicy& policy) : function_(function), task_() { embb::tasks::Action action(embb::base::MakeFunction( *this, &TaskWrapper::Run), policy); task_ = embb::tasks::Node::GetInstance().Spawn(action); } /** * Waits until the task has finished execution. */ ~TaskWrapper() { task_.Wait(MTAPI_INFINITE); } private: Function function_; embb::tasks::Task task_; void Run(embb::tasks::TaskContext&) { function_(); } }; } // namespace internal template void Invoke( Function1 func1, Function2 func2, const embb::tasks::ExecutionPolicy& policy) { internal::TaskWrapper wrap1(func1, policy); internal::TaskWrapper wrap2(func2, policy); } template void Invoke( Function1 func1, Function2 func2, Function3 func3, const embb::tasks::ExecutionPolicy& policy) { internal::TaskWrapper wrap1(func1, policy); internal::TaskWrapper wrap2(func2, policy); internal::TaskWrapper wrap3(func3, policy); } template void Invoke( Function1 func1, Function2 func2, Function3 func3, Function4 func4, const embb::tasks::ExecutionPolicy& policy) { internal::TaskWrapper wrap1(func1, policy); internal::TaskWrapper wrap2(func2, policy); internal::TaskWrapper wrap3(func3, policy); internal::TaskWrapper wrap4(func4, policy); } template void Invoke( Function1 func1, Function2 func2, Function3 func3, Function4 func4, Function5 func5, const embb::tasks::ExecutionPolicy& policy) { internal::TaskWrapper wrap1(func1, policy); internal::TaskWrapper wrap2(func2, policy); internal::TaskWrapper wrap3(func3, policy); internal::TaskWrapper wrap4(func4, policy); internal::TaskWrapper wrap5(func5, policy); } template void Invoke( Function1 func1, Function2 func2, Function3 func3, Function4 func4, Function5 func5, Function6 func6, const embb::tasks::ExecutionPolicy& policy) { internal::TaskWrapper wrap1(func1, policy); internal::TaskWrapper wrap2(func2, policy); internal::TaskWrapper wrap3(func3, policy); internal::TaskWrapper wrap4(func4, policy); internal::TaskWrapper wrap5(func5, policy); internal::TaskWrapper wrap6(func6, policy); } template void Invoke( Function1 func1, Function2 func2, Function3 func3, Function4 func4, Function5 func5, Function6 func6, Function7 func7, const embb::tasks::ExecutionPolicy& policy) { internal::TaskWrapper wrap1(func1, policy); internal::TaskWrapper wrap2(func2, policy); internal::TaskWrapper wrap3(func3, policy); internal::TaskWrapper wrap4(func4, policy); internal::TaskWrapper wrap5(func5, policy); internal::TaskWrapper wrap6(func6, policy); internal::TaskWrapper wrap7(func7, policy); } template void Invoke( Function1 func1, Function2 func2, Function3 func3, Function4 func4, Function5 func5, Function6 func6, Function7 func7, Function8 func8, const embb::tasks::ExecutionPolicy& policy) { internal::TaskWrapper wrap1(func1, policy); internal::TaskWrapper wrap2(func2, policy); internal::TaskWrapper wrap3(func3, policy); internal::TaskWrapper wrap4(func4, policy); internal::TaskWrapper wrap5(func5, policy); internal::TaskWrapper wrap6(func6, policy); internal::TaskWrapper wrap7(func7, policy); internal::TaskWrapper wrap8(func8, policy); } template void Invoke( Function1 func1, Function2 func2, Function3 func3, Function4 func4, Function5 func5, Function6 func6, Function7 func7, Function8 func8, Function9 func9, const embb::tasks::ExecutionPolicy& policy) { internal::TaskWrapper wrap1(func1, policy); internal::TaskWrapper wrap2(func2, policy); internal::TaskWrapper wrap3(func3, policy); internal::TaskWrapper wrap4(func4, policy); internal::TaskWrapper wrap5(func5, policy); internal::TaskWrapper wrap6(func6, policy); internal::TaskWrapper wrap7(func7, policy); internal::TaskWrapper wrap8(func8, policy); internal::TaskWrapper wrap9(func9, policy); } template void Invoke( Function1 func1, Function2 func2, Function3 func3, Function4 func4, Function5 func5, Function6 func6, Function7 func7, Function8 func8, Function9 func9, Function10 func10, const embb::tasks::ExecutionPolicy& policy) { internal::TaskWrapper wrap1(func1, policy); internal::TaskWrapper wrap2(func2, policy); internal::TaskWrapper wrap3(func3, policy); internal::TaskWrapper wrap4(func4, policy); internal::TaskWrapper wrap5(func5, policy); internal::TaskWrapper wrap6(func6, policy); internal::TaskWrapper wrap7(func7, policy); internal::TaskWrapper wrap8(func8, policy); internal::TaskWrapper wrap9(func9, policy); internal::TaskWrapper wrap10(func10, policy); } template void Invoke( Function1 func1, Function2 func2) { Invoke(func1, func2, embb::tasks::ExecutionPolicy()); } template void Invoke( Function1 func1, Function2 func2, Function3 func3) { Invoke(func1, func2, func3, embb::tasks::ExecutionPolicy()); } template void Invoke( Function1 func1, Function2 func2, Function3 func3, Function4 func4) { Invoke(func1, func2, func3, func4, embb::tasks::ExecutionPolicy()); } template void Invoke( Function1 func1, Function2 func2, Function3 func3, Function4 func4, Function5 func5) { Invoke(func1, func2, func3, func4, func5, embb::tasks::ExecutionPolicy()); } template void Invoke( Function1 func1, Function2 func2, Function3 func3, Function4 func4, Function5 func5, Function6 func6) { Invoke(func1, func2, func3, func4, func5, func6, embb::tasks::ExecutionPolicy()); } template void Invoke( Function1 func1, Function2 func2, Function3 func3, Function4 func4, Function5 func5, Function6 func6, Function7 func7) { Invoke(func1, func2, func3, func4, func5, func6, func7, embb::tasks::ExecutionPolicy()); } template void Invoke( Function1 func1, Function2 func2, Function3 func3, Function4 func4, Function5 func5, Function6 func6, Function7 func7, Function8 func8) { Invoke(func1, func2, func3, func4, func5, func6, func7, func8, embb::tasks::ExecutionPolicy()); } template void Invoke( Function1 func1, Function2 func2, Function3 func3, Function4 func4, Function5 func5, Function6 func6, Function7 func7, Function8 func8, Function9 func9) { Invoke(func1, func2, func3, func4, func5, func6, func7, func8, func9, embb::tasks::ExecutionPolicy()); } template void Invoke( Function1 func1, Function2 func2, Function3 func3, Function4 func4, Function5 func5, Function6 func6, Function7 func7, Function8 func8, Function9 func9, Function10 func10) { Invoke(func1, func2, func3, func4, func5, func6, func7, func8, func9, func10, embb::tasks::ExecutionPolicy()); } #endif // else DOXYGEN } // namespace algorithms } // namespace embb #endif // EMBB_ALGORITHMS_INVOKE_H_