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 // -----------------------------------------------------------------------
55 //frsh_shared_objects.h
57 //==============================================
58 // ******** ******* ******** ** **
59 // **///// /**////** **////// /** /**
60 // ** /** /** /** /** /**
61 // ******* /******* /********* /**********
62 // **//// /**///** ////////** /**//////**
63 // ** /** //** /** /** /**
64 // ** /** //** ******** /** /**
65 // // // // //////// // //
67 // FRSH(FRescor ScHeduler), pronounced "fresh"
68 //==============================================
70 #ifndef _FRSH_SHARED_OBJECTS_H_
71 #define _FRSH_SHARED_OBJECTS_H_
73 #include "frsh_shared_objects_types.h"
74 #include "frsh_core_types.h"
78 #define FRSH_SHAREDOBJS_MODULE_SUPPORTED 1
81 * @file frsh_shared_objects.h
85 * @defgroup sharedobj Shared Objects module
87 * This module includes the functions to declare and use shared
88 * objects in different critical sections.
90 * A shared object is an abstraction of a mutex giving it a name and a
91 * possible priority ceiling.
93 * A critical section represents a usage of a shared object with a wcet.
94 * One or more critical sections can be included in a contract.
96 * There are two types of shared_objects: protected and unprotected.
98 * - <b>UNPROTECTED shared objects</b>. These shared objects are always
99 * used in trusted critical sections for which the worst-case
100 * execution times can be guaranteed not to be exceeded by the
101 * application designer (eg because tools have been used to verify
102 * the schedulability off-line). Given these conditions, there is
103 * no need to have a mechanism to monitor their execution time, with
104 * the corresponding savings in overhead.
106 * - <b>PROTECTED shared objects</b>. For these shared objects a mechanism
107 * may be used in one or more of their critical sections to monitor
108 * and enforce their worst-case execution time. These shared
109 * objects are restricted to data in regular memory because a
110 * mechanism to save and restore the state is necessary in order to
111 * cleanly abort a misbehaving critical section.\n
113 * Critical sections are categorized depending on wcet monitoring and
114 * rollback capability.
116 * - <b>UNCHECKED critical sections</b>. These critical sections are
117 * not monitored by FRSH for wcet compliance. Their wcet value is
118 * used only for analysis purposes (calculation of blocking times).
120 * - <b>READ critical sections</b>. These critical sections have
121 * their wcet enforced but they don't have any rollback action
122 * applied when their wcet is exceeded.
124 * - <b>WRITE critical sections</b>. These critical sections have
125 * their wcet monitored and they have a rollback mechanism applied
126 * to their memory areas prior to being aborted for exceeding their
129 * READ and WRITE critical sections must use PROTECTED shared objects,
130 * but UNCHECKED critical sections may use PROTECTED or UNPROTECTED
133 * The monitoring mechanism for READ and WRITE critical section works
134 * by executing them indirectly via a registered callback function.
135 * UNCHECKED critical sections are executed directly by the
138 * The rollback mechanism for WRITE critical sections requires an
139 * additional registration of the memory areas that the callback
140 * function may modify. With this data FRSH will do an initial saving
141 * of this areas that will used for restoration when there is a rollback
144 * Note that extra time for the saving and the restoration must be
145 * included in the wcet specified for a WRITE critical section.
146 * Functions are provided to assist the developer in calculating this
149 * The reason for allowing the use of PROTECTED shared objects in
150 * UNCHECKED critical sections is to allow for legacy or trusted
151 * code that would use UNCHECKED critical sections to share a shared
152 * object with an untrusted code using READ or WRITE critical sections.
154 * This module makes use of the following constants defined in
155 * frsh_configuration_parameters.h. We list them with our proposed
158 * FRSH_MAX_N_SHARED_OBJECTS 100 \n
159 * FRSH_MAX_N_CRITICAL_SECTIONS 20\n
160 * FRSH_MAX_N_MEMORY_AREAS 4\n
166 /////////////////////////////////////////////////////
167 // SHARED OBJECTS & OPERATIONS MANAGEMENT
168 /////////////////////////////////////////////////////
170 * @defgroup so_opp_mgmnt Shared Objects & Operations
173 * These functions are used to declare shared objects and link them
180 * frsh_sharedobj_init()
182 * Initialization of shared objects. If the object identified by
183 * obj_label does not yet exist, it is created, a handle to the object is
184 * returned in the variable pointed to by obj_handle, and the
185 * specified mutex is initialized with the appropriate attributes
186 * necessary for the current implementation. If the object already
187 * exists, the function fails. The object is created according to the
188 * kind of object (protected or unprotected) specified by obj_kind
190 * @param[in] obj_label Label defined by the application. Char * for
191 * a string of FRSH_MAX_SIZE_SHARED_OBJ_LABEL
192 * characters (+ null terminating \0).
194 * @param[in] obj_kind Whether it is protected or unprotected.
196 * @param[out] obj_handle Placeholder for the shared object handle.
198 * @param[out] mutex Placeholder for the mutex.
200 * @return 0 if no error \n
201 * FRSH_ERR_BAD_ARGUMENT : if obj_label, obj_handle, or mutex are NULL \n
202 * FRSH_ERR_SHARED_OBJ_ALREADY_INITIALIZED : if the object identified
203 * by label already exists \n
204 * FRSH_ERR_TOO_MANY_SHARED_OBJS : if the number of already
205 * initialized shared objects exceed the
206 * FRSH_MAX_N_SHARED_OBJECTS configuration parameter. \n
208 * It may also return any of the error codes that are returned by
209 * fosa_mutex_init() and fosa_mutex_set_prioceiling().
212 int frsh_sharedobj_init
214 frsh_sharedobj_kind_t obj_kind,
215 frsh_sharedobj_handle_t *obj_handle,
216 frsh_mutex_t *mutex);
221 * frsh_sharedobj_get_handle()
223 * Getting the handle of shared objects. If the object already exists
224 * a handle to the object is returned in the variable pointed to by
225 * obj_handle. Otherwise, an error code is returned.
227 * @param[in] obj_label Defined by the application at object creation
228 * time. Char * for a string of FRSH_MAX_SIZE_SHARED_OBJ_LABEL
229 * characters (+ null terminating \0).
231 * @param[out] obj_handle Placeholder for the object handle.
233 * @return 0 if no error \n
234 * FRSH_ERR_BAD_ARGUMENT : if label or obj_handle are NULL \n
235 * FRSH_ERR_SHARED_OBJ_NOT_INITIALIZED : if the shared object identified
236 * by obj_label does not exist \n
237 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
238 * scheduled under FRSH \n
239 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
241 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
242 * has been cancelled or it is not valid \n
244 * It may also return any of the error codes that are returned by the
245 * fosa_mutex_init() function call
248 int frsh_sharedobj_get_handle
250 frsh_sharedobj_handle_t *obj_handle);
254 * frsh_sharedobj_get_mutex()
256 * Getting the mutex of shared objects.
258 * @param[in] obj_handle Handle of the shared object
260 * @param[out] mutex Placeholder for A POINTER to a pointer of the
261 * mutex. We give the pointer to discourage the
262 * application of using a local copy of the mutex.
264 * @return 0 if no error \n
265 * FRSH_ERR_BAD_ARGUMENT : if obj_handle or mutex are NULL or obj_handle
266 * is not correct or reference a wrong shared object \n
267 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
268 * scheduled under the FRSH \n
269 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
271 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
272 * has been cancelled or it is not valid
275 int frsh_sharedobj_get_mutex
276 (frsh_sharedobj_handle_t obj_handle,
277 frsh_mutex_t **mutex);
280 * frsh_sharedobj_get_obj_kind()
282 * Get the object kind (protected/unprotected) of the object handle.
284 * @param[in] obj_handle Handle of the shared object
286 * @param[out] obj_kind Placeholder for an enumeration variable of
287 * protected / unprotected.
289 * @return 0 if no error \n
290 * FRSH_ERR_BAD_ARGUMENT : if obj_handle or mutex are NULL or obj_handle
291 * is not correct or reference a wrong shared object \n
292 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
293 * scheduled under the FRSH \n
294 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
296 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
297 * has been cancelled or it is not valid
300 int frsh_sharedobj_get_obj_kind
301 (frsh_sharedobj_handle_t obj_handle,
302 frsh_sharedobj_kind_t *obj_kind);
305 * frsh_sharedobj_remove()
307 * Allows the implementation to remove a shared object when the last
308 * vres referencing it is cancelled. This removes the object id and
309 * other internal data associated with the object, but does not remove
310 * the mutex; this is done by the application through the common POSIX
313 * @return 0 if no error \n
314 * FRSH_ERR_BAD_ARGUMENT : if obj_handle is NULL or obj_handle
315 * is not correct or references a wrong shared object \n
316 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
317 * scheduled under the FRSH \n
318 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
320 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
321 * has been cancelled or it is not valid
324 int frsh_sharedobj_remove
325 (frsh_sharedobj_handle_t obj_handle);
331 /////////////////////////////////////////////////////
333 /////////////////////////////////////////////////////
335 * @defgroup so_critical Critical Sections
338 * These functions are used to create and manage the parameters
339 * of critical sections. Critical sections are operations that
340 * make use of a shared object in a mutually exclusive way.
348 * Initialize the critical section pointed to by csect
349 * with a handle to its shared object, and the worst-case execution
352 * The operation_kind is set to FRSH_CSOK_UNCHECKED.
354 * @param[in] obj_handle Shared object previously initialised.
356 * @param[in] wcet Execution time of the critical section. This
357 * budget is consumed in parallel with the vres budget.
359 * @param[out] csect Critical section memory placeholder.
361 * @return 0 if no error \n
362 * FRSH_ERR_BAD_ARGUMENT : if obj_handle is NULL \b or \n
363 * obj_handle is not correct or references a wrong shared object \b or \n
364 * if wcet is in the wrong format for specifying a time interval value \n
365 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
366 * scheduled under the FRSH \n
367 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
369 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
370 * has been cancelled or it is not valid
374 (frsh_sharedobj_handle_t obj_handle,
375 frsh_rel_time_t wcet,
376 frsh_csect_t *csect);
380 * frsh_csect_get_sharedobj_handle()
382 * Get in the variable pointed to by obj_handle the handle to the
383 * shared object stored in the critical section referenced by csect
385 * @return 0 if no error \n
386 * FRSH_ERR_BAD_ARGUMENT : if csect or obj_handle are NULL or csect
388 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
389 * scheduled under the FRSH \n
390 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
392 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
393 * has been cancelled or it is not valid
396 int frsh_csect_get_sharedobj_handle
397 (const frsh_csect_t *csect,
398 frsh_sharedobj_handle_t * obj_handle);
401 * frsh_csect_get_wcet()
403 * Get in the variable pointed to by wcet the worst-case execution time
404 * of the operation stored in the critical section referenced by csect.
406 * @return 0 if no error \n
407 * FRSH_ERR_BAD_ARGUMENT : if csect or wcet are NULL or csect
409 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
410 * scheduled under FRSH \n
411 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
413 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
414 * has been cancelled or it is not valid
417 int frsh_csect_get_wcet
418 (const frsh_csect_t *csect,
419 frsh_rel_time_t *wcet);
423 * frsh_csect_register_read_op()
425 * Register the given operation with the critical section and set
426 * op_kind to FRSH_CSOK_READ.
428 * The function returns an error if the shared_object is unprotected.
430 * @return 0 if no error \n
431 * FRSH_ERR_BAD_ARGUMENT : if csect or op are NULL or if csect points
432 * to a wrong critical section or if the shared_object is of type
434 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
435 * scheduled under FRSH \n
436 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
438 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
439 * has been cancelled or it is not valid
442 int frsh_csect_register_read_op
443 (frsh_csect_t *csect,
447 * frsh_csect_register_write_op()
449 * Register the given operation with the critical section, register
450 * the memory areas and set op_kind to FRSH_CSOK_WRITE.
452 * If the memory areas are empty the functions returns an error.
454 * The function returns an error if the shared_object is unprotected.
456 * @return 0 if no error \n
457 * FRSH_ERR_BAD_ARGUMENT : if op, csect or areas are NULL or csect points
458 * to a wrong critical section, or areas has a wrong size, or if the
459 * shared_object of csect is of type unprotected.
460 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
461 * scheduled under the FRSH \n
462 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
464 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
465 * has been cancelled or it is not valid
468 int frsh_csect_register_write_op
469 (frsh_csect_t *csect,
471 const frsh_memory_areas_t *areas);
475 * frsh_csect_get_op_kind()
477 * Returns the type of operation (read/write/unchecked) of the critical section.
479 * @return 0 if no error \n
480 * FRSH_ERR_BAD_ARGUMENT : if csect or op_kind are NULL or csect
482 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
483 * scheduled under FRSH \n
484 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
486 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
487 * has been cancelled or it is not valid
490 int frsh_csect_get_op_kind
491 (const frsh_csect_t *csect,
492 frsh_csect_op_kind_t *op_kind);
496 * frsh_csect_get_read_op()
498 * Get into the variable pointed to by op the operation pointer stored
499 * in the critical section referenced by csect.
501 * If the csect is of type write or unchecked it returns an error.
503 * @return 0 if no error \n
504 * FRSH_ERR_BAD_ARGUMENT : if csect is NULL or points to a wrong
505 * critical section, or to a critical section that is not of the
506 * FRSH_CSOK_READ kind \n
507 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
508 * scheduled under FRSH \n
509 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
511 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
512 * has been cancelled or it is not valid
515 int frsh_csect_get_read_op
516 (const frsh_csect_t *csect,
517 frsh_csect_op_t *op);
522 * frsh_csect_get_write_op()
524 * Get the operation pointer and the memory areas stored in the csect.
526 * If the csect is of type read or unchecked.
528 * @return 0 if no error \n
529 * FRSH_ERR_BAD_ARGUMENT : if csect is NULL or points to a wrong
530 * critical section, or to a critical section that is not of the
531 * FRSH_CSOK_WRITE kind \n
532 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
533 * scheduled under FRSH \n
534 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
536 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
537 * has been cancelled or it is not valid \n
540 int frsh_csect_get_write_op
541 (const frsh_csect_t *csect,
543 frsh_memory_areas_t *areas);
547 * frsh_csect_invoke()
549 * Invoke the registered operation in the critical section, with the pointers
550 * to the input and output parameters specified by input_arg and
553 * If the section is of type FRSH_CSOK_UNCHECKED, the function returns
556 * For read operations, the mutex is locked, the csect budget is set equal
557 * to the wcet, the registered read operation is invoked, and then the
558 * mutex is unlocked; if the csect budget expires, the operation is
559 * interrupted, the mutex is unlocked, and the function returns with
562 * For write operations, the mutex is locked, the registered memory
563 * areas are backed up, the csect budget is set equal to the wcet, the
564 * registered write operation is called, and the mutex is unlocked. If
565 * the csect budget expires, the operation is interrupted, the backed-up
566 * memory areas are recovered, the mutex is unlocked, and the function
567 * returns with an error code. The blocking time suffered by higher
568 * priority tasks is at most the wcet of the operation plus the backup
569 * time plus the recovery time.
571 * If the shared object in the critical section is not protected it
574 * @return 0 if no error \n
575 * FRSH_ERR_BAD_ARGUMENT : if csect is NULL or points to a wrong
576 * critical section, or to a critical section that is unprotected \n
577 * FRSH_ERR_BUDGET_EXPIRED : the csect budget expired and the protected
578 * operation was interrupted \n
579 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
580 * scheduled under FRSH \n
581 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
583 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
584 * has been cancelled or it is not valid
587 int frsh_csect_invoke
588 (const frsh_csect_t *csect,
589 const void * input_arg,
593 * frsh_csect_get_blocking_time()
595 * Get in the variable pointed to by blocking the maximum blocking
596 * time of the operation of the referenced protected critical section.
598 * For read or unchecked operations, the maximum blocking time is the wcet.
600 * For write operations, the maximum blocking time suffered by higher
601 * priority tasks is the wcet of the operation plus the backup time
602 * plus the recovery time.
604 * @return 0 if no error \n
605 * FRSH_ERR_BAD_ARGUMENT : if csect or blocking are NULL or if csect
606 * points to a wrong critical section, or to a critical section
607 * that is unprotected \n
608 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
609 * scheduled under FRSH \n
610 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
612 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
613 * has been cancelled or it is not valid
616 int frsh_csect_get_blocking_time
617 (const frsh_csect_t *csect,
618 frsh_rel_time_t *blocking);
622 * frsh_csect_destroy()
624 * Destroy a critical section, deallocating all the resources that may
625 * have been allocated to it.
627 int frsh_csect_destroy
628 (frsh_csect_t *csect);
631 * frsh_csect_register_thread()
633 * Register the calling thread for invoking time-protected critical
634 * sections via frsh_csect_invoke.
636 int frsh_csect_register_thread();
639 * frsh_csect_deregister_thread()
641 * Deregister the calling thread from being able to invoke
642 * time-protected critical sections. This operation releases system
643 * resources that may have been allocated for the thread.
645 int frsh_csect_deregister_thread();
649 /*@}*/ /* For so_critical group */
652 /////////////////////////////////////////////////////
653 // CONTRACT PARAMETERS
654 /////////////////////////////////////////////////////
656 * @defgroup so_contract Shared Objects & Contract Parameters
659 * These functions are used to link shared objects to contracts via
667 * frsh_contract_set_csects()
669 * The operation updates the specified contract parameters object by
670 * setting its critical sections to the specified input parameter.
672 * @return 0 if no error \n
673 * FRSH_ERR_BAD_ARGUMENT : if any of the pointers is NULL or
674 * the size of the critical_sections structure is less than zero
675 * or greater than FRSH_MAX_N_CRITICAL_SECTIONS
678 int frsh_contract_set_csects
679 (frsh_contract_t *contract,
680 const frsh_csects_group_t *critical_sections);
683 * frsh_contract_get_csects()
685 * The operation obtains from the specified contract parameters object
686 * its critical sections, and copies them to the places pointed to by
687 * the specified input parameter. Only those critical_section_data
688 * records that are in use in the critical_sections structure are
689 * copied (according to its size field).
691 * @return 0 if no error \n
692 * FRSH_ERR_BAD_ARGUMENT : if any of the pointers is NULL
695 int frsh_contract_get_csects
696 (const frsh_contract_t *contract,
697 frsh_csects_group_t *critical_sections);
699 /*@}*/ /* For so_contract group */
701 /*@}*/ /* For shared_objects group */
705 #endif // _FRSH_SHARED_OBJECTS_H_