Commit 4248d8f5 by Marcus Winter

removed tasks_cpp

parent b1896e6c
......@@ -180,7 +180,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)
......
......@@ -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})
......
......@@ -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;
......
/*
* 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 <iostream>
#include <embb/tasks/tasks.h>
#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;
}
void fibonacciActionFunction(
int n,
int* result,
embb::tasks::TaskContext & task_context
) {
int b = n - 2;
int y;
fibonacciActionFunction(
b,
&y,
task_context);
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
)
);
embb::tasks::Node& node = embb::tasks::Node::GetInstance();
int result;
embb::tasks::Task task = node.Spawn(
embb::base::Bind(
embb::base::MakeFunction(fibonacciActionFunction),
n,
&result,
embb::base::Placeholder::_1
)
);
mtapi_status_t status = task.Wait(MTAPI_INFINITE);
MTAPI_CHECK_STATUS(status);
......@@ -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
......
......@@ -28,6 +28,7 @@
#define EMBB_MTAPI_EXECUTION_POLICY_H_
#include <embb/mtapi/c/mtapi.h>
#include <embb/mtapi/internal/cmake_config.h>
namespace embb {
namespace mtapi {
......
......@@ -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_
......@@ -30,6 +30,7 @@
#include <embb/base/memory_allocation.h>
#include <embb/base/function.h>
#include <embb/mtapi/c/mtapi.h>
#include <embb/mtapi/execution_policy.h>
#include <embb/mtapi/status_exception.h>
#include <embb/mtapi/node_attributes.h>
#include <embb/mtapi/group.h>
......@@ -44,6 +45,10 @@
#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 {
......
......@@ -25,6 +25,7 @@
*/
#include <embb/mtapi/execution_policy.h>
#include <embb/mtapi/node.h>
#include <embb/base/exceptions.h>
#include <embb/base/c/internal/bitset.h>
#include <cassert>
......
......@@ -25,6 +25,7 @@
*/
#include <embb/mtapi/node.h>
#include <embb/base/c/mutex.h>
namespace embb {
namespace mtapi {
......@@ -76,7 +77,7 @@ Node & Node::GetInstance() {
}
embb_spin_unlock(&init_mutex);
}
return *node_instance;
return *node_instance_;
#else
if (IsInitialized()) {
return *node_instance_;
......
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)
/*
* 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 <embb/base/function.h>
#include <embb/tasks/task_context.h>
#include <embb/tasks/execution_policy.h>
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 <typename Function>
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 <typename Function>
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<void, TaskContext &> function_;
ExecutionPolicy execution_policy_;
};
} // namespace tasks
} // namespace embb
#endif // EMBB_TASKS_ACTION_H_
/*
* 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 <embb/mtapi/c/mtapi.h>
#include <embb/tasks/task_context.h>
#include <embb/tasks/action.h>
#include <embb/tasks/task.h>
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_
/*
* 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_EXECUTION_POLICY_H_
#define EMBB_TASKS_EXECUTION_POLICY_H_
#include <embb/mtapi/c/mtapi.h>
namespace embb {
namespace tasks {
/**
* Describes the execution policy of a parallel algorithm.
* The execution policy comprises
* - the affinity of tasks to MTAPI worker threads (not CPU cores) and
* - the priority of the spawned tasks.
*
* The priority is a number between 0 (denoting the highest priority) to
* max_priorities - 1 as given during initialization using Node::Initialize().
* The default value of max_priorities is 4.
*
* \ingroup CPP_TASKS
*/
class ExecutionPolicy{
public:
/**
* Constructs the default execution policy.
* Sets the affinity to all worker threads and the priority to the default
* value.
*/
ExecutionPolicy();
/**
* Constructs an execution policy with the specified affinity and priority.
*/
ExecutionPolicy(
bool initial_affinity, /**< [in] \c true sets the affinity to
all worker threads, \c false to no
worker threads. */
mtapi_uint_t priority /**< [in] Priority for the execution
policy. */
);
/**
* Constructs an execution policy with the specified priority.
* Sets the affinity to all worker threads.
*/
explicit ExecutionPolicy(
mtapi_uint_t priority /**< [in] Priority for the execution
policy. */
);
/**
* Constructs an execution policy with the specified affinity.
* Sets the priority to the default value.
*/
explicit ExecutionPolicy(
bool initial_affinity /**< [in] \c true sets the affinity to
all worker threads, \c false to no
worker threads. */
);
/**
* Sets affinity to a specific worker thread.
*/
void AddWorker(
mtapi_uint_t worker /**< [in] Worker thread index */
);
/**
* Removes affinity to a specific worker thread.
*/
void RemoveWorker(
mtapi_uint_t worker /**< [in] Worker thread index */
);
/**
* Checks if affinity to a specific worker thread is set.
*
* \return \c true if affinity is set, otherwise \c false
*/
bool IsSetWorker(
mtapi_uint_t worker /**< [in] Worker thread index */
);
/**
* Returns the number of cores the policy is affine to.
*
* \return the number of cores
*/
unsigned int GetCoreCount() const;
/**
* Returns the affinity
*
* \return the affinity
*/
const mtapi_affinity_t &GetAffinity() const;
/** Returns the priority
*
* \return the priority
*/
mtapi_uint_t GetPriority() const;
friend class Task;
private:
/**
* Default priority.
* Currently set to 0 = MAX priority.
*/
static const mtapi_uint_t DefaultPriority;
/**
* Task Affinity.
* Maps the affinity of tasks to MTAPI worker threads (not CPU cores).
*/
mtapi_affinity_t affinity_;
/**
* Task Priority.
*/
mtapi_uint_t priority_;
};
} // namespace tasks
} // namespace embb
#endif // EMBB_TASKS_EXECUTION_POLICY_H_
/*
* 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 <embb/mtapi/c/mtapi.h>
#include <embb/tasks/action.h>
#include <embb/tasks/task.h>
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_
/*
* 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 <list>
#include <embb/base/core_set.h>
#include <embb/base/mutex.h>
#include <embb/mtapi/c/mtapi.h>
#include <embb/tasks/action.h>
#include <embb/tasks/task.h>
#include <embb/tasks/continuation.h>
#include <embb/tasks/group.h>
#include <embb/tasks/queue.h>
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<Queue*> queues_;
std::list<Group*> groups_;
embb::base::Spinlock queue_lock_;
embb::base::Spinlock group_lock_;
};
} // namespace tasks
} // namespace embb
#endif // EMBB_TASKS_NODE_H_
/*
* 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 <embb/mtapi/c/mtapi.h>
#include <embb/tasks/action.h>
#include <embb/tasks/task.h>
#include <embb/tasks/group.h>
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_
/*
* 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 <embb/mtapi/c/mtapi.h>
#include <embb/tasks/action.h>
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_
/*
* 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 <embb/mtapi/c/mtapi.h>
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_
/*
* 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 <embb/tasks/internal/cmake_config.h>
#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 <embb/tasks/execution_policy.h>
#include <embb/tasks/action.h>
#include <embb/tasks/continuation.h>
#include <embb/tasks/group.h>
#include <embb/tasks/node.h>
#include <embb/tasks/queue.h>
#include <embb/tasks/task.h>
#include <embb/tasks/task_context.h>
#endif // EMBB_TASKS_TASKS_H_
/*
* 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 <cstddef>
#include <embb/base/memory_allocation.h>
#include <embb/base/function.h>
#include <embb/tasks/tasks.h>
#include <continuationstage.h>
namespace embb {
namespace tasks {
Continuation::Continuation(Action action) {
first_ = last_ = embb::base::Allocation::New<ContinuationStage>();
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<ContinuationStage>();
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
/*
* 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 <embb/tasks/tasks.h>
namespace embb {
namespace tasks {
struct ContinuationStage {
Action action;
ContinuationStage * next;
};
} // namespace tasks
} // namespace embb
#endif // TASKS_CPP_SRC_CONTINUATIONSTAGE_H_
/*
* 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 <embb/tasks/execution_policy.h>
#include <embb/tasks/tasks.h>
#include <embb/base/exceptions.h>
#include <embb/base/c/internal/bitset.h>
#include <cassert>
namespace embb {
namespace tasks {
ExecutionPolicy::ExecutionPolicy() :
priority_(DefaultPriority) {
#if TASKS_CPP_AUTOMATIC_INITIALIZE
Node::GetInstance(); // MTAPI has to be initialized
#endif
mtapi_status_t status;
mtapi_affinity_init(&affinity_, MTAPI_TRUE, &status);
if (MTAPI_SUCCESS != status) {
EMBB_THROW(embb::base::ErrorException,
"Could not default construct Affinity.");
}
}
ExecutionPolicy::ExecutionPolicy(bool initial_affinity, mtapi_uint_t priority)
:priority_(priority) {
#if TASKS_CPP_AUTOMATIC_INITIALIZE
Node::GetInstance(); // MTAPI has to be initialized
#endif
mtapi_status_t status;
mtapi_affinity_init(&affinity_, initial_affinity ? MTAPI_TRUE : MTAPI_FALSE,
&status);
if (MTAPI_SUCCESS != status) {
EMBB_THROW(embb::base::ErrorException,
"Could not default construct Affinity.");
}
}
ExecutionPolicy::ExecutionPolicy(mtapi_uint_t priority)
:priority_(priority) {
#if TASKS_CPP_AUTOMATIC_INITIALIZE
Node::GetInstance(); // MTAPI has to be initialized
#endif
mtapi_status_t status;
mtapi_affinity_init(&affinity_, MTAPI_TRUE, &status);
if (MTAPI_SUCCESS != status) {
EMBB_THROW(embb::base::ErrorException,
"Could not default construct Affinity.");
}
}
ExecutionPolicy::ExecutionPolicy(bool initial_affinity)
:priority_(DefaultPriority) {
#if TASKS_CPP_AUTOMATIC_INITIALIZE
Node::GetInstance(); // MTAPI has to be initialized
#endif
mtapi_status_t status;
mtapi_affinity_init(&affinity_, initial_affinity ? MTAPI_TRUE : MTAPI_FALSE,
&status);
if (MTAPI_SUCCESS != status) {
EMBB_THROW(embb::base::ErrorException,
"Could not default construct Affinity.");
}
}
void ExecutionPolicy::AddWorker(mtapi_uint_t worker) {
mtapi_status_t status;
mtapi_affinity_set(&affinity_, worker, MTAPI_TRUE, &status);
assert(MTAPI_SUCCESS == status);
}
void ExecutionPolicy::RemoveWorker(mtapi_uint_t worker) {
mtapi_status_t status;
mtapi_affinity_set(&affinity_, worker, MTAPI_FALSE, &status);
assert(MTAPI_SUCCESS == status);
}
bool ExecutionPolicy::IsSetWorker(mtapi_uint_t worker) {
mtapi_status_t status;
mtapi_boolean_t aff = mtapi_affinity_get(&affinity_, worker, &status);
assert(MTAPI_SUCCESS == status);
return MTAPI_TRUE == aff;
}
unsigned int ExecutionPolicy::GetCoreCount() const {
return embb_bitset_count(&affinity_);
}
const mtapi_affinity_t &ExecutionPolicy::GetAffinity() const {
return affinity_;
}
mtapi_uint_t ExecutionPolicy::GetPriority() const {
return priority_;
}
const mtapi_uint_t ExecutionPolicy::DefaultPriority = 0;
} // namespace tasks
} // namespace embb
/*
* 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 <cstring>
#include <cassert>
#include <embb/base/exceptions.h>
#include <embb/tasks/tasks.h>
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
/*
* 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 <algorithm>
#include <cstddef>
#include <cstdlib>
#include <cassert>
#include <embb/base/memory_allocation.h>
#include <embb/base/exceptions.h>
#include <embb/base/thread.h>
#include <embb/tasks/tasks.h>
#if TASKS_CPP_AUTOMATIC_INITIALIZE
#include <embb/base/mutex.h>
#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<Action*>(const_cast<void*>(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<Queue*>::iterator ii = queues_.begin();
ii != queues_.end();
++ii) {
embb::base::Allocation::Delete(*ii);
}
queues_.clear();
for (std::list<Group*>::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<Node>(
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<Node>(
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<Group>();
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<Group*>::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<Queue>(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<Queue*>::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
/*
* 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 <cassert>
#include <embb/base/exceptions.h>
#include <embb/tasks/tasks.h>
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
/*
* 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 <cstring>
#include <cassert>
#include <embb/base/memory_allocation.h>
#include <embb/base/exceptions.h>
#include <embb/tasks/tasks.h>
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>(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>(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>(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>(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>(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>(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
/*
* 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 <cassert>
#include <embb/tasks/tasks.h>
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
/*
* 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 <partest/partest.h>
#include <iostream>
#include <tasks_cpp_test_task.h>
#include <tasks_cpp_test_group.h>
#include <tasks_cpp_test_queue.h>
PT_MAIN("TASKS") {
PT_RUN(TaskTest);
PT_RUN(GroupTest);
PT_RUN(QueueTest);
}
/*
* 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 <partest/partest.h>
#include <embb/tasks/tasks.h>
#define THIS_DOMAIN_ID 1
#define THIS_NODE_ID 1
#endif // TASKS_CPP_TEST_TASKS_CPP_TEST_CONFIG_H_
/*
* 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 <iostream>
#include <tasks_cpp_test_config.h>
#include <tasks_cpp_test_group.h>
#include <embb/base/c/memory_allocation.h>
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);
}
/*
* 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 <partest/partest.h>
class GroupTest : public partest::TestCase {
public:
GroupTest();
private:
void TestBasic();
};
#endif // TASKS_CPP_TEST_TASKS_CPP_TEST_GROUP_H_
/*
* 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 <cstdlib>
#include <tasks_cpp_test_config.h>
#include <tasks_cpp_test_queue.h>
#include <embb/base/c/memory_allocation.h>
#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);
}
/*
* 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 <partest/partest.h>
class QueueTest : public partest::TestCase {
public:
QueueTest();
private:
void TestBasic();
};
#endif // TASKS_CPP_TEST_TASKS_CPP_TEST_QUEUE_H_
/*
* 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 <iostream>
#include <string>
#include <cassert>
#include <tasks_cpp_test_config.h>
#include <tasks_cpp_test_task.h>
#include <embb/base/c/memory_allocation.h>
#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);
}
/*
* 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 <partest/partest.h>
class TaskTest : public partest::TestCase {
public:
TaskTest();
private:
void TestBasic();
};
#endif // TASKS_CPP_TEST_TASKS_CPP_TEST_TASK_H_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment