diff --git a/mtapi_cpp/include/embb/mtapi/action.h b/mtapi_cpp/include/embb/mtapi/action.h index 564ab49..28ef3c7 100644 --- a/mtapi_cpp/include/embb/mtapi/action.h +++ b/mtapi_cpp/include/embb/mtapi/action.h @@ -43,60 +43,26 @@ class Action { public: /** * Constructs an Action. + * The Action object will be invalid. */ - Action( - mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ - mtapi_action_function_t func, /**< The action function */ - const void * node_local_data, /**< Node local data available to all - Tasks using this Action */ - mtapi_size_t node_local_data_size, /**< Size of node local data */ - ActionAttributes const & attributes - /**< Attributes of the Action */ - ) { - Create(job_id, func, node_local_data, node_local_data_size, - &attributes.GetInternal()); + Action() { + handle_.id = 0; + handle_.tag = 0; } - /** - * Constructs an Action. - */ - Action( - mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ - mtapi_action_function_t func, /**< The action function */ - const void * node_local_data, /**< Node local data available to all - Tasks using this Action */ - mtapi_size_t node_local_data_size /**< Size of node local data */ - ) { - Create(job_id, func, node_local_data, node_local_data_size, - MTAPI_DEFAULT_ACTION_ATTRIBUTES); - } - - /** - * Constructs an Action. - */ - Action( - mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ - mtapi_action_function_t func, /**< The action function */ - ActionAttributes const & attributes - /**< Attributes of the Action */ - ) { - Create(job_id, func, MTAPI_NULL, 0, &attributes.GetInternal()); + Action(Action const & other) : handle_(other.handle_) { + // empty } - /** - * Constructs an Action. - */ - Action( - mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ - mtapi_action_function_t func /**< The action function */ - ) { - Create(job_id, func, MTAPI_NULL, 0, MTAPI_DEFAULT_ACTION_ATTRIBUTES); + Action & operator=(Action const & other) { + handle_ = other.handle_; + return *this; } /** - * Destroys an Action. + * Deletes an Action. */ - ~Action() { + void Delete() { mtapi_action_delete(handle_, MTAPI_INFINITE, MTAPI_NULL); } @@ -111,20 +77,20 @@ class Action { return handle_; } - private: - // no default constructor - Action(); - - // not copyable - Action(Action const & other); - void operator=(Action const & other); + friend class Node; - void Create( - mtapi_job_id_t job_id, - mtapi_action_function_t func, - const void * node_local_data, - mtapi_size_t node_local_data_size, + private: + /** + * Constructs an Action. + */ + Action( + mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ + mtapi_action_function_t func, /**< The action function */ + const void * node_local_data, /**< Node local data available to all + Tasks using this Action */ + mtapi_size_t node_local_data_size, /**< Size of node local data */ mtapi_action_attributes_t const * attributes + /**< Attributes of the Action */ ) { mtapi_status_t status; handle_ = mtapi_action_create(job_id, func, diff --git a/mtapi_cpp/include/embb/mtapi/execution_policy.h b/mtapi_cpp/include/embb/mtapi/execution_policy.h new file mode 100644 index 0000000..c6c7efa --- /dev/null +++ b/mtapi_cpp/include/embb/mtapi/execution_policy.h @@ -0,0 +1,153 @@ +/* + * 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 + +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_ diff --git a/mtapi_cpp/include/embb/mtapi/group.h b/mtapi_cpp/include/embb/mtapi/group.h index 6d47598..8810d5f 100644 --- a/mtapi_cpp/include/embb/mtapi/group.h +++ b/mtapi_cpp/include/embb/mtapi/group.h @@ -51,49 +51,19 @@ namespace mtapi { */ class Group { public: - /** - * Constructs a Group object with default attributes. - * Requires an initialized Node. - */ - Group() { - Create(MTAPI_GROUP_ID_NONE, MTAPI_DEFAULT_GROUP_ATTRIBUTES); + Group(Group const & other) : handle_(other.handle_) { + // empty } - /** - * Constructs a Group object using the given Attributes. - * Requires an initialized Node. - */ - Group( - GroupAttributes const & attr /**< The GroupAttributes to use. */ - ) { - Create(MTAPI_GROUP_ID_NONE, &attr.GetInternal()); + Group & operator=(Group const & other) { + handle_ = other.handle_; + return *this; } /** - * Constructs a Group object with default attributes and the given ID. - * Requires an initialized Node. + * Deletes a Group object. */ - Group( - mtapi_group_id_t id /**< A user defined ID of the Group. */ - ) { - Create(id, MTAPI_DEFAULT_GROUP_ATTRIBUTES); - } - - /** - * Constructs a Group object with given attributes and ID. - * Requires an initialized Node. - */ - Group( - mtapi_group_id_t id, /**< A user defined ID of the Group. */ - GroupAttributes const & attr /**< The GroupAttributes to use. */ - ) { - Create(id, &attr.GetInternal()); - } - - /** - * Destroys a Group object. - */ - ~Group() { + void Delete() { // delete the group, ignore status mtapi_group_delete(handle_, MTAPI_NULL); } @@ -194,7 +164,6 @@ class Group { ) { mtapi_status_t status; mtapi_group_wait_any(handle_, result, timeout, &status); - needs_delete_ = status != MTAPI_GROUP_COMPLETED; return status; } @@ -245,7 +214,6 @@ class Group { ) { mtapi_status_t status; mtapi_group_wait_all(handle_, timeout, &status); - needs_delete_ = status != MTAPI_SUCCESS; return status; } @@ -271,21 +239,21 @@ class Group { } friend class embb::base::Allocation; + friend class Node; private: - // not copyable - Group(Group const & other); - void operator=(Group const & other); - - void Create( - mtapi_group_id_t group_id, + /** + * Constructs a Group object with given attributes and ID. + * Requires an initialized Node. + */ + Group( + mtapi_group_id_t id, /**< A user defined ID of the Group. */ mtapi_group_attributes_t const * attributes + /**< The GroupAttributes to use. */ ) { - needs_delete_ = false; mtapi_status_t status; - handle_ = mtapi_group_create(group_id, attributes, &status); + handle_ = mtapi_group_create(id, attributes, &status); internal::CheckStatus(status); - needs_delete_ = true; } Task Start( @@ -307,7 +275,6 @@ class Group { } mtapi_group_hndl_t handle_; - bool needs_delete_; }; } // namespace mtapi diff --git a/mtapi_cpp/include/embb/mtapi/job.h b/mtapi_cpp/include/embb/mtapi/job.h index 7b4c0f9..38a274d 100644 --- a/mtapi_cpp/include/embb/mtapi/job.h +++ b/mtapi_cpp/include/embb/mtapi/job.h @@ -50,19 +50,6 @@ class Job { } /** - * Constructs a Job with the given \c job_id and \c domain_id. - * Requires an initialized Node. - */ - Job( - mtapi_job_id_t job_id, /**< Job ID to use. */ - mtapi_domain_t domain_id /**< Domain ID to use. */ - ) { - mtapi_status_t status; - handle_ = mtapi_job_get(job_id, domain_id, &status); - internal::CheckStatus(status); - } - - /** * Copies a Job object. */ Job( @@ -91,8 +78,23 @@ class Job { return handle_; } + friend class Node; + 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 diff --git a/mtapi_cpp/include/embb/mtapi/node.h b/mtapi_cpp/include/embb/mtapi/node.h index 115e48c..9a03b57 100644 --- a/mtapi_cpp/include/embb/mtapi/node.h +++ b/mtapi_cpp/include/embb/mtapi/node.h @@ -31,9 +31,12 @@ #include #include #include +#include +#include #include #include #include +#include namespace embb { @@ -69,16 +72,7 @@ class Node { static void Initialize( mtapi_domain_t domain_id, /**< [in] The domain id to use */ mtapi_node_t node_id /**< [in] The node id to use */ - ) { - if (IsInitialized()) { - EMBB_THROW(StatusException, - "MTAPI: node was already initialized."); - } else { - NodeAttributes attributes; // default attributes - node_instance_ = embb::base::Allocation::New( - domain_id, node_id, attributes); - } - } + ); /** * Initializes the runtime singleton. @@ -91,15 +85,7 @@ class Node { mtapi_domain_t domain_id, /**< [in] The domain id to use */ mtapi_node_t node_id, /**< [in] The node id to use */ NodeAttributes const & attributes /**< [in] Attributes to use */ - ) { - if (IsInitialized()) { - EMBB_THROW(StatusException, - "MTAPI: node was already initialized."); - } else { - node_instance_ = embb::base::Allocation::New( - domain_id, node_id, attributes); - } - } + ); /** * Checks if runtime is initialized. @@ -116,29 +102,14 @@ class Node { * \return Reference to the Node singleton * \threadsafe */ - static Node & GetInstance() { - if (IsInitialized()) { - return *node_instance_; - } else { - EMBB_THROW(StatusException, - "MTAPI: node is not initialized."); - } - } + static Node & GetInstance(); /** * Shuts the runtime system down. * \throws ErrorException if the singleton is not initialized. * \notthreadsafe */ - static void Finalize() { - if (IsInitialized()) { - embb::base::Allocation::Delete(node_instance_); - node_instance_ = NULL; - } else { - EMBB_THROW(StatusException, - "MTAPI: node is not initialized."); - } - } + static void Finalize(); /** * Returns the number of available cores. @@ -159,6 +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. * * \returns The handle to the started Task. @@ -238,6 +218,123 @@ 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_); + } + + Job GetJob(mtapi_job_id_t job_id, mtapi_domain_t domain_id) { + return Job(job_id, domain_id); + } + + /** + * Constructs an Action. + */ + Action CreateAction( + mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ + mtapi_action_function_t func, /**< The action function */ + const void * node_local_data, /**< Node local data available to all + Tasks using this Action */ + mtapi_size_t node_local_data_size, /**< Size of node local data */ + ActionAttributes const & attributes + /**< Attributes of the Action */ + ) { + return Action(job_id, func, node_local_data, node_local_data_size, + &attributes.GetInternal()); + } + + /** + * Constructs an Action. + */ + Action CreateAction( + mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ + mtapi_action_function_t func, /**< The action function */ + const void * node_local_data, /**< Node local data available to all + Tasks using this Action */ + mtapi_size_t node_local_data_size /**< Size of node local data */ + ) { + return Action(job_id, func, node_local_data, node_local_data_size, + MTAPI_DEFAULT_ACTION_ATTRIBUTES); + } + + /** + * Constructs an Action. + */ + Action CreateAction( + mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ + mtapi_action_function_t func, /**< The action function */ + ActionAttributes const & attributes + /**< Attributes of the Action */ + ) { + return Action(job_id, func, MTAPI_NULL, 0, &attributes.GetInternal()); + } + + /** + * Constructs an Action. + */ + Action CreateAction( + mtapi_job_id_t job_id, /**< Job ID the Action belongs to */ + mtapi_action_function_t func /**< The action function */ + ) { + return Action(job_id, func, MTAPI_NULL, 0, MTAPI_DEFAULT_ACTION_ATTRIBUTES); + } + + /** + * Constructs a Group object with default attributes. + */ + Group CreateGroup() { + return Group(MTAPI_GROUP_ID_NONE, MTAPI_DEFAULT_GROUP_ATTRIBUTES); + } + + /** + * Constructs a Group object with default attributes and the given ID. + */ + Group CreateGroup( + mtapi_group_id_t id /**< A user defined ID of the Group. */ + ) { + return Group(id, MTAPI_DEFAULT_GROUP_ATTRIBUTES); + } + + /** + * Constructs a Group object using the given Attributes. + */ + Group CreateGroup( + GroupAttributes const & group_attr) { + return Group(MTAPI_GROUP_ID_NONE, &group_attr.GetInternal()); + } + + /** + * Constructs a Group object with given attributes and ID. + */ + Group CreateGroup( + mtapi_group_id_t id, /**< A user defined ID of the Group. */ + GroupAttributes const & group_attr /**< The GroupAttributes to use. */ + ) { + return Group(id, &group_attr.GetInternal()); + } + + /** + * Constructs a Queue with the given Job and default attributes. + */ + Queue CreateQueue( + Job & job /**< The Job to use for the Queue. */ + ) { + return Queue(MTAPI_QUEUE_ID_NONE, job, MTAPI_DEFAULT_QUEUE_ATTRIBUTES); + } + + /** + * Constructs a Queue with the given Job and QueueAttributes. + */ + Queue CreateQueue( + Job const & job, /**< The Job to use for the Queue. */ + QueueAttributes const & attr /**< The attributes to use. */ + ) { + return Queue(MTAPI_QUEUE_ID_NONE, job, &attr.GetInternal()); + } + friend class embb::base::Allocation; private: @@ -251,21 +348,15 @@ class Node { NodeAttributes const & attr) { mtapi_status_t status; mtapi_info_t info; + queue_count_ = attr.GetInternal().max_queues; mtapi_initialize(domain_id, node_id, &attr.GetInternal(), &info, &status); - needs_finalize_ = status == MTAPI_SUCCESS; internal::CheckStatus(status); core_count_ = info.hardware_concurrency; worker_thread_count_ = embb_core_set_count( &attr.GetInternal().core_affinity); - } - ~Node() { - if (needs_finalize_) { - mtapi_status_t status; - mtapi_finalize(&status); - internal::CheckStatus(status); - } + domain_id_ = domain_id; } Task Start( @@ -288,9 +379,10 @@ class Node { static embb::mtapi::Node * node_instance_; + mtapi_domain_t domain_id_; mtapi_uint_t core_count_; mtapi_uint_t worker_thread_count_; - bool needs_finalize_; + mtapi_uint_t queue_count_; }; } // namespace mtapi diff --git a/mtapi_cpp/include/embb/mtapi/queue.h b/mtapi_cpp/include/embb/mtapi/queue.h index 718fac3..5f372b2 100644 --- a/mtapi_cpp/include/embb/mtapi/queue.h +++ b/mtapi_cpp/include/embb/mtapi/queue.h @@ -51,31 +51,19 @@ namespace mtapi { */ class Queue { public: - /** - * Constructs a Queue with the given Job and default attributes. - * Requires an initialized Node. - */ - Queue( - Job const & job /**< The Job to use for the Queue. */ - ) { - Create(MTAPI_QUEUE_ID_NONE, job, MTAPI_DEFAULT_QUEUE_ATTRIBUTES); + Queue(Queue const & other) : handle_(other.handle_) { + // empty } - /** - * Constructs a Queue with the given Job and QueueAttributes. - * Requires an initialized Node. - */ - Queue( - Job const & job, /**< The Job to use for the Queue. */ - QueueAttributes const & attr /**< The attributes to use. */ - ) { - Create(MTAPI_QUEUE_ID_NONE, job, &attr.GetInternal()); + Queue & operator=(Queue const & other) { + handle_ = other.handle_; + return *this; } /** - * Destroys a Queue object. + * Deletes a Queue object. */ - ~Queue() { + void Delete() { mtapi_queue_delete(handle_, MTAPI_INFINITE, MTAPI_NULL); } @@ -272,16 +260,13 @@ class Queue { } friend class embb::base::Allocation; + friend class Node; private: // no default constructor Queue(); - // not copyable - Queue(Queue const & other); - void operator=(Queue const & other); - - void Create( + Queue( mtapi_queue_id_t queue_id, Job const & job, mtapi_queue_attributes_t const * attributes diff --git a/mtapi_cpp/src/execution_policy.cc b/mtapi_cpp/src/execution_policy.cc new file mode 100644 index 0000000..80f2cf6 --- /dev/null +++ b/mtapi_cpp/src/execution_policy.cc @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2014-2016, Siemens AG. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +namespace embb { +namespace 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 diff --git a/mtapi_cpp/src/node.cc b/mtapi_cpp/src/node.cc index 9b77f2c..bf27a62 100644 --- a/mtapi_cpp/src/node.cc +++ b/mtapi_cpp/src/node.cc @@ -30,6 +30,74 @@ namespace embb { namespace mtapi { embb::mtapi::Node * embb::mtapi::Node::node_instance_ = NULL; +#if MTAPI_CPP_AUTOMATIC_INITIALIZE +static embb_spinlock_t init_mutex = { { 0 } }; +#endif + +void Node::Initialize( + mtapi_domain_t domain_id, + mtapi_node_t node_id + ) { + if (IsInitialized()) { + EMBB_THROW(StatusException, + "MTAPI: node was already initialized."); + } + else { + NodeAttributes attributes; // default attributes + node_instance_ = embb::base::Allocation::New( + domain_id, node_id, attributes); + } +} + +void Node::Initialize( + mtapi_domain_t domain_id, + mtapi_node_t node_id, + NodeAttributes const & attributes + ) { + if (IsInitialized()) { + EMBB_THROW(StatusException, + "MTAPI: node was already initialized."); + } + else { + node_instance_ = embb::base::Allocation::New( + domain_id, node_id, attributes); + } +} + +Node & Node::GetInstance() { +#if MTAPI_CPP_AUTOMATIC_INITIALIZE + if (!IsInitialized()) { + embb_spin_lock(&init_mutex); + if (!IsInitialized()) { + Node::Initialize( + MTAPI_CPP_AUTOMATIC_DOMAIN_ID, MTAPI_CPP_AUTOMATIC_NODE_ID); + atexit(Node::Finalize); + } + embb_spin_unlock(&init_mutex); + } + return *node_instance; +#else + if (IsInitialized()) { + return *node_instance_; + } + else { + EMBB_THROW(StatusException, + "MTAPI: node is not initialized."); + } +#endif +} + +void Node::Finalize() { + if (IsInitialized()) { + mtapi_finalize(MTAPI_NULL); + embb::base::Allocation::Delete(node_instance_); + node_instance_ = NULL; + } + else { + EMBB_THROW(StatusException, + "MTAPI: node is not initialized."); + } +} } // namespace mtapi } // namespace embb diff --git a/mtapi_cpp/test/mtapi_cpp_test_group.cc b/mtapi_cpp/test/mtapi_cpp_test_group.cc index 1378311..a384316 100644 --- a/mtapi_cpp/test/mtapi_cpp_test_group.cc +++ b/mtapi_cpp/test/mtapi_cpp_test_group.cc @@ -61,12 +61,14 @@ GroupTest::GroupTest() { void GroupTest::TestBasic() { embb::mtapi::Node::Initialize(THIS_DOMAIN_ID, THIS_NODE_ID); + embb::mtapi::Node & node = embb::mtapi::Node::GetInstance(); - embb::mtapi::Job job(JOB_TEST_GROUP, THIS_DOMAIN_ID); - embb::mtapi::Action action(JOB_TEST_GROUP, testGroupAction); + embb::mtapi::Job job = node.GetJob(JOB_TEST_GROUP); + embb::mtapi::Action action = + node.CreateAction(JOB_TEST_GROUP, testGroupAction); { - embb::mtapi::Group group; + embb::mtapi::Group group = node.CreateGroup(); result_example_t buffer[TASK_COUNT]; for (int ii = 0; ii < TASK_COUNT; ii++) { @@ -86,7 +88,7 @@ void GroupTest::TestBasic() { } { - embb::mtapi::Group group; + embb::mtapi::Group group = node.CreateGroup(); result_example_t buffer[TASK_COUNT]; for (int ii = 0; ii < 4; ii++) { diff --git a/mtapi_cpp/test/mtapi_cpp_test_queue.cc b/mtapi_cpp/test/mtapi_cpp_test_queue.cc index 8e17abf..6a492fb 100644 --- a/mtapi_cpp/test/mtapi_cpp_test_queue.cc +++ b/mtapi_cpp/test/mtapi_cpp_test_queue.cc @@ -54,13 +54,14 @@ QueueTest::QueueTest() { void QueueTest::TestBasic() { embb::mtapi::Node::Initialize(THIS_DOMAIN_ID, THIS_NODE_ID); + embb::mtapi::Node & node = embb::mtapi::Node::GetInstance(); - embb::mtapi::Job job(JOB_TEST_QUEUE, THIS_DOMAIN_ID); - embb::mtapi::Action action(JOB_TEST_QUEUE, testQueueAction, - MTAPI_NULL, 0); + embb::mtapi::Job job = node.GetJob(JOB_TEST_QUEUE); + embb::mtapi::Action action = node.CreateAction( + JOB_TEST_QUEUE, testQueueAction, MTAPI_NULL, 0); { - embb::mtapi::Queue queue(job); + embb::mtapi::Queue queue = node.CreateQueue(job); int result = 0; embb::mtapi::Task task = queue.Enqueue(MTAPI_NULL, &result); diff --git a/mtapi_cpp/test/mtapi_cpp_test_task.cc b/mtapi_cpp/test/mtapi_cpp_test_task.cc index fa3de4e..7600b04 100644 --- a/mtapi_cpp/test/mtapi_cpp_test_task.cc +++ b/mtapi_cpp/test/mtapi_cpp_test_task.cc @@ -96,9 +96,10 @@ void TaskTest::TestBasic() { } { - embb::mtapi::Job job_task(JOB_TEST_TASK, THIS_DOMAIN_ID); + embb::mtapi::Job job_task = node.GetJob(JOB_TEST_TASK); - embb::mtapi::Action action_task(JOB_TEST_TASK, testTaskAction); + embb::mtapi::Action action_task = + node.CreateAction(JOB_TEST_TASK, testTaskAction); std::string test; embb::mtapi::Task task = node.Start(job_task, "simple", &test); @@ -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::ActionAttributes()); + embb::mtapi::Action action_error = + node.CreateAction(JOB_TEST_ERROR, testErrorAction); std::string test; embb::mtapi::Task task = node.Start(job_error, "simple", &test);