1 // -----------------------------------------------------------------------
2 // Copyright (C) 2006 - 2008 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 (FRescor ScHeduler)
36 // FRSH is free software; you can redistribute it and/or modify it
37 // under terms of the GNU General Public License as published by the
38 // Free Software Foundation; either version 2, or (at your option) any
39 // later version. FRSH is distributed in the hope that it will be
40 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
41 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
42 // General Public License for more details. You should have received a
43 // copy of the GNU General Public License along with FRSH; see file
44 // COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
45 // Cambridge, MA 02139, USA.
47 // As a special exception, including FRSH header files in a file,
48 // instantiating FRSH generics or templates, or linking other files
49 // with FRSH objects to produce an executable application, does not
50 // by itself cause the resulting executable application to be covered
51 // by the GNU General Public License. This exception does not
52 // however invalidate any other reasons why the executable file might be
53 // covered by the GNU Public License.
54 // As a special exception, if you include this header file into source
55 // files to be compiled, this header file does not by itself cause
56 // the resulting executable to be covered by the GNU General Public
57 // License. This exception does not however invalidate any other
58 // reasons why the executable file might be covered by the GNU General
60 // -----------------------------------------------------------------------
61 //frsh_shared_objects.h
63 //==============================================
64 // ******** ******* ******** ** **
65 // **///// /**////** **////// /** /**
66 // ** /** /** /** /** /**
67 // ******* /******* /********* /**********
68 // **//// /**///** ////////** /**//////**
69 // ** /** //** /** /** /**
70 // ** /** //** ******** /** /**
71 // // // // //////// // //
73 // FRSH(FRescor ScHeduler), pronounced "fresh"
74 //==============================================
76 #ifndef _FRSH_SHARED_OBJECTS_H_
77 #define _FRSH_SHARED_OBJECTS_H_
79 #include "frsh_shared_objects_types.h"
80 #include "frsh_core_types.h"
84 #define FRSH_SHAREDOBJS_MODULE_SUPPORTED 1
87 * @file frsh_shared_objects.h
91 * @defgroup sharedobj Shared Objects module
93 * This module includes the functions to declare and use shared
94 * objects in different critical sections.
96 * A shared object is an abstraction of a mutex giving it a name and a
97 * possible priority ceiling.
99 * A critical section represents a usage of a shared object with a wcet.
100 * One or more critical sections can be included in a contract.
102 * There are two types of shared_objects: protected and unprotected.
104 * - <b>UNPROTECTED shared objects</b>. These shared objects are always
105 * used in trusted critical sections for which the worst-case
106 * execution times can be guaranteed not to be exceeded by the
107 * application designer (eg because tools have been used to verify
108 * the schedulability off-line). Given these conditions, there is
109 * no need to have a mechanism to monitor their execution time, with
110 * the corresponding savings in overhead.
112 * - <b>PROTECTED shared objects</b>. For these shared objects a mechanism
113 * may be used in one or more of their critical sections to monitor
114 * and enforce their worst-case execution time. These shared
115 * objects are restricted to data in regular memory because a
116 * mechanism to save and restore the state is necessary in order to
117 * cleanly abort a misbehaving critical section.\n
119 * Critical sections are categorized depending on wcet monitoring and
120 * rollback capability.
122 * - <b>UNCHECKED critical sections</b>. These critical sections are
123 * not monitored by FRSH for wcet compliance. Their wcet value is
124 * used only for analysis purposes (calculation of blocking times).
126 * - <b>READ critical sections</b>. These critical sections have
127 * their wcet enforced but they don't have any rollback action
128 * applied when their wcet is exceeded.
130 * - <b>WRITE critical sections</b>. These critical sections have
131 * their wcet monitored and they have a rollback mechanism applied
132 * to their memory areas prior to being aborted for exceeding their
135 * READ and WRITE critical sections must use PROTECTED shared objects,
136 * but UNCHECKED critical sections may use PROTECTED or UNPROTECTED
139 * The monitoring mechanism for READ and WRITE critical section works
140 * by executing them indirectly via a registered callback function.
141 * UNCHECKED critical sections are executed directly by the
144 * The rollback mechanism for WRITE critical sections requires an
145 * additional registration of the memory areas that the callback
146 * function may modify. With this data FRSH will do an initial saving
147 * of this areas that will used for restoration when there is a rollback
150 * Note that extra time for the saving and the restoration must be
151 * included in the wcet specified for a WRITE critical section.
152 * Functions are provided to assist the developer in calculating this
155 * The reason for allowing the use of PROTECTED shared objects in
156 * UNCHECKED critical sections is to allow for legacy or trusted
157 * code that would use UNCHECKED critical sections to share a shared
158 * object with an untrusted code using READ or WRITE critical sections.
160 * This module makes use of the following constants defined in
161 * frsh_configuration_parameters.h. We list them with our proposed
164 * FRSH_MAX_N_SHARED_OBJECTS 100 \n
165 * FRSH_MAX_N_CRITICAL_SECTIONS 20\n
166 * FRSH_MAX_N_MEMORY_AREAS 4\n
172 /////////////////////////////////////////////////////
173 // SHARED OBJECTS & OPERATIONS MANAGEMENT
174 /////////////////////////////////////////////////////
176 * @defgroup so_opp_mgmnt Shared Objects & Operations
179 * These functions are used to declare shared objects and link them
186 * frsh_sharedobj_init()
188 * Initialization of shared objects. If the object identified by
189 * obj_label does not yet exist, it is created, a handle to the object is
190 * returned in the variable pointed to by obj_handle, and the
191 * specified mutex is initialized with the appropriate attributes
192 * necessary for the current implementation. If the object already
193 * exists, the function fails. The object is created according to the
194 * kind of object (protected or unprotected) specified by obj_kind
196 * @param[in] obj_label Label defined by the application. Char * for
197 * a string of FRSH_MAX_SIZE_SHARED_OBJ_LABEL
198 * characters (+ null terminating \0).
200 * @param[in] obj_kind Whether it is protected or unprotected.
202 * @param[out] obj_handle Placeholder for the shared object handle.
204 * @param[out] mutex Placeholder for the mutex.
206 * @return 0 if no error \n
207 * FRSH_ERR_BAD_ARGUMENT : if obj_label, obj_handle, or mutex are NULL \n
208 * FRSH_ERR_SHARED_OBJ_ALREADY_INITIALIZED : if the object identified
209 * by label already exists \n
210 * FRSH_ERR_TOO_MANY_SHARED_OBJS : if the number of already
211 * initialized shared objects exceed the
212 * FRSH_MAX_N_SHARED_OBJECTS configuration parameter. \n
214 * It may also return any of the error codes that are returned by
215 * fosa_mutex_init() and fosa_mutex_set_prioceiling().
218 int frsh_sharedobj_init
220 frsh_sharedobj_kind_t obj_kind,
221 frsh_sharedobj_handle_t *obj_handle,
222 frsh_mutex_t *mutex);
227 * frsh_sharedobj_get_handle()
229 * Getting the handle of shared objects. If the object already exists
230 * a handle to the object is returned in the variable pointed to by
231 * obj_handle. Otherwise, an error code is returned.
233 * @param[in] obj_label Defined by the application at object creation
234 * time. Char * for a string of FRSH_MAX_SIZE_SHARED_OBJ_LABEL
235 * characters (+ null terminating \0).
237 * @param[out] obj_handle Placeholder for the object handle.
239 * @return 0 if no error \n
240 * FRSH_ERR_BAD_ARGUMENT : if label or obj_handle are NULL \n
241 * FRSH_ERR_SHARED_OBJ_NOT_INITIALIZED : if the shared object identified
242 * by obj_label does not exist \n
243 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
244 * scheduled under FRSH \n
245 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
247 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
248 * has been cancelled or it is not valid \n
250 * It may also return any of the error codes that are returned by the
251 * fosa_mutex_init() function call
254 int frsh_sharedobj_get_handle
256 frsh_sharedobj_handle_t *obj_handle);
260 * frsh_sharedobj_get_mutex()
262 * Getting the mutex of shared objects.
264 * @param[in] obj_handle Handle of the shared object
266 * @param[out] mutex Placeholder for A POINTER to a pointer of the
267 * mutex. We give the pointer to discourage the
268 * application of using a local copy of the mutex.
270 * @return 0 if no error \n
271 * FRSH_ERR_BAD_ARGUMENT : if obj_handle or mutex are NULL or obj_handle
272 * is not correct or reference a wrong shared object \n
273 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
274 * scheduled under the FRSH \n
275 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
277 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
278 * has been cancelled or it is not valid
281 int frsh_sharedobj_get_mutex
282 (frsh_sharedobj_handle_t obj_handle,
283 frsh_mutex_t **mutex);
286 * frsh_sharedobj_get_obj_kind()
288 * Get the object kind (protected/unprotected) of the object handle.
290 * @param[in] obj_handle Handle of the shared object
292 * @param[out] obj_kind Placeholder for an enumeration variable of
293 * protected / unprotected.
295 * @return 0 if no error \n
296 * FRSH_ERR_BAD_ARGUMENT : if obj_handle or mutex are NULL or obj_handle
297 * is not correct or reference a wrong shared object \n
298 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
299 * scheduled under the FRSH \n
300 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
302 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
303 * has been cancelled or it is not valid
306 int frsh_sharedobj_get_obj_kind
307 (frsh_sharedobj_handle_t obj_handle,
308 frsh_sharedobj_kind_t *obj_kind);
311 * frsh_sharedobj_remove()
313 * Allows the implementation to remove a shared object when the last
314 * vres referencing it is cancelled. This removes the object id and
315 * other internal data associated with the object, but does not remove
316 * the mutex; this is done by the application through the common POSIX
319 * @return 0 if no error \n
320 * FRSH_ERR_BAD_ARGUMENT : if obj_handle is NULL or obj_handle
321 * is not correct or references a wrong shared object \n
322 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
323 * scheduled under the FRSH \n
324 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
326 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
327 * has been cancelled or it is not valid
330 int frsh_sharedobj_remove
331 (frsh_sharedobj_handle_t obj_handle);
337 /////////////////////////////////////////////////////
339 /////////////////////////////////////////////////////
341 * @defgroup so_critical Critical Sections
344 * These functions are used to create and manage the parameters
345 * of critical sections. Critical sections are operations that
346 * make use of a shared object in a mutually exclusive way.
354 * Initialize the critical section pointed to by csect
355 * with a handle to its shared object, and the worst-case execution
358 * The operation_kind is set to FRSH_CSOK_UNCHECKED.
360 * @param[in] obj_handle Shared object previously initialised.
362 * @param[in] wcet Execution time of the critical section. This
363 * budget is consumed in parallel with the vres budget.
365 * @param[out] csect Critical section memory placeholder.
367 * @return 0 if no error \n
368 * FRSH_ERR_BAD_ARGUMENT : if obj_handle is NULL \b or \n
369 * obj_handle is not correct or references a wrong shared object \b or \n
370 * if wcet is in the wrong format for specifying a time interval value \n
371 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
372 * scheduled under the FRSH \n
373 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
375 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
376 * has been cancelled or it is not valid
380 (frsh_sharedobj_handle_t obj_handle,
381 frsh_rel_time_t wcet,
382 frsh_csect_t *csect);
386 * frsh_csect_get_sharedobj_handle()
388 * Get in the variable pointed to by obj_handle the handle to the
389 * shared object stored in the critical section referenced by csect
391 * @return 0 if no error \n
392 * FRSH_ERR_BAD_ARGUMENT : if csect or obj_handle are NULL or csect
394 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
395 * scheduled under the FRSH \n
396 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
398 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
399 * has been cancelled or it is not valid
402 int frsh_csect_get_sharedobj_handle
403 (const frsh_csect_t *csect,
404 frsh_sharedobj_handle_t * obj_handle);
407 * frsh_csect_get_wcet()
409 * Get in the variable pointed to by wcet the worst-case execution time
410 * of the operation stored in the critical section referenced by csect.
412 * @return 0 if no error \n
413 * FRSH_ERR_BAD_ARGUMENT : if csect or wcet are NULL or csect
415 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
416 * scheduled under FRSH \n
417 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
419 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
420 * has been cancelled or it is not valid
423 int frsh_csect_get_wcet
424 (const frsh_csect_t *csect,
425 frsh_rel_time_t *wcet);
429 * frsh_csect_register_read_op()
431 * Register the given operation with the critical section and set
432 * op_kind to FRSH_CSOK_READ.
434 * The function returns an error if the shared_object is unprotected.
436 * @return 0 if no error \n
437 * FRSH_ERR_BAD_ARGUMENT : if csect or op are NULL or if csect points
438 * to a wrong critical section or if the shared_object is of type
440 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
441 * scheduled under FRSH \n
442 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
444 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
445 * has been cancelled or it is not valid
448 int frsh_csect_register_read_op
449 (frsh_csect_t *csect,
453 * frsh_csect_register_write_op()
455 * Register the given operation with the critical section, register
456 * the memory areas and set op_kind to FRSH_CSOK_WRITE.
458 * If the memory areas are empty the functions returns an error.
460 * The function returns an error if the shared_object is unprotected.
462 * @return 0 if no error \n
463 * FRSH_ERR_BAD_ARGUMENT : if op, csect or areas are NULL or csect points
464 * to a wrong critical section, or areas has a wrong size, or if the
465 * shared_object of csect is of type unprotected.
466 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
467 * scheduled under the FRSH \n
468 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
470 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
471 * has been cancelled or it is not valid
474 int frsh_csect_register_write_op
475 (frsh_csect_t *csect,
477 const frsh_memory_areas_t *areas);
481 * frsh_csect_get_op_kind()
483 * Returns the type of operation (read/write/unchecked) of the critical section.
485 * @return 0 if no error \n
486 * FRSH_ERR_BAD_ARGUMENT : if csect or op_kind are NULL or csect
488 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
489 * scheduled under FRSH \n
490 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
492 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
493 * has been cancelled or it is not valid
496 int frsh_csect_get_op_kind
497 (const frsh_csect_t *csect,
498 frsh_csect_op_kind_t *op_kind);
502 * frsh_csect_get_read_op()
504 * Get into the variable pointed to by op the operation pointer stored
505 * in the critical section referenced by csect.
507 * If the csect is of type write or unchecked it returns an error.
509 * @return 0 if no error \n
510 * FRSH_ERR_BAD_ARGUMENT : if csect is NULL or points to a wrong
511 * critical section, or to a critical section that is not of the
512 * FRSH_CSOK_READ kind \n
513 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
514 * scheduled under FRSH \n
515 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
517 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
518 * has been cancelled or it is not valid
521 int frsh_csect_get_read_op
522 (const frsh_csect_t *csect,
523 frsh_csect_op_t *op);
528 * frsh_csect_get_write_op()
530 * Get the operation pointer and the memory areas stored in the csect.
532 * If the csect is of type read or unchecked.
534 * @return 0 if no error \n
535 * FRSH_ERR_BAD_ARGUMENT : if csect is NULL or points to a wrong
536 * critical section, or to a critical section that is not of the
537 * FRSH_CSOK_WRITE kind \n
538 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
539 * scheduled under FRSH \n
540 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
542 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
543 * has been cancelled or it is not valid \n
546 int frsh_csect_get_write_op
547 (const frsh_csect_t *csect,
549 frsh_memory_areas_t *areas);
553 * frsh_csect_invoke()
555 * Invoke the registered operation in the critical section, with the pointers
556 * to the input and output parameters specified by input_arg and
559 * If the section is of type FRSH_CSOK_UNCHECKED, the function returns
562 * For read operations, the mutex is locked, the csect budget is set equal
563 * to the wcet, the registered read operation is invoked, and then the
564 * mutex is unlocked; if the csect budget expires, the operation is
565 * interrupted, the mutex is unlocked, and the function returns with
568 * For write operations, the mutex is locked, the registered memory
569 * areas are backed up, the csect budget is set equal to the wcet, the
570 * registered write operation is called, and the mutex is unlocked. If
571 * the csect budget expires, the operation is interrupted, the backed-up
572 * memory areas are recovered, the mutex is unlocked, and the function
573 * returns with an error code. The blocking time suffered by higher
574 * priority tasks is at most the wcet of the operation plus the backup
575 * time plus the recovery time.
577 * If the shared object in the critical section is not protected it
580 * @return 0 if no error \n
581 * FRSH_ERR_BAD_ARGUMENT : if csect is NULL or points to a wrong
582 * critical section, or to a critical section that is unprotected \n
583 * FRSH_ERR_BUDGET_EXPIRED : the csect budget expired and the protected
584 * operation was interrupted \n
585 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
586 * scheduled under FRSH \n
587 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
589 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
590 * has been cancelled or it is not valid
593 int frsh_csect_invoke
594 (const frsh_csect_t *csect,
595 const void * input_arg,
599 * frsh_csect_get_blocking_time()
601 * Get in the variable pointed to by blocking the maximum blocking
602 * time of the operation of the referenced protected critical section.
604 * For read or unchecked operations, the maximum blocking time is the wcet.
606 * For write operations, the maximum blocking time suffered by higher
607 * priority tasks is the wcet of the operation plus the backup time
608 * plus the recovery time.
610 * @return 0 if no error \n
611 * FRSH_ERR_BAD_ARGUMENT : if csect or blocking are NULL or if csect
612 * points to a wrong critical section, or to a critical section
613 * that is unprotected \n
614 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
615 * scheduled under FRSH \n
616 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
618 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
619 * has been cancelled or it is not valid
622 int frsh_csect_get_blocking_time
623 (const frsh_csect_t *csect,
624 frsh_rel_time_t *blocking);
628 * frsh_csect_destroy()
630 * Destroy a critical section, deallocating all the resources that may
631 * have been allocated to it.
633 int frsh_csect_destroy
634 (frsh_csect_t *csect);
637 * frsh_csect_register_thread()
639 * Register the calling thread for invoking time-protected critical
640 * sections via frsh_csect_invoke.
642 int frsh_csect_register_thread();
645 * frsh_csect_deregister_thread()
647 * Deregister the calling thread from being able to invoke
648 * time-protected critical sections. This operation releases system
649 * resources that may have been allocated for the thread.
651 int frsh_csect_deregister_thread();
655 /*@}*/ /* For so_critical group */
658 /////////////////////////////////////////////////////
659 // CONTRACT PARAMETERS
660 /////////////////////////////////////////////////////
662 * @defgroup so_contract Shared Objects & Contract Parameters
665 * These functions are used to link shared objects to contracts via
673 * frsh_contract_set_csects()
675 * The operation updates the specified contract parameters object by
676 * setting its critical sections to the specified input parameter.
678 * @return 0 if no error \n
679 * FRSH_ERR_BAD_ARGUMENT : if any of the pointers is NULL or
680 * the size of the critical_sections structure is less than zero
681 * or greater than FRSH_MAX_N_CRITICAL_SECTIONS
684 int frsh_contract_set_csects
685 (frsh_contract_t *contract,
686 const frsh_csects_group_t *critical_sections);
689 * frsh_contract_get_csects()
691 * The operation obtains from the specified contract parameters object
692 * its critical sections, and copies them to the places pointed to by
693 * the specified input parameter. Only those critical_section_data
694 * records that are in use in the critical_sections structure are
695 * copied (according to its size field).
697 * @return 0 if no error \n
698 * FRSH_ERR_BAD_ARGUMENT : if any of the pointers is NULL
701 int frsh_contract_get_csects
702 (const frsh_contract_t *contract,
703 frsh_csects_group_t *critical_sections);
705 /*@}*/ /* For so_contract group */
707 /*@}*/ /* For shared_objects group */
711 #endif // _FRSH_SHARED_OBJECTS_H_