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 #include <assert.h>
28 
29 #include <embb/mtapi/c/mtapi.h>
30 
31 #include <embb/base/c/internal/unused.h>
32 
33 #include <embb_mtapi_log.h>
34 #include <embb_mtapi_alloc.h>
35 #include <mtapi_status_t.h>
36 #include <embb_mtapi_task_context_t.h>
37 #include <embb_mtapi_thread_context_t.h>
38 #include <embb_mtapi_task_t.h>
39 
40 
41 /* ---- CLASS MEMBERS ------------------------------------------------------ */
42 
embb_mtapi_task_context_initialize_with_thread_context_and_task(embb_mtapi_task_context_t * that,embb_mtapi_thread_context_t * thread_context,embb_mtapi_task_t * task)43 void embb_mtapi_task_context_initialize_with_thread_context_and_task(
44   embb_mtapi_task_context_t* that,
45   embb_mtapi_thread_context_t* thread_context,
46   embb_mtapi_task_t* task) {
47   assert(MTAPI_NULL != that);
48   assert(MTAPI_NULL != thread_context);
49   assert(MTAPI_NULL != task);
50 
51   that->task = task;
52   that->thread_context = thread_context;
53   that->num_instances = task->attributes.num_instances;
54   that->instance_num =
55     embb_atomic_fetch_and_add_unsigned_int(&task->current_instance, 1);
56 }
57 
embb_mtapi_task_context_finalize(embb_mtapi_task_context_t * that)58 void embb_mtapi_task_context_finalize(embb_mtapi_task_context_t* that) {
59   assert(MTAPI_NULL != that);
60 
61   that->instance_num = 0;
62   that->num_instances = 0;
63   that->task = MTAPI_NULL;
64   that->thread_context = MTAPI_NULL;
65 }
66 
67 
68 /* ---- INTERFACE FUNCTIONS ------------------------------------------------ */
69 
mtapi_context_status_set(MTAPI_INOUT mtapi_task_context_t * task_context,MTAPI_IN mtapi_status_t error_code,MTAPI_OUT mtapi_status_t * status)70 void mtapi_context_status_set(
71   MTAPI_INOUT mtapi_task_context_t* task_context,
72   MTAPI_IN mtapi_status_t error_code,
73   MTAPI_OUT mtapi_status_t* status) {
74   mtapi_status_t local_status = MTAPI_ERR_UNKNOWN;
75 
76   embb_mtapi_log_trace("mtapi_action_status_set() called\n");
77 
78   if (MTAPI_NULL != task_context) {
79     embb_mtapi_thread_context_t* local_context =
80       (embb_mtapi_thread_context_t*)embb_tss_get(
81         &(task_context->thread_context->tss_id));
82 
83     if (local_context == task_context->thread_context) {
84       /* for remote actions the result shall be transferred to the
85          waiting node at the end of the task */
86       switch (error_code) {
87       case MTAPI_SUCCESS:
88       case MTAPI_ERR_ARG_SIZE:
89       case MTAPI_ERR_RESULT_SIZE:
90       case MTAPI_ERR_ACTION_CANCELLED:
91       case MTAPI_ERR_ACTION_FAILED:
92       case MTAPI_ERR_ACTION_DELETED:
93         task_context->task->error_code = error_code;
94         local_status = MTAPI_SUCCESS;
95         break;
96       case MTAPI_ERR_CORE_NUM:
97       case MTAPI_ERR_RUNTIME_LOADBALANCING_NOTSUPPORTED:
98       case MTAPI_ERR_RUNTIME_REMOTETASKS_NOTSUPPORTED:
99       case MTAPI_ERR_ARG_NOT_IMPLEMENTED:
100       case MTAPI_ERR_FUNC_NOT_IMPLEMENTED:
101       case MTAPI_ERR_WAIT_PENDING:
102       case MTAPI_ERR_BUFFER_SIZE:
103       case MTAPI_ERR_UNKNOWN:
104       case MTAPI_GROUP_COMPLETED:
105       case MTAPI_ERR_GROUP_LIMIT:
106       case MTAPI_ERR_GROUP_INVALID:
107       case MTAPI_ERR_QUEUE_LIMIT:
108       case MTAPI_ERR_QUEUE_DISABLED:
109       case MTAPI_ERR_QUEUE_DELETED:
110       case MTAPI_ERR_QUEUE_INVALID:
111       case MTAPI_ERR_JOB_INVALID:
112       case MTAPI_ERR_TASK_LIMIT:
113       case MTAPI_ERR_TASK_INVALID:
114       case MTAPI_ERR_CONTEXT_OUTOFCONTEXT:
115       case MTAPI_ERR_CONTEXT_INVALID:
116       case MTAPI_ERR_ACTION_DISABLED:
117       case MTAPI_ERR_ACTION_NUM_INVALID:
118       case MTAPI_ERR_ACTION_LIMIT:
119       case MTAPI_ERR_ACTION_EXISTS:
120       case MTAPI_ERR_ACTION_INVALID:
121       case MTAPI_ERR_NODE_NOTINIT:
122       case MTAPI_ERR_DOMAIN_INVALID:
123       case MTAPI_ERR_NODE_INVALID:
124       case MTAPI_ERR_NODE_INITIALIZED:
125       case MTAPI_ERR_NODE_INITFAILED:
126       case MTAPI_ERR_ATTR_SIZE:
127       case MTAPI_ERR_ATTR_READONLY:
128       case MTAPI_ERR_PARAMETER:
129       case MTAPI_TIMEOUT:
130       case MTAPI_ERR_ATTR_NUM:
131       default:
132         /* trying to set invalid error code */
133         local_status = MTAPI_ERR_PARAMETER;
134         break;
135       }
136     } else {
137       local_status = MTAPI_ERR_CONTEXT_OUTOFCONTEXT;
138     }
139   } else {
140     local_status = MTAPI_ERR_CONTEXT_INVALID;
141   }
142 
143   mtapi_status_set(status, local_status);
144 }
145 
mtapi_context_runtime_notify(MTAPI_IN mtapi_task_context_t * task_context,MTAPI_IN mtapi_notification_t notification,MTAPI_IN void * data,MTAPI_IN mtapi_size_t data_size,MTAPI_OUT mtapi_status_t * status)146 void mtapi_context_runtime_notify(
147   MTAPI_IN mtapi_task_context_t* task_context,
148   MTAPI_IN mtapi_notification_t notification,
149   MTAPI_IN void* data,
150   MTAPI_IN mtapi_size_t data_size,
151   MTAPI_OUT mtapi_status_t* status) {
152   mtapi_status_t local_status = MTAPI_ERR_UNKNOWN;
153 
154   EMBB_UNUSED(notification);
155   EMBB_UNUSED(data);
156   EMBB_UNUSED(data_size);
157 
158   embb_mtapi_log_trace("mtapi_context_runtime_notify() called\n");
159 
160   if (MTAPI_NULL != task_context) {
161     mtapi_task_context_t* local_context = (mtapi_task_context_t*) embb_tss_get(
162       &(task_context->thread_context->tss_id));
163 
164     if (local_context == task_context) {
165       local_status = MTAPI_SUCCESS;
166     } else {
167       local_status = MTAPI_ERR_CONTEXT_OUTOFCONTEXT;
168     }
169   } else {
170     local_status = MTAPI_ERR_CONTEXT_INVALID;
171   }
172 
173   mtapi_status_set(status, local_status);
174 }
175 
mtapi_context_taskstate_get(MTAPI_IN mtapi_task_context_t * task_context,MTAPI_OUT mtapi_status_t * status)176 mtapi_task_state_t mtapi_context_taskstate_get(
177   MTAPI_IN mtapi_task_context_t* task_context,
178   MTAPI_OUT mtapi_status_t* status) {
179   mtapi_status_t local_status = MTAPI_ERR_UNKNOWN;
180   mtapi_task_state_t task_state = MTAPI_TASK_ERROR;
181 
182   embb_mtapi_log_trace("mtapi_context_taskstate_get() called\n");
183 
184   if (MTAPI_NULL != task_context) {
185     embb_mtapi_thread_context_t* local_context =
186       (embb_mtapi_thread_context_t*)embb_tss_get(
187         &(task_context->thread_context->tss_id));
188 
189     if (local_context == task_context->thread_context) {
190       task_state = (mtapi_task_state_t)embb_atomic_load_int(
191         &task_context->task->state);
192       local_status = MTAPI_SUCCESS;
193     } else {
194       local_status = MTAPI_ERR_CONTEXT_OUTOFCONTEXT;
195     }
196   } else {
197     local_status = MTAPI_ERR_CONTEXT_INVALID;
198   }
199 
200   mtapi_status_set(status, local_status);
201   return task_state;
202 }
203 
204 /* derived from OpenMP's omp_get_thread_num(); */
mtapi_context_instnum_get(MTAPI_IN mtapi_task_context_t * task_context,MTAPI_OUT mtapi_status_t * status)205 mtapi_uint_t mtapi_context_instnum_get(
206   MTAPI_IN mtapi_task_context_t* task_context,
207   MTAPI_OUT mtapi_status_t* status) {
208   mtapi_status_t local_status = MTAPI_ERR_UNKNOWN;
209   mtapi_uint_t instnum = 0;
210 
211   embb_mtapi_log_trace("mtapi_context_instnum_get() called\n");
212 
213   if (MTAPI_NULL != task_context) {
214     embb_mtapi_thread_context_t* local_context =
215       (embb_mtapi_thread_context_t*)embb_tss_get(
216         &(task_context->thread_context->tss_id));
217 
218     if (local_context == task_context->thread_context) {
219       instnum = task_context->instance_num;
220       local_status = MTAPI_SUCCESS;
221     } else {
222       local_status = MTAPI_ERR_CONTEXT_OUTOFCONTEXT;
223     }
224   } else {
225     local_status = MTAPI_ERR_CONTEXT_INVALID;
226   }
227 
228   mtapi_status_set(status, local_status);
229   return instnum;
230 }
231 
232 /* derived from OpenMP's omp_get_num_threads(); */
mtapi_context_numinst_get(MTAPI_IN mtapi_task_context_t * task_context,MTAPI_OUT mtapi_status_t * status)233 mtapi_uint_t mtapi_context_numinst_get(
234   MTAPI_IN mtapi_task_context_t* task_context,
235   MTAPI_OUT mtapi_status_t* status) {
236   mtapi_status_t local_status = MTAPI_ERR_UNKNOWN;
237   mtapi_uint_t numinst = 0;
238 
239   embb_mtapi_log_trace("mtapi_context_numinst_get() called\n");
240 
241   if (MTAPI_NULL != task_context) {
242     embb_mtapi_thread_context_t* local_context =
243       (embb_mtapi_thread_context_t*)embb_tss_get(
244         &(task_context->thread_context->tss_id));
245 
246     if (local_context == task_context->thread_context) {
247       numinst = task_context->num_instances;
248       local_status = MTAPI_SUCCESS;
249     } else {
250       local_status = MTAPI_ERR_CONTEXT_OUTOFCONTEXT;
251     }
252   } else {
253     local_status = MTAPI_ERR_CONTEXT_INVALID;
254   }
255 
256   mtapi_status_set(status, local_status);
257   return numinst;
258 }
259 
mtapi_context_corenum_get(MTAPI_IN mtapi_task_context_t * task_context,MTAPI_OUT mtapi_status_t * status)260 mtapi_uint_t mtapi_context_corenum_get(
261   MTAPI_IN mtapi_task_context_t* task_context,
262   MTAPI_OUT mtapi_status_t* status) {
263   mtapi_status_t local_status = MTAPI_ERR_UNKNOWN;
264   mtapi_uint_t corenum = 0;
265 
266   embb_mtapi_log_trace("mtapi_context_corenum_get() called\n");
267 
268   if (MTAPI_NULL != task_context) {
269     embb_mtapi_thread_context_t* local_context =
270       (embb_mtapi_thread_context_t*)embb_tss_get(
271         &(task_context->thread_context->tss_id));
272 
273     if (local_context == task_context->thread_context) {
274       corenum = task_context->thread_context->core_num;
275       local_status = MTAPI_SUCCESS;
276     } else {
277       local_status = MTAPI_ERR_CONTEXT_OUTOFCONTEXT;
278     }
279   } else {
280     local_status = MTAPI_ERR_CONTEXT_INVALID;
281   }
282 
283   mtapi_status_set(status, local_status);
284   return corenum;
285 }
286