Embedded Multicore Building Blocks V1.0.0
node.h
1 /*
2  * Copyright (c) 2014-2017, Siemens AG. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #ifndef EMBB_MTAPI_NODE_H_
28 #define EMBB_MTAPI_NODE_H_
29 
30 #include <embb/base/memory_allocation.h>
31 #include <embb/base/function.h>
32 #include <embb/mtapi/c/mtapi.h>
33 #include <embb/mtapi/c/mtapi_ext.h>
34 #include <embb/mtapi/execution_policy.h>
35 #include <embb/mtapi/status_exception.h>
36 #include <embb/mtapi/node_attributes.h>
37 #include <embb/mtapi/group.h>
38 #include <embb/mtapi/queue.h>
39 #include <embb/mtapi/task.h>
40 #include <embb/mtapi/task_attributes.h>
41 #include <embb/mtapi/job.h>
42 #include <embb/mtapi/action.h>
43 #include <embb/mtapi/task_context.h>
44 
45 #ifdef GetJob
46 #undef GetJob
47 #endif
48 
49 #ifdef MTAPI_CPP_AUTOMATIC_INITIALIZE
50 #define MTAPI_CPP_AUTOMATIC_DOMAIN_ID 1
51 #define MTAPI_CPP_AUTOMATIC_NODE_ID 1
52 #endif
53 #define EMBB_MTAPI_FUNCTION_JOB_ID 2
54 
55 namespace embb {
56 
57 namespace base {
58 
59 class Allocation;
60 
61 } // namespace base
62 
63 namespace mtapi {
64 
70 class Node {
71  public:
76 
81  ~Node() {
82  function_action_.Delete();
83  mtapi_finalize(MTAPI_NULL);
84  }
85 
100  static void Initialize(
101  mtapi_domain_t domain_id,
102  mtapi_node_t node_id
103  );
104 
112  static void Initialize(
113  mtapi_domain_t domain_id,
114  mtapi_node_t node_id,
115  NodeAttributes const & attributes
116  );
117 
124  static bool IsInitialized() {
125  return NULL != node_instance_;
126  }
127 
133  static Node & GetInstance();
134 
140  static void Finalize();
141 
147  mtapi_uint_t GetCoreCount() const {
148  return core_count_;
149  }
150 
156  mtapi_uint_t GetWorkerThreadCount() const {
157  return worker_thread_count_;
158  }
159 
165  mtapi_uint_t GetQueueCount() const {
166  return queue_count_;
167  }
168 
174  mtapi_uint_t GetGroupCount() const {
175  return group_count_;
176  }
177 
183  mtapi_uint_t GetTaskLimit() const {
184  return task_limit_;
185  }
186 
194  SMPFunction const & func
195  ) {
196  Job job = GetJob(EMBB_MTAPI_FUNCTION_JOB_ID);
197  void * res = NULL;
198  return Start(
199  job, embb::base::Allocation::New<SMPFunction>(func), res);
200  }
201 
209  SMPFunction const & func,
210  ExecutionPolicy const & policy
212  ) {
213  Job job = GetJob(EMBB_MTAPI_FUNCTION_JOB_ID);
214  void * res = NULL;
215  TaskAttributes task_attr;
216  task_attr.SetPolicy(policy);
217  return Start(
218  job, embb::base::Allocation::New<SMPFunction>(func), res, task_attr);
219  }
220 
227  template <typename ARGS, typename RES>
229  mtapi_task_id_t task_id,
230  Job const & job,
231  const ARGS * arguments,
232  RES * results,
233  TaskAttributes const & attributes
234  ) {
235  return Start(task_id,
236  job.GetInternal(),
237  arguments, internal::SizeOfType<ARGS>(),
238  results, internal::SizeOfType<RES>(),
239  &attributes.GetInternal());
240  }
241 
248  template <typename ARGS, typename RES>
250  mtapi_task_id_t task_id,
251  Job const & job,
252  const ARGS * arguments,
253  RES * results
254  ) {
255  return Start(task_id,
256  job.GetInternal(),
257  arguments, internal::SizeOfType<ARGS>(),
258  results, internal::SizeOfType<RES>(),
259  MTAPI_DEFAULT_TASK_ATTRIBUTES);
260  }
261 
268  template <typename ARGS, typename RES>
270  Job const & job,
271  const ARGS * arguments,
272  RES * results,
273  TaskAttributes const & attributes
274  ) {
275  return Start(MTAPI_TASK_ID_NONE,
276  job.GetInternal(),
277  arguments, internal::SizeOfType<ARGS>(),
278  results, internal::SizeOfType<RES>(),
279  &attributes.GetInternal());
280  }
281 
288  template <typename ARGS, typename RES>
290  Job const & job,
291  const ARGS * arguments,
292  RES * results
293  ) {
294  return Start(MTAPI_TASK_ID_NONE,
295  job.GetInternal(),
296  arguments, internal::SizeOfType<ARGS>(),
297  results, internal::SizeOfType<RES>(),
298  MTAPI_DEFAULT_TASK_ATTRIBUTES);
299  }
300 
309  mtapi_job_id_t job_id
310  ) {
311  return Job(job_id, domain_id_);
312  }
313 
321  mtapi_job_id_t job_id,
322  mtapi_domain_t domain_id
323  ) {
324  return Job(job_id, domain_id);
325  }
326 
334  mtapi_job_id_t job_id,
336  const void * node_local_data,
338  mtapi_size_t node_local_data_size,
339  ActionAttributes const & attributes
341  ) {
342  return Action(job_id, func, node_local_data, node_local_data_size,
343  &attributes.GetInternal());
344  }
345 
353  mtapi_job_id_t job_id,
355  const void * node_local_data,
357  mtapi_size_t node_local_data_size
358  ) {
359  return Action(job_id, func, node_local_data, node_local_data_size,
360  MTAPI_DEFAULT_ACTION_ATTRIBUTES);
361  }
362 
370  mtapi_job_id_t job_id,
372  ActionAttributes const & attributes
374  ) {
375  return Action(job_id, func, MTAPI_NULL, 0, &attributes.GetInternal());
376  }
377 
385  mtapi_job_id_t job_id,
387  ) {
388  return Action(job_id, func, MTAPI_NULL, 0, MTAPI_DEFAULT_ACTION_ATTRIBUTES);
389  }
390 
398  return Group(MTAPI_GROUP_ID_NONE, MTAPI_DEFAULT_GROUP_ATTRIBUTES);
399  }
400 
408  mtapi_group_id_t id
409  ) {
410  return Group(id, MTAPI_DEFAULT_GROUP_ATTRIBUTES);
411  }
412 
420  GroupAttributes const & group_attr
421  ) {
422  return Group(MTAPI_GROUP_ID_NONE, &group_attr.GetInternal());
423  }
424 
432  mtapi_group_id_t id,
433  GroupAttributes const & group_attr
434  ) {
435  return Group(id, &group_attr.GetInternal());
436  }
437 
445  Job & job
446  ) {
447  return Queue(MTAPI_QUEUE_ID_NONE, job, MTAPI_DEFAULT_QUEUE_ATTRIBUTES);
448  }
449 
457  Job const & job,
458  QueueAttributes const & attr
459  ) {
460  return Queue(MTAPI_QUEUE_ID_NONE, job, &attr.GetInternal());
461  }
462 
463  friend class embb::base::Allocation;
464 
472  mtapi_task_id_t task_id,
473  mtapi_job_hndl_t job,
474  const void * arguments,
475  mtapi_size_t arguments_size,
476  void * results,
477  mtapi_size_t results_size,
478  mtapi_task_attributes_t const * attributes
480  ) {
481  mtapi_status_t status;
482  mtapi_task_hndl_t task_hndl =
483  mtapi_task_start(task_id, job, arguments, arguments_size,
484  results, results_size, attributes, MTAPI_GROUP_NONE,
485  &status);
486  internal::CheckStatus(status);
487  return Task(task_hndl);
488  }
489 
495  mtapi_ext_yield();
496  }
497 
498  private:
499  // not copyable
500  Node(Node const & node);
501  Node const & operator=(Node const & other);
502 
503  Node(
504  mtapi_domain_t domain_id,
505  mtapi_node_t node_id,
506  NodeAttributes const & attr) {
507  mtapi_status_t status;
508  mtapi_info_t info;
509  queue_count_ = attr.GetInternal().max_queues;
510  group_count_ = attr.GetInternal().max_groups;
511  task_limit_ = attr.GetInternal().max_tasks;
512  mtapi_initialize(domain_id, node_id, &attr.GetInternal(), &info, &status);
513  internal::CheckStatus(status);
514 
515  core_count_ = info.hardware_concurrency;
516  worker_thread_count_ = embb_core_set_count(
517  &attr.GetInternal().core_affinity);
518 
519  domain_id_ = domain_id;
520 
521  function_action_ =
522  CreateAction(EMBB_MTAPI_FUNCTION_JOB_ID, ActionFunction);
523  }
524 
525  static void ActionFunction(
526  const void* args,
527  mtapi_size_t /*args_size*/,
528  void* /*result_buffer*/,
529  mtapi_size_t /*result_buffer_size*/,
530  const void* /*node_local_data*/,
531  mtapi_size_t /*node_local_data_size*/,
532  mtapi_task_context_t * context) {
533  TaskContext task_context(context);
536  const_cast<void*>(args));
537  (*func)(task_context);
539  }
540 
541  static embb::mtapi::Node * node_instance_;
542 
543  mtapi_domain_t domain_id_;
544  mtapi_uint_t core_count_;
545  mtapi_uint_t worker_thread_count_;
546  mtapi_uint_t queue_count_;
547  mtapi_uint_t group_count_;
548  mtapi_uint_t task_limit_;
549  Action function_action_;
550 };
551 
552 } // namespace mtapi
553 } // namespace embb
554 
555 #endif // EMBB_MTAPI_NODE_H_
Definition: lock_free_mpmc_queue.h:40
embb::base::Function< void, TaskContext & > SMPFunction
Function type for simple SMP interface.
Definition: node.h:75
Action CreateAction(mtapi_job_id_t job_id, mtapi_action_function_t func)
Constructs an Action.
Definition: node.h:384
void mtapi_ext_yield()
This function yields execution to the MTAPI scheduler for at most one task.
Contains attributes of a Node.
Definition: node_attributes.h:42
Action CreateAction(mtapi_job_id_t job_id, mtapi_action_function_t func, const void *node_local_data, mtapi_size_t node_local_data_size)
Constructs an Action.
Definition: node.h:352
Contains attributes of an Action.
Definition: action_attributes.h:42
A singleton representing the MTAPI runtime.
Definition: node.h:70
Action CreateAction(mtapi_job_id_t job_id, mtapi_action_function_t func, const void *node_local_data, mtapi_size_t node_local_data_size, ActionAttributes const &attributes)
Constructs an Action.
Definition: node.h:333
Job GetJob(mtapi_job_id_t job_id)
Retrieves a handle to the Job identified by job_id within the domain of the local Node...
Definition: node.h:308
static bool IsInitialized()
Checks if runtime is initialized.
Definition: node.h:124
~Node()
Destroys the runtime singleton.
Definition: node.h:81
Queue CreateQueue(Job const &job, QueueAttributes const &attr)
Constructs a Queue with the given Job and QueueAttributes.
Definition: node.h:456
Task Start(SMPFunction const &func)
Starts a new Task.
Definition: node.h:193
void mtapi_initialize(const mtapi_domain_t domain_id, const mtapi_node_t node_id, const mtapi_node_attributes_t *attributes, mtapi_info_t *mtapi_info, mtapi_status_t *status)
Initializes the MTAPI environment on a given MTAPI node in a given MTAPI domain.
Task Start(mtapi_task_id_t task_id, mtapi_job_hndl_t job, const void *arguments, mtapi_size_t arguments_size, void *results, mtapi_size_t results_size, mtapi_task_attributes_t const *attributes)
Starts a new Task.
Definition: node.h:471
Task Start(mtapi_task_id_t task_id, Job const &job, const ARGS *arguments, RES *results)
Starts a new Task.
Definition: node.h:249
Task Start(mtapi_task_id_t task_id, Job const &job, const ARGS *arguments, RES *results, TaskAttributes const &attributes)
Starts a new Task.
Definition: node.h:228
mtapi_task_attributes_t const & GetInternal() const
Returns the internal representation of this object.
Definition: task_attributes.h:148
mtapi_action_attributes_t const & GetInternal() const
Returns the internal representation of this object.
Definition: action_attributes.h:114
mtapi_uint_t GetGroupCount() const
Returns the number of available groups.
Definition: node.h:174
Contains attributes of a Group.
Definition: group_attributes.h:41
mtapi_uint_t GetQueueCount() const
Returns the number of available queues.
Definition: node.h:165
Represents a collection of Actions.
Definition: job.h:41
Task Start(Job const &job, const ARGS *arguments, RES *results)
Starts a new Task.
Definition: node.h:289
Wraps function pointers, member function pointers, and functors with up to five arguments.
Definition: function.h:94
Allows for stream processing, either ordered or unordered.
Definition: queue.h:52
mtapi_node_attributes_t const & GetInternal() const
Returns the internal representation of this object.
Definition: node_attributes.h:261
Queue CreateQueue(Job &job)
Constructs a Queue with the given Job and default attributes.
Definition: node.h:444
Group CreateGroup(GroupAttributes const &group_attr)
Constructs a Group object using the given Attributes.
Definition: node.h:419
Contains attributes of a Task.
Definition: task_attributes.h:42
mtapi_task_hndl_t mtapi_task_start(const mtapi_task_id_t task_id, const mtapi_job_hndl_t job, const void *arguments, const mtapi_size_t arguments_size, void *result_buffer, const mtapi_size_t result_size, const mtapi_task_attributes_t *attributes, const mtapi_group_hndl_t group, mtapi_status_t *status)
This function schedules a task for execution.
mtapi_queue_attributes_t const & GetInternal() const
Returns the internal representation of this object.
Definition: queue_attributes.h:166
void mtapi_finalize(mtapi_status_t *status)
Finalizes the MTAPI environment on a given MTAPI node and domain.
Group CreateGroup(mtapi_group_id_t id, GroupAttributes const &group_attr)
Constructs a Group object with given attributes and ID.
Definition: node.h:431
Task Start(Job const &job, const ARGS *arguments, RES *results, TaskAttributes const &attributes)
Starts a new Task.
Definition: node.h:269
mtapi_uint_t GetTaskLimit() const
Returns the number of available tasks.
Definition: node.h:183
unsigned int embb_core_set_count(const embb_core_set_t *core_set)
Returns the number of cores contained in the specified set.
Describes the execution policy of a parallel algorithm.
Definition: execution_policy.h:48
TaskAttributes & SetPolicy(ExecutionPolicy const &policy)
Sets the ExecutionPolicy of a Task.
Definition: task_attributes.h:114
Task Start(SMPFunction const &func, ExecutionPolicy const &policy)
Starts a new Task with a given affinity and priority.
Definition: node.h:208
mtapi_uint_t GetWorkerThreadCount() const
Returns the number of worker threads.
Definition: node.h:156
Group CreateGroup(mtapi_group_id_t id)
Constructs a Group object with default attributes and the given ID.
Definition: node.h:407
Group CreateGroup()
Constructs a Group object with default attributes.
Definition: node.h:397
static void Delete(Type *to_delete)
Destructs an instance of type Type and frees the allocated memory.
Definition: memory_allocation.h:176
Represents a facility to wait for multiple related Tasks.
Definition: group.h:52
mtapi_uint_t GetCoreCount() const
Returns the number of available cores.
Definition: node.h:147
Action CreateAction(mtapi_job_id_t job_id, mtapi_action_function_t func, ActionAttributes const &attributes)
Constructs an Action.
Definition: node.h:369
mtapi_group_attributes_t const & GetInternal() const
Returns the internal representation of this object.
Definition: group_attributes.h:60
void(* mtapi_action_function_t)(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)
An action function is the executable software function that implements an action. ...
Definition: mtapi.h:941
void YieldToScheduler()
This function yields execution to the MTAPI scheduler for at most one task.
Definition: node.h:494
Job GetJob(mtapi_job_id_t job_id, mtapi_domain_t domain_id)
Retrieves a handle to the Job identified by job_id and domain_id.
Definition: node.h:320
Common (static) functionality for unaligned and aligned memory allocation.
Definition: memory_allocation.h:55
Holds the actual worker function used to execute a Task.
Definition: action.h:42
Provides information about the status of the currently running Task.
Definition: task_context.h:41
Contains attributes of a Queue.
Definition: queue_attributes.h:41
A Task represents a running Action of a specific Job.
Definition: task.h:41
mtapi_job_hndl_t GetInternal() const
Returns the internal representation of this object.
Definition: job.h:80