2 * @file frsh_sharedobj.c
3 * @author Dario Faggioli <faggioli@gandalf.sssup.it>
5 * @brief FRSH shared objects related functions.
9 #include <fres_contract.h>
10 #include <fres_contract_idl.h>
11 #include <frsh_error.h>
12 #include <fres_blocks.h>
13 #include <frsh_core.h>
14 #include <fres_sharedobj.h>
16 int frsh_sharedobj_init
17 (const char *obj_label,
18 frsh_sharedobj_kind_t obj_kind,
19 frsh_sharedobj_handle_t *obj_handle,
23 return FRSH_ERR_BAD_ARGUMENT;
25 /* In this implementation external mutex is not supported, *
26 * use frsh_sharedobj_get_mutex instead. */
28 return FRSH_ERR_BAD_ARGUMENT;
30 *obj_handle = fres_sharedobj_new(obj_label, obj_kind);
31 if (!(*obj_handle)) goto err;
38 int frsh_sharedobj_get_handle
40 frsh_sharedobj_handle_t *obj_handle)
42 if (!obj_label || !obj_handle)
43 return FRSH_ERR_BAD_ARGUMENT;
45 *obj_handle = fres_sharedobj_get_label(obj_label);
46 if (!(*obj_handle)) goto err;
53 int frsh_sharedobj_get_mutex
54 (frsh_sharedobj_handle_t obj_handle,
57 if (!obj_handle || !mutex)
58 return FRSH_ERR_BAD_ARGUMENT;
60 *mutex = &obj_handle->mutex;
65 int frsh_sharedobj_get_obj_kind
66 (frsh_sharedobj_handle_t obj_handle,
67 frsh_sharedobj_kind_t *obj_kind)
69 if (!obj_handle || !obj_kind)
70 return FRSH_ERR_BAD_ARGUMENT;
72 *obj_kind = obj_handle->kind;
77 int frsh_sharedobj_remove(frsh_sharedobj_handle_t obj_handle)
80 return FRSH_ERR_BAD_ARGUMENT;
82 return fres_sharedobj_destroy(obj_handle);
85 /* Critical Sections. */
88 (frsh_sharedobj_handle_t obj_handle,
92 if (!obj_handle || !csect)
93 return FRSH_ERR_BAD_ARGUMENT;
95 csect->op_kind = FRSH_CSOK_UNCHECKED;
96 strncpy(csect->obj_label,
98 sizeof(obj_handle->label));
100 csect->blocking = wcet;
102 csect->areas.size = 0;
107 int frsh_csect_get_sharedobj_handle
108 (const frsh_csect_t *csect,
109 frsh_sharedobj_handle_t *obj_handle)
111 if (!obj_handle || !csect)
112 return FRSH_ERR_BAD_ARGUMENT;
114 *obj_handle = fres_sharedobj_get_label(csect->obj_label);
119 int frsh_csect_get_wcet
120 (const frsh_csect_t *csect,
121 frsh_rel_time_t *wcet)
124 return FRSH_ERR_BAD_ARGUMENT;
131 int frsh_csect_get_blocking_time
132 (const frsh_csect_t *csect,
133 fosa_rel_time_t *blocking)
135 if (!csect || !blocking)
136 return FRSH_ERR_BAD_ARGUMENT;
138 *blocking = csect->blocking;
143 int frsh_csect_get_op_kind
144 (const frsh_csect_t *csect,
145 frsh_csect_op_kind_t *op_kind)
147 if (!csect || !op_kind)
148 return FRSH_ERR_BAD_ARGUMENT;
150 *op_kind = csect->op_kind;
155 int frsh_csect_get_read_op
156 (const frsh_csect_t *csect,
161 csect->op_kind != FRSH_CSOK_READ)
162 return FRSH_ERR_BAD_ARGUMENT;
169 int frsh_csect_get_write_op
170 (const frsh_csect_t *csect,
172 frsh_memory_areas_t *areas)
179 csect->op_kind != FRSH_CSOK_WRITE)
180 return FRSH_ERR_BAD_ARGUMENT;
183 areas->size = csect->areas.size;
185 for (i = 0; i < areas->size; i++)
186 areas->memory_areas[i] = csect->areas.memory_areas[i];
191 int frsh_csect_register_read_op
192 (frsh_csect_t *csect,
196 return FRSH_ERR_BAD_ARGUMENT;
198 csect->op_kind = FRSH_CSOK_READ;
201 /* Account for protection overheads: NOT IMPLEMENTED! */
202 /* csect->blocking = fosa_rel_time_add(csect->wcet, ); */
203 csect->blocking = csect->wcet;
208 int frsh_csect_register_write_op
209 (frsh_csect_t *csect,
211 const frsh_memory_areas_t *areas)
216 return FRSH_ERR_BAD_ARGUMENT;
218 if (areas->size <= 0 || areas->size > FRSH_MAX_N_MEMORY_AREAS)
219 return FRSH_ERR_BAD_ARGUMENT;
222 * Check for the shared object associated with this
223 * critical section not to be UNPROTECTED;
226 csect->areas.size = areas->size;
227 csect->op_kind = FRSH_CSOK_WRITE;
230 for (i = 0; i< areas->size; i++)
231 csect->areas.memory_areas[i] = areas->memory_areas[i];
233 /* Account for protection and rollback overheads: NOT IMPLEMENTED! */
234 /* csect->blocking = fosa_rel_time_add(csect->wcet, ); */
235 csect->blocking = csect->wcet;
240 int frsh_csect_invoke
241 (const frsh_csect_t *csect,
242 const void *input_arg,
245 int i, jumped, ret = 0;
246 frsh_memory_areas_t storage = { .size = 0 };
247 frsh_sharedobj_handle_t obj_handle;
248 fosa_mutex_t *obj_mutex;
249 fosa_clock_id_t clockid;
250 fosa_signal_t signal;
251 fosa_signal_info_t siginfo;
254 ret = FRSH_ERR_BAD_ARGUMENT;
258 obj_handle = fres_sharedobj_get_label(csect->obj_label);
263 ret = frsh_sharedobj_get_mutex(obj_handle, &obj_mutex);
265 ret = fosa_mutex_lock(obj_mutex);
268 siginfo.sival_ptr = (void*) (&(obj_handle->context));
269 ret = fosa_long_jump_install_handler(&signal, NULL);
270 if (ret) goto out_unlock;
272 /* Prepare the WCET timer. */
273 ret = fosa_thread_get_cputime_clock(fosa_thread_self() ,&clockid);
274 if (ret) goto out_unlock;
275 ret = fosa_timer_create_with_receiver(clockid,
278 &obj_handle->wcet_timer,
280 if (ret) goto out_unlock;
281 ret = fosa_rel_timer_arm(obj_handle->wcet_timer, &csect->wcet);
282 if (ret) goto out_disarm;
284 /* Backup memory areas. */
285 if (csect->op_kind == FRSH_CSOK_WRITE) {
286 for (i = 0; i < csect->areas.size; i++) {
287 storage.memory_areas[i].size =
288 csect->areas.memory_areas[i].size;
289 storage.memory_areas[i].area =
290 malloc(csect->areas.memory_areas[i].size);
291 if (!storage.memory_areas[i].area) {
295 if (!memcpy(storage.memory_areas[i].area,
296 csect->areas.memory_areas[i].area,
297 csect->areas.memory_areas[i].size)) {
305 ret = fosa_long_jump_save_context(&obj_handle->context);
306 if (ret) goto out_disarm;
307 ret = fosa_long_jump_was_performed(&obj_handle->context, &jumped);
308 if (ret) goto out_disarm;
311 /* Invoke the operation. */
312 csect->op(input_arg,output_arg);
314 /* Leave the critical section normally. */
318 ret = FRSH_ERR_BUDGET_EXPIRED;
320 /* Restore backed-up memory areas. */
321 if (csect->op_kind == FRSH_CSOK_WRITE) {
322 for (i = 0; i < csect->areas.size; i++)
323 if (!memcpy(csect->areas.memory_areas[i].area,
324 storage.memory_areas[i].area,
325 csect->areas.memory_areas[i].size)) {
332 fosa_timer_disarm(obj_handle->wcet_timer, NULL);
333 fosa_timer_delete(obj_handle->wcet_timer);
335 for (i = 0; i < storage.size; i++)
336 if (storage.memory_areas[i].area) /* Uneeded ? */
337 free(storage.memory_areas[i].area);
340 fosa_mutex_unlock(obj_mutex);
345 /* Contract Parameters. */
347 int frsh_contract_set_csects
348 (frsh_contract_t *contract,
349 const frsh_csects_group_t *critical_sections)
351 fres_block_csects *c;
354 if (!contract || !*contract || !critical_sections)
355 return FRSH_ERR_BAD_ARGUMENT;
357 if (critical_sections->size < 0 ||
358 critical_sections->size > FRSH_MAX_N_CRITICAL_SECTIONS)
359 return FRSH_ERR_BAD_ARGUMENT;
361 c = malloc(sizeof(*c));
362 if (!c) return FOSA_ENOMEM;
364 len = critical_sections->size;
365 c->sections._length = len;
366 c->sections._maximum = len;
367 c->sections._buffer = CORBA_sequence_frsh_csect_runtime_allocbuf(len);
368 for (i = 0; i < len; i++)
369 memcpy(&c->sections._buffer[i],
370 &critical_sections->csects[i],
371 sizeof(c->sections._buffer[i]));
373 fres_contract_del_csects(*contract);
374 ret = fres_contract_add_csects(*contract, c);
384 int frsh_contract_get_csects
385 (const frsh_contract_t *contract,
386 frsh_csects_group_t *critical_sections)
388 fres_block_csects *c;
391 if (!contract || !*contract || !critical_sections)
392 return FRSH_ERR_BAD_ARGUMENT;
394 c = fres_contract_get_csects(*contract);
396 critical_sections->size = c->sections._length;
397 for (i = 0; i < critical_sections->size; i++)
398 memcpy(&critical_sections->csects[i],
399 &c->sections._buffer[i],
400 sizeof(critical_sections->csects[i]));