Commit 28ea6ab3 by Marcus Winter

mtapi_cpp: added functionality to start Function objects directly as a task

parent ea2bc757
......@@ -118,7 +118,7 @@ class ExecutionPolicy{
*
* \return the affinity
*/
const mtapi_affinity_t &GetAffinity() const;
mtapi_affinity_t GetAffinity() const;
/** Returns the priority
*
......
......@@ -35,6 +35,7 @@
* \ingroup CPP
*/
#include <embb/mtapi/execution_policy.h>
#include <embb/mtapi/job.h>
#include <embb/mtapi/action.h>
#include <embb/mtapi/group.h>
......
......@@ -28,6 +28,7 @@
#define EMBB_MTAPI_NODE_H_
#include <embb/base/memory_allocation.h>
#include <embb/base/function.h>
#include <embb/mtapi/c/mtapi.h>
#include <embb/mtapi/status_exception.h>
#include <embb/mtapi/node_attributes.h>
......@@ -37,6 +38,13 @@
#include <embb/mtapi/task_attributes.h>
#include <embb/mtapi/job.h>
#include <embb/mtapi/action.h>
#include <embb/mtapi/task_context.h>
#ifdef GetJob
#undef GetJob
#endif
#define EMBB_MTAPI_FUNCTION_JOB_ID 2
namespace embb {
......@@ -55,6 +63,8 @@ namespace mtapi {
*/
class Node {
public:
typedef embb::base::Function<void, TaskContext &> SMPFunction;
/**
* Initializes the runtime singleton using default values:
* - all available cores will be used
......@@ -156,6 +166,27 @@ class Node {
return task_limit_;
}
Task Start(
SMPFunction const & func
) {
Job job = GetJob(EMBB_MTAPI_FUNCTION_JOB_ID);
void * res = NULL;
return Start(
job, embb::base::Allocation::New<SMPFunction>(func), res);
}
Task Start(
SMPFunction const & func,
ExecutionPolicy const & policy
) {
Job job = GetJob(EMBB_MTAPI_FUNCTION_JOB_ID);
void * res = NULL;
TaskAttributes task_attr;
task_attr.SetPolicy(policy);
return Start(
job, embb::base::Allocation::New<SMPFunction>(func), res, task_attr);
}
/**
* Starts a new Task.
*
......@@ -236,10 +267,6 @@ class Node {
MTAPI_DEFAULT_TASK_ATTRIBUTES);
}
#ifdef GetJob
#undef GetJob
#endif
Job GetJob(mtapi_job_id_t job_id) {
return Job(job_id, domain_id_);
}
......@@ -397,6 +424,21 @@ class Node {
return Task(task_hndl);
}
static void ActionFunction(
const void* args,
mtapi_size_t /*args_size*/,
void* /*result_buffer*/,
mtapi_size_t /*result_buffer_size*/,
const void* /*node_local_data*/,
mtapi_size_t /*node_local_data_size*/,
mtapi_task_context_t * context) {
TaskContext task_context(context);
embb::base::Function<void, TaskContext &> * func =
reinterpret_cast<embb::base::Function<void, TaskContext &>*>(const_cast<void*>(args));
(*func)(task_context);
embb::base::Allocation::Delete(func);
}
static embb::mtapi::Node * node_instance_;
mtapi_domain_t domain_id_;
......@@ -405,6 +447,7 @@ class Node {
mtapi_uint_t queue_count_;
mtapi_uint_t group_count_;
mtapi_uint_t task_limit_;
Action function_action_;
};
} // namespace mtapi
......
......@@ -29,6 +29,7 @@
#include <embb/mtapi/c/mtapi.h>
#include <embb/mtapi/internal/check_status.h>
#include <embb/mtapi/execution_policy.h>
namespace embb {
namespace mtapi {
......@@ -86,6 +87,31 @@ class TaskAttributes {
}
/**
* Sets the affinity of a Task.
* The affinity influences on which worker the Task will be executed.
*
* \returns Reference to this object.
* \notthreadsafe
*/
TaskAttributes & SetAffinity(
mtapi_affinity_t affinity /**< The affinity to set. */
) {
mtapi_status_t status;
mtapi_taskattr_set(&attributes_, MTAPI_TASK_AFFINITY,
&affinity, sizeof(affinity), &status);
internal::CheckStatus(status);
return *this;
}
TaskAttributes & SetPolicy(
ExecutionPolicy const & policy
) {
SetPriority(policy.GetPriority());
SetAffinity(policy.GetAffinity());
return *this;
}
/**
* Sets the number of instances in a Task.
* The Task will be launched \c instances times. In the action function,
* the number of instances and the current instance can be queried from
......
......@@ -109,7 +109,7 @@ unsigned int ExecutionPolicy::GetCoreCount() const {
return embb_bitset_count(&affinity_);
}
const mtapi_affinity_t &ExecutionPolicy::GetAffinity() const {
mtapi_affinity_t ExecutionPolicy::GetAffinity() const {
return affinity_;
}
......
......@@ -41,11 +41,13 @@ void Node::Initialize(
if (IsInitialized()) {
EMBB_THROW(StatusException,
"MTAPI: node was already initialized.");
}
else {
} else {
NodeAttributes attributes; // default attributes
node_instance_ = embb::base::Allocation::New<Node>(
domain_id, node_id, attributes);
Job job = node_instance_->GetJob(EMBB_MTAPI_FUNCTION_JOB_ID);
node_instance_->function_action_ =
node_instance_->CreateAction(EMBB_MTAPI_FUNCTION_JOB_ID, ActionFunction);
}
}
......@@ -57,8 +59,7 @@ void Node::Initialize(
if (IsInitialized()) {
EMBB_THROW(StatusException,
"MTAPI: node was already initialized.");
}
else {
} else {
node_instance_ = embb::base::Allocation::New<Node>(
domain_id, node_id, attributes);
}
......@@ -79,8 +80,7 @@ Node & Node::GetInstance() {
#else
if (IsInitialized()) {
return *node_instance_;
}
else {
} else {
EMBB_THROW(StatusException,
"MTAPI: node is not initialized.");
}
......@@ -89,11 +89,11 @@ Node & Node::GetInstance() {
void Node::Finalize() {
if (IsInitialized()) {
node_instance_->function_action_.Delete();
mtapi_finalize(MTAPI_NULL);
embb::base::Allocation::Delete(node_instance_);
node_instance_ = NULL;
}
else {
} else {
EMBB_THROW(StatusException,
"MTAPI: node is not initialized.");
}
......
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