1 // -----------------------------------------------------------------------
2 // Copyright (C) 2006 - 2007 FRESCOR consortium partners:
4 // Universidad de Cantabria, SPAIN
5 // University of York, UK
6 // Scuola Superiore Sant'Anna, ITALY
7 // Kaiserslautern University, GERMANY
8 // Univ. Politécnica Valencia, SPAIN
9 // Czech Technical University in Prague, CZECH REPUBLIC
11 // Thales Communication S.A. FRANCE
12 // Visual Tools S.A. SPAIN
13 // Rapita Systems Ltd UK
16 // See http://www.frescor.org for a link to partners' websites
18 // FRESCOR project (FP6/2005/IST/5-034026) is funded
19 // in part by the European Union Sixth Framework Programme
20 // The European Union is not liable of any use that may be
24 // based on previous work (FSF) done in the FIRST project
26 // Copyright (C) 2005 Mälardalen University, SWEDEN
27 // Scuola Superiore S.Anna, ITALY
28 // Universidad de Cantabria, SPAIN
29 // University of York, UK
31 // FSF API web pages: http://marte.unican.es/fsf/docs
32 // http://shark.sssup.it/contrib/first/docs/
34 // This file is part of FRSH API
36 // FRSH API is free software; you can redistribute it and/or modify
37 // it under the terms of the GNU General Public License as published by
38 // the Free Software Foundation; either version 2, or (at your option)
41 // FRSH API is distributed in the hope that it will be useful, but
42 // WITHOUT ANY WARRANTY; without even the implied warranty of
43 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
44 // General Public License for more details.
46 // You should have received a copy of the GNU General Public License
47 // distributed with FRSH API; see file COPYING. If not, write to the
48 // Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
51 // As a special exception, if you include this header file into source
52 // files to be compiled, this header file does not by itself cause
53 // the resulting executable to be covered by the GNU General Public
54 // License. This exception does not however invalidate any other
55 // reasons why the executable file might be covered by the GNU General
57 // -----------------------------------------------------------------------
58 //frsh_shared_objects.h
60 //==============================================
61 // ******** ******* ******** ** **
62 // **///// /**////** **////// /** /**
63 // ** /** /** /** /** /**
64 // ******* /******* /********* /**********
65 // **//// /**///** ////////** /**//////**
66 // ** /** //** /** /** /**
67 // ** /** //** ******** /** /**
68 // // // // //////// // //
70 // FRSH(FRescor ScHeduler), pronounced "fresh"
71 //==============================================
73 #ifndef _FRSH_SHARED_OBJECTS_H_
74 #define _FRSH_SHARED_OBJECTS_H_
76 #include "frsh_shared_objects_types.h"
77 #include "frsh_core_types.h"
80 #define FRSH_SHAREDOBJS_MODULE_SUPPORTED 1
83 * @file frsh_shared_objects.h
87 * @defgroup sharedobj Shared Objects module
89 * This module includes the functions to declare and use shared
90 * objects in different critical sections.
92 * A shared object is an abstraction of a mutex giving it a name and a
93 * possible priority ceiling.
95 * A critical section represents a usage of a shared object with a wcet.
96 * One or more critical sections can be included in a contract.
98 * There are two types of shared_objects: protected and unprotected.
100 * - <b>UNPROTECTED shared objects</b>. These shared objects are always
101 * used in trusted critical sections for which the worst-case
102 * execution times can be guaranteed not to be exceeded by the
103 * application designer (eg because tools have been used to verify
104 * the schedulability off-line). Given these conditions, there is
105 * no need to have a mechanism to monitor their execution time, with
106 * the corresponding savings in overhead.
108 * - <b>PROTECTED shared objects</b>. For these shared objects a mechanism
109 * may be used in one or more of their critical sections to monitor
110 * and enforce their worst-case execution time. These shared
111 * objects are restricted to data in regular memory because a
112 * mechanism to save and restore the state is necessary in order to
113 * cleanly abort a misbehaving critical section.\n
115 * Critical sections are categorized depending on wcet monitoring and
116 * rollback capability.
118 * - <b>UNCHECKED critical sections</b>. These critical sections are
119 * not monitored by FRSH for wcet compliance. Their wcet value is
120 * used only for analysis purposes (calculation of blocking times).
122 * - <b>READ critical sections</b>. These critical sections have
123 * their wcet enforced but they don't have any rollback action
124 * applied when their wcet is exceeded.
126 * - <b>WRITE critical sections</b>. These critical sections have
127 * their wcet monitored and they have a rollback mechanism applied
128 * to their memory areas prior to being aborted for exceeding their
131 * READ and WRITE critical sections must use PROTECTED shared objects,
132 * but UNCHECKED critical sections may use PROTECTED or UNPROTECTED
135 * The monitoring mechanism for READ and WRITE critical section works
136 * by executing them indirectly via a registered callback function.
137 * UNCHECKED critical sections are executed directly by the
140 * The rollback mechanism for WRITE critical sections requires an
141 * additional registration of the memory areas that the callback
142 * function may modify. With this data FRSH will do an initial saving
143 * of this areas that will used for restoration when there is a rollback
146 * Note that extra time for the saving and the restoration must be
147 * included in the wcet specified for a WRITE critical section.
148 * Functions are provided to assist the developer in calculating this
151 * The reason for allowing the use of PROTECTED shared objects in
152 * UNCHECKED critical sections is to allow for legacy or trusted
153 * code that would use UNCHECKED critical sections to share a shared
154 * object with an untrusted code using READ or WRITE critical sections.
156 * This module makes use of the following constants defined in
157 * frsh_configuration_parameters.h. We list them with our proposed
160 * FRSH_MAX_N_SHARED_OBJECTS 100 \n
161 * FRSH_MAX_N_CRITICAL_SECTIONS 20\n
162 * FRSH_MAX_N_MEMORY_AREAS 4\n
168 /////////////////////////////////////////////////////
169 // SHARED OBJECTS & OPERATIONS MANAGEMENT
170 /////////////////////////////////////////////////////
172 * @defgroup so_opp_mgmnt Shared Objects & Operations
175 * These functions are used to declare shared objects and link them
182 * frsh_sharedobj_init()
184 * Initialization of shared objects. If the object identified by
185 * obj_label does not yet exist, it is created, a handle to the object is
186 * returned in the variable pointed to by obj_handle, and the
187 * specified mutex is initialized with the appropriate attributes
188 * necessary for the current implementation. If the object already
189 * exists, the function fails. The object is created according to the
190 * kind of object (protected or unprotected) specified by obj_kind
192 * @param[in] obj_label Label defined by the application. Char * for
193 * a string of FRSH_MAX_SIZE_SHARED_OBJ_LABEL
194 * characters (+ null terminating \0).
196 * @param[in] obj_kind Whether it is protected or unprotected.
198 * @param[out] obj_handle Placeholder for the shared object handle.
200 * @param[out] mutex Placeholder for the mutex.
202 * @return 0 if no error \n
203 * FRSH_ERR_BAD_ARGUMENT : if obj_label, obj_handle, or mutex are NULL \n
204 * FRSH_ERR_SHARED_OBJ_ALREADY_INITIALIZED : if the object identified
205 * by label already exists \n
206 * FRSH_ERR_TOO_MANY_SHARED_OBJS : if the number of already
207 * initialized shared objects exceed the
208 * FRSH_MAX_N_SHARED_OBJECTS configuration parameter. \n
210 * It may also return any of the error codes that are returned by
211 * fosa_mutex_init() and fosa_mutex_set_prioceiling().
214 int frsh_sharedobj_init
216 frsh_sharedobj_kind_t obj_kind,
217 frsh_sharedobj_handle_t *obj_handle,
218 frsh_mutex_t *mutex);
223 * frsh_sharedobj_get_handle()
225 * Getting the handle of shared objects. If the object already exists
226 * a handle to the object is returned in the variable pointed to by
227 * obj_handle. Otherwise, an error code is returned.
229 * @param[in] obj_label Defined by the application at object creation
230 * time. Char * for a string of FRSH_MAX_SIZE_SHARED_OBJ_LABEL
231 * characters (+ null terminating \0).
233 * @param[out] obj_handle Placeholder for the object handle.
235 * @return 0 if no error \n
236 * FRSH_ERR_BAD_ARGUMENT : if label or obj_handle are NULL \n
237 * FRSH_ERR_SHARED_OBJ_NOT_INITIALIZED : if the shared object identified
238 * by obj_label does not exist \n
239 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
240 * scheduled under FRSH \n
241 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
243 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
244 * has been cancelled or it is not valid \n
246 * It may also return any of the error codes that are returned by the
247 * fosa_mutex_init() function call
250 int frsh_sharedobj_get_handle
252 frsh_sharedobj_handle_t *obj_handle);
256 * frsh_sharedobj_get_mutex()
258 * Getting the mutex of shared objects.
260 * @param[in] obj_handle Handle of the shared object
262 * @param[out] mutex Placeholder for A POINTER to a pointer of the
263 * mutex. We give the pointer to discourage the
264 * application of using a local copy of the mutex.
266 * @return 0 if no error \n
267 * FRSH_ERR_BAD_ARGUMENT : if obj_handle or mutex are NULL or obj_handle
268 * is not correct or reference a wrong shared object \n
269 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
270 * scheduled under the FRSH \n
271 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
273 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
274 * has been cancelled or it is not valid
277 int frsh_sharedobj_get_mutex
278 (frsh_sharedobj_handle_t obj_handle,
279 frsh_mutex_t **mutex);
282 * frsh_sharedobj_get_obj_kind()
284 * Get the object kind (protected/unprotected) of the object handle.
286 * @param[in] obj_handle Handle of the shared object
288 * @param[out] obj_kind Placeholder for an enumeration variable of
289 * protected / unprotected.
291 * @return 0 if no error \n
292 * FRSH_ERR_BAD_ARGUMENT : if obj_handle or mutex are NULL or obj_handle
293 * is not correct or reference a wrong shared object \n
294 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
295 * scheduled under the FRSH \n
296 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
298 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
299 * has been cancelled or it is not valid
302 int frsh_sharedobj_get_obj_kind
303 (frsh_sharedobj_handle_t obj_handle,
304 frsh_sharedobj_kind_t *obj_kind);
307 * frsh_sharedobj_remove()
309 * Allows the implementation to remove a shared object when the last
310 * vres referencing it is cancelled. This removes the object id and
311 * other internal data associated with the object, but does not remove
312 * the mutex; this is done by the application through the common POSIX
315 * @return 0 if no error \n
316 * FRSH_ERR_BAD_ARGUMENT : if obj_handle is NULL or obj_handle
317 * is not correct or references a wrong shared object \n
318 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
319 * scheduled under the FRSH \n
320 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
322 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
323 * has been cancelled or it is not valid
326 int frsh_sharedobj_remove
327 (frsh_sharedobj_handle_t obj_handle);
333 /////////////////////////////////////////////////////
335 /////////////////////////////////////////////////////
337 * @defgroup so_critical Critical Sections
340 * These functions are used to create and manage the parameters
341 * of critical sections. Critical sections are operations that
342 * make use of a shared object in a mutually exclusive way.
350 * Initialize the critical section pointed to by csect
351 * with a handle to its shared object, and the worst-case execution
354 * The operation_kind is set to FRSH_CSOK_UNCHECKED.
356 * @param[in] obj_handle Shared object previously initialised.
358 * @param[in] wcet Execution time of the critical section. This
359 * budget is consumed in parallel with the vres budget.
361 * @param[out] csect Critical section memory placeholder.
363 * @return 0 if no error \n
364 * FRSH_ERR_BAD_ARGUMENT : if obj_handle is NULL \b or \n
365 * obj_handle is not correct or references a wrong shared object \b or \n
366 * if wcet is in the wrong format for specifying a time interval value \n
367 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
368 * scheduled under the FRSH \n
369 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
371 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
372 * has been cancelled or it is not valid
376 (frsh_sharedobj_handle_t obj_handle,
377 struct timespec wcet,
378 frsh_csect_t *csect);
382 * frsh_csect_get_sharedobj_handle()
384 * Get in the variable pointed to by obj_handle the handle to the
385 * shared object stored in the critical section referenced by csect
387 * @return 0 if no error \n
388 * FRSH_ERR_BAD_ARGUMENT : if csect or obj_handle are NULL or csect
390 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
391 * scheduled under the FRSH \n
392 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
394 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
395 * has been cancelled or it is not valid
398 int frsh_csect_get_sharedobj_handle
399 (const frsh_csect_t *csect,
400 frsh_sharedobj_handle_t * obj_handle);
403 * frsh_csect_get_wcet()
405 * Get in the variable pointed to by wcet the worst-case execution time
406 * of the operation stored in the critical section referenced by csect.
408 * @return 0 if no error \n
409 * FRSH_ERR_BAD_ARGUMENT : if csect or wcet are NULL or csect
411 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
412 * scheduled under FRSH \n
413 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
415 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
416 * has been cancelled or it is not valid
419 int frsh_csect_get_wcet
420 (const frsh_csect_t *csect,
421 struct timespec *wcet);
425 * frsh_csect_register_read_op()
427 * Register the given operation with the critical section and set
428 * op_kind to FRSH_CSOK_READ.
430 * The function returns an error if the shared_object is unprotected.
432 * @return 0 if no error \n
433 * FRSH_ERR_BAD_ARGUMENT : if csect or op are NULL or if csect points
434 * to a wrong critical section or if the shared_object is of type
436 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
437 * scheduled under FRSH \n
438 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
440 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
441 * has been cancelled or it is not valid
444 int frsh_csect_register_read_op
445 (frsh_csect_t *csect,
449 * frsh_csect_register_write_op()
451 * Register the given operation with the critical section, register
452 * the memory areas and set op_kind to FRSH_CSOK_WRITE.
454 * If the memory areas are empty the functions returns an error.
456 * The function returns an error if the shared_object is unprotected.
458 * @return 0 if no error \n
459 * FRSH_ERR_BAD_ARGUMENT : if op, csect or areas are NULL or csect points
460 * to a wrong critical section, or areas has a wrong size, or if the
461 * shared_object of csect is of type unprotected.
462 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
463 * scheduled under the FRSH \n
464 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
466 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
467 * has been cancelled or it is not valid
470 int frsh_csect_register_write_op
471 (frsh_csect_t *csect,
473 const frsh_memory_areas_t *areas);
477 * frsh_csect_get_op_kind()
479 * Returns the type of operation (read/write/unchecked) of the critical section.
481 * @return 0 if no error \n
482 * FRSH_ERR_BAD_ARGUMENT : if csect or op_kind are NULL or csect
484 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
485 * scheduled under FRSH \n
486 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
488 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
489 * has been cancelled or it is not valid
492 int frsh_csect_get_op_kind
493 (const frsh_csect_t *csect,
494 frsh_csect_op_kind_t *op_kind);
498 * frsh_csect_get_read_op()
500 * Get into the variable pointed to by op the operation pointer stored
501 * in the critical section referenced by csect.
503 * If the csect is of type write or unchecked it returns an error.
505 * @return 0 if no error \n
506 * FRSH_ERR_BAD_ARGUMENT : if csect is NULL or points to a wrong
507 * critical section, or to a critical section that is not of the
508 * FRSH_CSOK_READ kind \n
509 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
510 * scheduled under FRSH \n
511 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
513 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
514 * has been cancelled or it is not valid
517 int frsh_csect_get_read_op
518 (const frsh_csect_t *csect,
519 frsh_csect_op_t *op);
524 * frsh_csect_get_write_op()
526 * Get the operation pointer and the memory areas stored in the csect.
528 * If the csect is of type read or unchecked.
530 * @return 0 if no error \n
531 * FRSH_ERR_BAD_ARGUMENT : if csect is NULL or points to a wrong
532 * critical section, or to a critical section that is not of the
533 * FRSH_CSOK_WRITE kind \n
534 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
535 * scheduled under FRSH \n
536 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
538 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
539 * has been cancelled or it is not valid \n
542 int frsh_csect_get_write_op
543 (const frsh_csect_t *csect,
545 frsh_memory_areas_t *areas);
549 * frsh_csect_invoke()
551 * Invoke the registered operation in the critical section, with the pointers
552 * to the input and output parameters specified by input_arg and
555 * If the section is of type FRSH_CSOK_UNCHECKED, the function returns
558 * For read operations, the mutex is locked, the csect budget is set equal
559 * to the wcet, the registered read operation is invoked, and then the
560 * mutex is unlocked; if the csect budget expires, the operation is
561 * interrupted, the mutex is unlocked, and the function returns with
564 * For write operations, the mutex is locked, the registered memory
565 * areas are backed up, the csect budget is set equal to the wcet, the
566 * registered write operation is called, and the mutex is unlocked. If
567 * the csect budget expires, the operation is interrupted, the backed-up
568 * memory areas are recovered, the mutex is unlocked, and the function
569 * returns with an error code. The blocking time suffered by higher
570 * priority tasks is at most the wcet of the operation plus the backup
571 * time plus the recovery time.
573 * If the shared object in the critical section is not protected it
576 * @return 0 if no error \n
577 * FRSH_ERR_BAD_ARGUMENT : if csect is NULL or points to a wrong
578 * critical section, or to a critical section that is unprotected \n
579 * FRSH_ERR_BUDGET_EXPIRED : the csect budget expired and the protected
580 * operation was interrupted \n
581 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
582 * scheduled under FRSH \n
583 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
585 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
586 * has been cancelled or it is not valid
589 int frsh_csect_invoke
590 (const frsh_csect_t *csect,
591 const void * input_arg,
595 * frsh_csect_get_blocking_time()
597 * Get in the variable pointed to by blocking the maximum blocking
598 * time of the operation of the referenced protected critical section.
600 * For read or unchecked operations, the maximum blocking time is the wcet.
602 * For write operations, the maximum blocking time suffered by higher
603 * priority tasks is the wcet of the operation plus the backup time
604 * plus the recovery time.
606 * @return 0 if no error \n
607 * FRSH_ERR_BAD_ARGUMENT : if csect or blocking are NULL or if csect
608 * points to a wrong critical section, or to a critical section
609 * that is unprotected \n
610 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
611 * scheduled under FRSH \n
612 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
614 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
615 * has been cancelled or it is not valid
618 int frsh_csect_get_blocking_time
619 (const frsh_csect_t *csect,
620 struct timespec *blocking);
624 * frsh_csect_destroy()
626 * Destroy a critical section, deallocating all the resources that may
627 * have been allocated to it.
629 int frsh_csect_destroy
630 (frsh_csect_t *csect);
633 * frsh_csect_register_thread()
635 * Register the calling thread for invoking time-protected critical
636 * sections via frsh_csect_invoke.
638 int frsh_csect_register_thread();
641 * frsh_csect_deregister_thread()
643 * Deregister the calling thread from being able to invoke
644 * time-protected critical sections. This operation releases system
645 * resources that may have been allocated for the thread.
647 int frsh_csect_deregister_thread();
651 /*@}*/ /* For so_critical group */
654 /////////////////////////////////////////////////////
655 // CONTRACT PARAMETERS
656 /////////////////////////////////////////////////////
658 * @defgroup so_contract Shared Objects & Contract Parameters
661 * These functions are used to link shared objects to contracts via
669 * frsh_contract_set_csects()
671 * The operation updates the specified contract parameters object by
672 * setting its critical sections to the specified input parameter.
674 * @return 0 if no error \n
675 * FRSH_ERR_BAD_ARGUMENT : if any of the pointers is NULL or
676 * the size of the critical_sections structure is less than zero
677 * or greater than FRSH_MAX_N_CRITICAL_SECTIONS
680 int frsh_contract_set_csects
681 (frsh_contract_t *contract,
682 const frsh_csects_group_t *critical_sections);
685 * frsh_contract_get_csects()
687 * The operation obtains from the specified contract parameters object
688 * its critical sections, and copies them to the places pointed to by
689 * the specified input parameter. Only those critical_section_data
690 * records that are in use in the critical_sections structure are
691 * copied (according to its size field).
693 * @return 0 if no error \n
694 * FRSH_ERR_BAD_ARGUMENT : if any of the pointers is NULL
697 int frsh_contract_get_csects
698 (const frsh_contract_t *contract,
699 frsh_csects_group_t *critical_sections);
701 /*@}*/ /* For so_contract group */
703 /*@}*/ /* For shared_objects group */
705 #endif // _FRSH_SHARED_OBJECTS_H_