Commit bdfa7dc4 by Marcus Winter

mtapi_cpp: first part of merge with tasks_cpp

parent 5bbc63a1
...@@ -43,60 +43,26 @@ class Action { ...@@ -43,60 +43,26 @@ class Action {
public: public:
/** /**
* Constructs an Action. * Constructs an Action.
* The Action object will be invalid.
*/ */
Action( Action() {
mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ handle_.id = 0;
mtapi_action_function_t func, /**< The action function */ handle_.tag = 0;
const void * node_local_data, /**< Node local data available to all
Tasks using this Action */
mtapi_size_t node_local_data_size, /**< Size of node local data */
ActionAttributes const & attributes
/**< Attributes of the Action */
) {
Create(job_id, func, node_local_data, node_local_data_size,
&attributes.GetInternal());
} }
/** Action(Action const & other) : handle_(other.handle_) {
* Constructs an Action. // empty
*/
Action(
mtapi_job_id_t job_id, /**< Job ID the Action belongs to */
mtapi_action_function_t func, /**< The action function */
const void * node_local_data, /**< Node local data available to all
Tasks using this Action */
mtapi_size_t node_local_data_size /**< Size of node local data */
) {
Create(job_id, func, node_local_data, node_local_data_size,
MTAPI_DEFAULT_ACTION_ATTRIBUTES);
}
/**
* Constructs an Action.
*/
Action(
mtapi_job_id_t job_id, /**< Job ID the Action belongs to */
mtapi_action_function_t func, /**< The action function */
ActionAttributes const & attributes
/**< Attributes of the Action */
) {
Create(job_id, func, MTAPI_NULL, 0, &attributes.GetInternal());
} }
/** Action & operator=(Action const & other) {
* Constructs an Action. handle_ = other.handle_;
*/ return *this;
Action(
mtapi_job_id_t job_id, /**< Job ID the Action belongs to */
mtapi_action_function_t func /**< The action function */
) {
Create(job_id, func, MTAPI_NULL, 0, MTAPI_DEFAULT_ACTION_ATTRIBUTES);
} }
/** /**
* Destroys an Action. * Deletes an Action.
*/ */
~Action() { void Delete() {
mtapi_action_delete(handle_, MTAPI_INFINITE, MTAPI_NULL); mtapi_action_delete(handle_, MTAPI_INFINITE, MTAPI_NULL);
} }
...@@ -111,20 +77,20 @@ class Action { ...@@ -111,20 +77,20 @@ class Action {
return handle_; return handle_;
} }
private: friend class Node;
// no default constructor
Action();
// not copyable
Action(Action const & other);
void operator=(Action const & other);
void Create( private:
mtapi_job_id_t job_id, /**
mtapi_action_function_t func, * Constructs an Action.
const void * node_local_data, */
mtapi_size_t node_local_data_size, Action(
mtapi_job_id_t job_id, /**< Job ID the Action belongs to */
mtapi_action_function_t func, /**< The action function */
const void * node_local_data, /**< Node local data available to all
Tasks using this Action */
mtapi_size_t node_local_data_size, /**< Size of node local data */
mtapi_action_attributes_t const * attributes mtapi_action_attributes_t const * attributes
/**< Attributes of the Action */
) { ) {
mtapi_status_t status; mtapi_status_t status;
handle_ = mtapi_action_create(job_id, func, handle_ = mtapi_action_create(job_id, func,
......
/*
* 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_MTAPI_EXECUTION_POLICY_H_
#define EMBB_MTAPI_EXECUTION_POLICY_H_
#include <embb/mtapi/c/mtapi.h>
namespace embb {
namespace mtapi {
/**
* 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_MTAPI
*/
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 mtapi
} // namespace embb
#endif // EMBB_MTAPI_EXECUTION_POLICY_H_
...@@ -51,49 +51,19 @@ namespace mtapi { ...@@ -51,49 +51,19 @@ namespace mtapi {
*/ */
class Group { class Group {
public: public:
/** Group(Group const & other) : handle_(other.handle_) {
* Constructs a Group object with default attributes. // empty
* Requires an initialized Node.
*/
Group() {
Create(MTAPI_GROUP_ID_NONE, MTAPI_DEFAULT_GROUP_ATTRIBUTES);
} }
/** Group & operator=(Group const & other) {
* Constructs a Group object using the given Attributes. handle_ = other.handle_;
* Requires an initialized Node. return *this;
*/
Group(
GroupAttributes const & attr /**< The GroupAttributes to use. */
) {
Create(MTAPI_GROUP_ID_NONE, &attr.GetInternal());
} }
/** /**
* Constructs a Group object with default attributes and the given ID. * Deletes a Group object.
* Requires an initialized Node.
*/ */
Group( void Delete() {
mtapi_group_id_t id /**< A user defined ID of the Group. */
) {
Create(id, MTAPI_DEFAULT_GROUP_ATTRIBUTES);
}
/**
* Constructs a Group object with given attributes and ID.
* Requires an initialized Node.
*/
Group(
mtapi_group_id_t id, /**< A user defined ID of the Group. */
GroupAttributes const & attr /**< The GroupAttributes to use. */
) {
Create(id, &attr.GetInternal());
}
/**
* Destroys a Group object.
*/
~Group() {
// delete the group, ignore status // delete the group, ignore status
mtapi_group_delete(handle_, MTAPI_NULL); mtapi_group_delete(handle_, MTAPI_NULL);
} }
...@@ -194,7 +164,6 @@ class Group { ...@@ -194,7 +164,6 @@ class Group {
) { ) {
mtapi_status_t status; mtapi_status_t status;
mtapi_group_wait_any(handle_, result, timeout, &status); mtapi_group_wait_any(handle_, result, timeout, &status);
needs_delete_ = status != MTAPI_GROUP_COMPLETED;
return status; return status;
} }
...@@ -245,7 +214,6 @@ class Group { ...@@ -245,7 +214,6 @@ class Group {
) { ) {
mtapi_status_t status; mtapi_status_t status;
mtapi_group_wait_all(handle_, timeout, &status); mtapi_group_wait_all(handle_, timeout, &status);
needs_delete_ = status != MTAPI_SUCCESS;
return status; return status;
} }
...@@ -271,21 +239,21 @@ class Group { ...@@ -271,21 +239,21 @@ class Group {
} }
friend class embb::base::Allocation; friend class embb::base::Allocation;
friend class Node;
private: private:
// not copyable /**
Group(Group const & other); * Constructs a Group object with given attributes and ID.
void operator=(Group const & other); * Requires an initialized Node.
*/
void Create( Group(
mtapi_group_id_t group_id, mtapi_group_id_t id, /**< A user defined ID of the Group. */
mtapi_group_attributes_t const * attributes mtapi_group_attributes_t const * attributes
/**< The GroupAttributes to use. */
) { ) {
needs_delete_ = false;
mtapi_status_t status; mtapi_status_t status;
handle_ = mtapi_group_create(group_id, attributes, &status); handle_ = mtapi_group_create(id, attributes, &status);
internal::CheckStatus(status); internal::CheckStatus(status);
needs_delete_ = true;
} }
Task Start( Task Start(
...@@ -307,7 +275,6 @@ class Group { ...@@ -307,7 +275,6 @@ class Group {
} }
mtapi_group_hndl_t handle_; mtapi_group_hndl_t handle_;
bool needs_delete_;
}; };
} // namespace mtapi } // namespace mtapi
......
...@@ -50,19 +50,6 @@ class Job { ...@@ -50,19 +50,6 @@ class Job {
} }
/** /**
* Constructs a Job with the given \c job_id and \c domain_id.
* Requires an initialized Node.
*/
Job(
mtapi_job_id_t job_id, /**< Job ID to use. */
mtapi_domain_t domain_id /**< Domain ID to use. */
) {
mtapi_status_t status;
handle_ = mtapi_job_get(job_id, domain_id, &status);
internal::CheckStatus(status);
}
/**
* Copies a Job object. * Copies a Job object.
*/ */
Job( Job(
...@@ -91,8 +78,23 @@ class Job { ...@@ -91,8 +78,23 @@ class Job {
return handle_; return handle_;
} }
friend class Node;
private: private:
mtapi_job_hndl_t handle_; /**
* Constructs a Job with the given \c job_id and \c domain_id.
* Requires an initialized Node.
*/
Job(
mtapi_job_id_t job_id, /**< Job ID to use. */
mtapi_domain_t domain_id /**< Domain ID to use. */
) {
mtapi_status_t status;
handle_ = mtapi_job_get(job_id, domain_id, &status);
internal::CheckStatus(status);
}
mtapi_job_hndl_t handle_;
}; };
} // namespace mtapi } // namespace mtapi
......
...@@ -31,9 +31,12 @@ ...@@ -31,9 +31,12 @@
#include <embb/mtapi/c/mtapi.h> #include <embb/mtapi/c/mtapi.h>
#include <embb/mtapi/status_exception.h> #include <embb/mtapi/status_exception.h>
#include <embb/mtapi/node_attributes.h> #include <embb/mtapi/node_attributes.h>
#include <embb/mtapi/group.h>
#include <embb/mtapi/queue.h>
#include <embb/mtapi/task.h> #include <embb/mtapi/task.h>
#include <embb/mtapi/task_attributes.h> #include <embb/mtapi/task_attributes.h>
#include <embb/mtapi/job.h> #include <embb/mtapi/job.h>
#include <embb/mtapi/action.h>
namespace embb { namespace embb {
...@@ -69,16 +72,7 @@ class Node { ...@@ -69,16 +72,7 @@ class Node {
static void Initialize( static void Initialize(
mtapi_domain_t domain_id, /**< [in] The domain id to use */ mtapi_domain_t domain_id, /**< [in] The domain id to use */
mtapi_node_t node_id /**< [in] The node id to use */ mtapi_node_t node_id /**< [in] The node id to use */
) { );
if (IsInitialized()) {
EMBB_THROW(StatusException,
"MTAPI: node was already initialized.");
} else {
NodeAttributes attributes; // default attributes
node_instance_ = embb::base::Allocation::New<Node>(
domain_id, node_id, attributes);
}
}
/** /**
* Initializes the runtime singleton. * Initializes the runtime singleton.
...@@ -91,15 +85,7 @@ class Node { ...@@ -91,15 +85,7 @@ class Node {
mtapi_domain_t domain_id, /**< [in] The domain id to use */ mtapi_domain_t domain_id, /**< [in] The domain id to use */
mtapi_node_t node_id, /**< [in] The node id to use */ mtapi_node_t node_id, /**< [in] The node id to use */
NodeAttributes const & attributes /**< [in] Attributes to use */ NodeAttributes const & attributes /**< [in] Attributes to use */
) { );
if (IsInitialized()) {
EMBB_THROW(StatusException,
"MTAPI: node was already initialized.");
} else {
node_instance_ = embb::base::Allocation::New<Node>(
domain_id, node_id, attributes);
}
}
/** /**
* Checks if runtime is initialized. * Checks if runtime is initialized.
...@@ -116,29 +102,14 @@ class Node { ...@@ -116,29 +102,14 @@ class Node {
* \return Reference to the Node singleton * \return Reference to the Node singleton
* \threadsafe * \threadsafe
*/ */
static Node & GetInstance() { static Node & GetInstance();
if (IsInitialized()) {
return *node_instance_;
} else {
EMBB_THROW(StatusException,
"MTAPI: node is not initialized.");
}
}
/** /**
* Shuts the runtime system down. * Shuts the runtime system down.
* \throws ErrorException if the singleton is not initialized. * \throws ErrorException if the singleton is not initialized.
* \notthreadsafe * \notthreadsafe
*/ */
static void Finalize() { static void Finalize();
if (IsInitialized()) {
embb::base::Allocation::Delete(node_instance_);
node_instance_ = NULL;
} else {
EMBB_THROW(StatusException,
"MTAPI: node is not initialized.");
}
}
/** /**
* Returns the number of available cores. * Returns the number of available cores.
...@@ -159,6 +130,15 @@ class Node { ...@@ -159,6 +130,15 @@ class Node {
} }
/** /**
* Returns the number of available queues.
* \return The number of available queues
* \waitfree
*/
mtapi_uint_t GetQueueCount() const {
return queue_count_;
}
/**
* Starts a new Task. * Starts a new Task.
* *
* \returns The handle to the started Task. * \returns The handle to the started Task.
...@@ -238,6 +218,123 @@ class Node { ...@@ -238,6 +218,123 @@ class Node {
MTAPI_DEFAULT_TASK_ATTRIBUTES); MTAPI_DEFAULT_TASK_ATTRIBUTES);
} }
#ifdef GetJob
#undef GetJob
#endif
Job GetJob(mtapi_job_id_t job_id) {
return Job(job_id, domain_id_);
}
Job GetJob(mtapi_job_id_t job_id, mtapi_domain_t domain_id) {
return Job(job_id, domain_id);
}
/**
* Constructs an Action.
*/
Action CreateAction(
mtapi_job_id_t job_id, /**< Job ID the Action belongs to */
mtapi_action_function_t func, /**< The action function */
const void * node_local_data, /**< Node local data available to all
Tasks using this Action */
mtapi_size_t node_local_data_size, /**< Size of node local data */
ActionAttributes const & attributes
/**< Attributes of the Action */
) {
return Action(job_id, func, node_local_data, node_local_data_size,
&attributes.GetInternal());
}
/**
* Constructs an Action.
*/
Action CreateAction(
mtapi_job_id_t job_id, /**< Job ID the Action belongs to */
mtapi_action_function_t func, /**< The action function */
const void * node_local_data, /**< Node local data available to all
Tasks using this Action */
mtapi_size_t node_local_data_size /**< Size of node local data */
) {
return Action(job_id, func, node_local_data, node_local_data_size,
MTAPI_DEFAULT_ACTION_ATTRIBUTES);
}
/**
* Constructs an Action.
*/
Action CreateAction(
mtapi_job_id_t job_id, /**< Job ID the Action belongs to */
mtapi_action_function_t func, /**< The action function */
ActionAttributes const & attributes
/**< Attributes of the Action */
) {
return Action(job_id, func, MTAPI_NULL, 0, &attributes.GetInternal());
}
/**
* Constructs an Action.
*/
Action CreateAction(
mtapi_job_id_t job_id, /**< Job ID the Action belongs to */
mtapi_action_function_t func /**< The action function */
) {
return Action(job_id, func, MTAPI_NULL, 0, MTAPI_DEFAULT_ACTION_ATTRIBUTES);
}
/**
* Constructs a Group object with default attributes.
*/
Group CreateGroup() {
return Group(MTAPI_GROUP_ID_NONE, MTAPI_DEFAULT_GROUP_ATTRIBUTES);
}
/**
* Constructs a Group object with default attributes and the given ID.
*/
Group CreateGroup(
mtapi_group_id_t id /**< A user defined ID of the Group. */
) {
return Group(id, MTAPI_DEFAULT_GROUP_ATTRIBUTES);
}
/**
* Constructs a Group object using the given Attributes.
*/
Group CreateGroup(
GroupAttributes const & group_attr) {
return Group(MTAPI_GROUP_ID_NONE, &group_attr.GetInternal());
}
/**
* Constructs a Group object with given attributes and ID.
*/
Group CreateGroup(
mtapi_group_id_t id, /**< A user defined ID of the Group. */
GroupAttributes const & group_attr /**< The GroupAttributes to use. */
) {
return Group(id, &group_attr.GetInternal());
}
/**
* Constructs a Queue with the given Job and default attributes.
*/
Queue CreateQueue(
Job & job /**< The Job to use for the Queue. */
) {
return Queue(MTAPI_QUEUE_ID_NONE, job, MTAPI_DEFAULT_QUEUE_ATTRIBUTES);
}
/**
* Constructs a Queue with the given Job and QueueAttributes.
*/
Queue CreateQueue(
Job const & job, /**< The Job to use for the Queue. */
QueueAttributes const & attr /**< The attributes to use. */
) {
return Queue(MTAPI_QUEUE_ID_NONE, job, &attr.GetInternal());
}
friend class embb::base::Allocation; friend class embb::base::Allocation;
private: private:
...@@ -251,21 +348,15 @@ class Node { ...@@ -251,21 +348,15 @@ class Node {
NodeAttributes const & attr) { NodeAttributes const & attr) {
mtapi_status_t status; mtapi_status_t status;
mtapi_info_t info; mtapi_info_t info;
queue_count_ = attr.GetInternal().max_queues;
mtapi_initialize(domain_id, node_id, &attr.GetInternal(), &info, &status); mtapi_initialize(domain_id, node_id, &attr.GetInternal(), &info, &status);
needs_finalize_ = status == MTAPI_SUCCESS;
internal::CheckStatus(status); internal::CheckStatus(status);
core_count_ = info.hardware_concurrency; core_count_ = info.hardware_concurrency;
worker_thread_count_ = embb_core_set_count( worker_thread_count_ = embb_core_set_count(
&attr.GetInternal().core_affinity); &attr.GetInternal().core_affinity);
}
~Node() { domain_id_ = domain_id;
if (needs_finalize_) {
mtapi_status_t status;
mtapi_finalize(&status);
internal::CheckStatus(status);
}
} }
Task Start( Task Start(
...@@ -288,9 +379,10 @@ class Node { ...@@ -288,9 +379,10 @@ class Node {
static embb::mtapi::Node * node_instance_; static embb::mtapi::Node * node_instance_;
mtapi_domain_t domain_id_;
mtapi_uint_t core_count_; mtapi_uint_t core_count_;
mtapi_uint_t worker_thread_count_; mtapi_uint_t worker_thread_count_;
bool needs_finalize_; mtapi_uint_t queue_count_;
}; };
} // namespace mtapi } // namespace mtapi
......
...@@ -51,31 +51,19 @@ namespace mtapi { ...@@ -51,31 +51,19 @@ namespace mtapi {
*/ */
class Queue { class Queue {
public: public:
/** Queue(Queue const & other) : handle_(other.handle_) {
* Constructs a Queue with the given Job and default attributes. // empty
* Requires an initialized Node.
*/
Queue(
Job const & job /**< The Job to use for the Queue. */
) {
Create(MTAPI_QUEUE_ID_NONE, job, MTAPI_DEFAULT_QUEUE_ATTRIBUTES);
} }
/** Queue & operator=(Queue const & other) {
* Constructs a Queue with the given Job and QueueAttributes. handle_ = other.handle_;
* Requires an initialized Node. return *this;
*/
Queue(
Job const & job, /**< The Job to use for the Queue. */
QueueAttributes const & attr /**< The attributes to use. */
) {
Create(MTAPI_QUEUE_ID_NONE, job, &attr.GetInternal());
} }
/** /**
* Destroys a Queue object. * Deletes a Queue object.
*/ */
~Queue() { void Delete() {
mtapi_queue_delete(handle_, MTAPI_INFINITE, MTAPI_NULL); mtapi_queue_delete(handle_, MTAPI_INFINITE, MTAPI_NULL);
} }
...@@ -272,16 +260,13 @@ class Queue { ...@@ -272,16 +260,13 @@ class Queue {
} }
friend class embb::base::Allocation; friend class embb::base::Allocation;
friend class Node;
private: private:
// no default constructor // no default constructor
Queue(); Queue();
// not copyable Queue(
Queue(Queue const & other);
void operator=(Queue const & other);
void Create(
mtapi_queue_id_t queue_id, mtapi_queue_id_t queue_id,
Job const & job, Job const & job,
mtapi_queue_attributes_t const * attributes mtapi_queue_attributes_t const * attributes
......
/*
* 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/mtapi/execution_policy.h>
#include <embb/base/exceptions.h>
#include <embb/base/c/internal/bitset.h>
#include <cassert>
namespace embb {
namespace mtapi {
ExecutionPolicy::ExecutionPolicy() :
priority_(DefaultPriority) {
#if MTAPI_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 MTAPI_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 MTAPI_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 MTAPI_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 mtapi
} // namespace embb
...@@ -30,6 +30,74 @@ namespace embb { ...@@ -30,6 +30,74 @@ namespace embb {
namespace mtapi { namespace mtapi {
embb::mtapi::Node * embb::mtapi::Node::node_instance_ = NULL; embb::mtapi::Node * embb::mtapi::Node::node_instance_ = NULL;
#if MTAPI_CPP_AUTOMATIC_INITIALIZE
static embb_spinlock_t init_mutex = { { 0 } };
#endif
void Node::Initialize(
mtapi_domain_t domain_id,
mtapi_node_t node_id
) {
if (IsInitialized()) {
EMBB_THROW(StatusException,
"MTAPI: node was already initialized.");
}
else {
NodeAttributes attributes; // default attributes
node_instance_ = embb::base::Allocation::New<Node>(
domain_id, node_id, attributes);
}
}
void Node::Initialize(
mtapi_domain_t domain_id,
mtapi_node_t node_id,
NodeAttributes const & attributes
) {
if (IsInitialized()) {
EMBB_THROW(StatusException,
"MTAPI: node was already initialized.");
}
else {
node_instance_ = embb::base::Allocation::New<Node>(
domain_id, node_id, attributes);
}
}
Node & Node::GetInstance() {
#if MTAPI_CPP_AUTOMATIC_INITIALIZE
if (!IsInitialized()) {
embb_spin_lock(&init_mutex);
if (!IsInitialized()) {
Node::Initialize(
MTAPI_CPP_AUTOMATIC_DOMAIN_ID, MTAPI_CPP_AUTOMATIC_NODE_ID);
atexit(Node::Finalize);
}
embb_spin_unlock(&init_mutex);
}
return *node_instance;
#else
if (IsInitialized()) {
return *node_instance_;
}
else {
EMBB_THROW(StatusException,
"MTAPI: node is not initialized.");
}
#endif
}
void Node::Finalize() {
if (IsInitialized()) {
mtapi_finalize(MTAPI_NULL);
embb::base::Allocation::Delete(node_instance_);
node_instance_ = NULL;
}
else {
EMBB_THROW(StatusException,
"MTAPI: node is not initialized.");
}
}
} // namespace mtapi } // namespace mtapi
} // namespace embb } // namespace embb
...@@ -61,12 +61,14 @@ GroupTest::GroupTest() { ...@@ -61,12 +61,14 @@ GroupTest::GroupTest() {
void GroupTest::TestBasic() { void GroupTest::TestBasic() {
embb::mtapi::Node::Initialize(THIS_DOMAIN_ID, THIS_NODE_ID); embb::mtapi::Node::Initialize(THIS_DOMAIN_ID, THIS_NODE_ID);
embb::mtapi::Node & node = embb::mtapi::Node::GetInstance();
embb::mtapi::Job job(JOB_TEST_GROUP, THIS_DOMAIN_ID); embb::mtapi::Job job = node.GetJob(JOB_TEST_GROUP);
embb::mtapi::Action action(JOB_TEST_GROUP, testGroupAction); embb::mtapi::Action action =
node.CreateAction(JOB_TEST_GROUP, testGroupAction);
{ {
embb::mtapi::Group group; embb::mtapi::Group group = node.CreateGroup();
result_example_t buffer[TASK_COUNT]; result_example_t buffer[TASK_COUNT];
for (int ii = 0; ii < TASK_COUNT; ii++) { for (int ii = 0; ii < TASK_COUNT; ii++) {
...@@ -86,7 +88,7 @@ void GroupTest::TestBasic() { ...@@ -86,7 +88,7 @@ void GroupTest::TestBasic() {
} }
{ {
embb::mtapi::Group group; embb::mtapi::Group group = node.CreateGroup();
result_example_t buffer[TASK_COUNT]; result_example_t buffer[TASK_COUNT];
for (int ii = 0; ii < 4; ii++) { for (int ii = 0; ii < 4; ii++) {
......
...@@ -54,13 +54,14 @@ QueueTest::QueueTest() { ...@@ -54,13 +54,14 @@ QueueTest::QueueTest() {
void QueueTest::TestBasic() { void QueueTest::TestBasic() {
embb::mtapi::Node::Initialize(THIS_DOMAIN_ID, THIS_NODE_ID); embb::mtapi::Node::Initialize(THIS_DOMAIN_ID, THIS_NODE_ID);
embb::mtapi::Node & node = embb::mtapi::Node::GetInstance();
embb::mtapi::Job job(JOB_TEST_QUEUE, THIS_DOMAIN_ID); embb::mtapi::Job job = node.GetJob(JOB_TEST_QUEUE);
embb::mtapi::Action action(JOB_TEST_QUEUE, testQueueAction, embb::mtapi::Action action = node.CreateAction(
MTAPI_NULL, 0); JOB_TEST_QUEUE, testQueueAction, MTAPI_NULL, 0);
{ {
embb::mtapi::Queue queue(job); embb::mtapi::Queue queue = node.CreateQueue(job);
int result = 0; int result = 0;
embb::mtapi::Task task = queue.Enqueue<void, int>(MTAPI_NULL, &result); embb::mtapi::Task task = queue.Enqueue<void, int>(MTAPI_NULL, &result);
......
...@@ -96,9 +96,10 @@ void TaskTest::TestBasic() { ...@@ -96,9 +96,10 @@ void TaskTest::TestBasic() {
} }
{ {
embb::mtapi::Job job_task(JOB_TEST_TASK, THIS_DOMAIN_ID); embb::mtapi::Job job_task = node.GetJob(JOB_TEST_TASK);
embb::mtapi::Action action_task(JOB_TEST_TASK, testTaskAction); embb::mtapi::Action action_task =
node.CreateAction(JOB_TEST_TASK, testTaskAction);
std::string test; std::string test;
embb::mtapi::Task task = node.Start(job_task, "simple", &test); embb::mtapi::Task task = node.Start(job_task, "simple", &test);
...@@ -109,10 +110,10 @@ void TaskTest::TestBasic() { ...@@ -109,10 +110,10 @@ void TaskTest::TestBasic() {
} }
{ {
embb::mtapi::Job job_error(JOB_TEST_ERROR, THIS_DOMAIN_ID); embb::mtapi::Job job_error = node.GetJob(JOB_TEST_ERROR);
embb::mtapi::Action action_error(JOB_TEST_ERROR, testErrorAction, embb::mtapi::Action action_error =
embb::mtapi::ActionAttributes()); node.CreateAction(JOB_TEST_ERROR, testErrorAction);
std::string test; std::string test;
embb::mtapi::Task task = node.Start(job_error, "simple", &test); embb::mtapi::Task task = node.Start(job_error, "simple", &test);
......
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