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_fosa.h"
77 #include "frsh_shared_objects_types.h"
78 #include "frsh_core_types.h"
81 #define FRSH_SHAREDOBJS_MODULE_SUPPORTED 1
84 * @file frsh_shared_objects.h
88 * @defgroup sharedobj Shared Objects module
90 * This module includes the functions to declare and use shared
91 * objects in different critical sections.
93 * A shared object is an abstraction of a mutex giving it a name and a
94 * possible priority ceiling.
96 * A critical section associates a shared object with a wcet.
97 * One or more critical sections can be included in a contract.
99 * There are two types of shared_objects: protected and unprotected.
100 * Protected shared objects have FRSH alone managing the mutex while
101 * unprotected shared objects have the mutex residing in the
102 * application memory space.
104 * There are also two types of critical sections:
106 * - UNBOUNDED critical sections:
107 * - They are considered in FRSH only for analysis purposes. They
108 * inform FRSH about which shared objects are used in which
109 * contracts in order to compute blocking times.
110 * - These critical sections are executed directly by the
111 * application and it is the designer's responsibility to
112 * respect the specified wcet.
113 * - They can only contain unprotected shared objects because
114 * their mutex must be visible to the application.
116 * - BOUNDED cricital sections:
117 * - They provide not only analysis information but also the
118 * needed means for FRSH to enforce the wcet of the critical
119 * section in a clean way.
120 * - For a bounded critical section FRSH aborts its execution if
121 * its wcet gets exceeded. A backup-rollback mechanism of
122 * pre-declared memory areas preserves the original values of
123 * those areas in case the critical section is aborted.
124 * - The application cannot modify directly the memory areas and
125 * therefore cannot execute the critical section directly.
126 * Instead it executes it indirectly via frsh_csect_invoke()
127 * providing a callback to the critical section.
128 * - This time protection comes at a penalty of extra blocking
129 * blocking time accounted for the backup and the possible need
130 * of restoration of the modified memory areas.
133 * We allow bounded critical sections to be used with protected
134 * or unprotected shared objects although we recommend to use
135 * protected shared objects whenever possible.
137 * The reason to allow unprotected shared objects in bounded
138 * critical sections is to allow the sharing of the mutex with legacy
139 * applications that cannot be rearranged into callback functions.
140 * This is not possible with protected shared objects because shared
141 * objects don't give visibility of the mutex to the application.
144 * A FRSH shared object is an association of:
145 * - a mutex with an optional priority celing.
146 * - a name (obj_id) and
147 * - a type (protected or unprotected).
149 * A FRSH critical section is an association of:
151 * - a wcet (which is EXTRA from the allocated budget).
152 * - An operation pointer (NULL if unbounded).
153 * - An attribute operation kind (unbounded, write or read).
154 * - A list of memory areas modified by the operation (when it is
157 * This module makes use of the following constants defined in
158 * frsh_configuration_parameters.h. We list them with our proposed
161 * FRSH_MAX_N_SHARED_OBJECTS 100
162 * FRSH_MAX_N_CRITICAL_SECTIONS 20
163 * FRSH_MAX_N_MEMORY_AREAS 4
169 /////////////////////////////////////////////////////
170 // SHARED OBJECTS & OPERATIONS MANAGEMENT
171 /////////////////////////////////////////////////////
173 * @defgroup so_opp_mgmnt Shared Objects & Operations
176 * These functions are used to declare shared objects and link them
183 * frsh_sharedobj_init()
185 * Initialization of shared objects. If the object identified by
186 * obj_id does not yet exist it is created, a handle to the object is
187 * returned in the variable pointed to by obj_handle, and the
188 * specified mutex is initialized with the appropriate attributes
189 * necessary for the current implementation. If the object already
190 * exists, the function fails. The object is created according to the
191 * kind of object (protected or unprotected) specified by obj_kind
193 * @param[in] obj_id Object ID defined by the application.
195 * @param[in] obj_kind Whether it is protected or unprotected.
197 * @param[out] obj_handle Placeholder for the shared object handle.
199 * @param[out] mutex Placeholder for the mutex. (Ignored for
200 * protected shared objects).
202 * @return 0 if no error \n
203 * FRSH_ERR_BAD_ARGUMENT : if obj_id, obj_handle, or mutex are NULL \n
204 * FRSH_ERR_SHARED_OBJ_ALREADY_INITIALIZED : if the object identified
205 * by obj_id 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
215 (frsh_sharedobj_id_t obj_id,
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 by the function.
229 * @param[in] obj_id Defined by the application at object creation
232 * @param[out] obj_handle Placeholder for the object handle.
234 * @return 0 if no error \n
235 * FRSH_ERR_BAD_ARGUMENT : if obj_id or obj_handle are NULL \n
236 * FRSH_ERR_SHARED_OBJ_NOT_INITIALIZED : if the shared object identified
237 * by obj_id does not exist \n
238 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
239 * scheduled under FRSH \n
240 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
242 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
243 * has been cancelled or it is not valid \n
245 * It may also return any of the error codes that are returned by the
246 * fosa_mutex_init() function call
249 int frsh_sharedobj_get_handle
250 (frsh_sharedobj_id_t obj_id,
251 frsh_sharedobj_handle_t *obj_handle);
255 * frsh_sharedobj_get_mutex()
257 * Getting the mutex of shared objects.
259 * This function returns an error if the shared object is protected.
261 * @param[in] obj_handle Handle of the shared object
263 * @param[out] mutex Placeholder for A POINTER to a pointer of the
264 * mutex. We give the pointer to discourage the
265 * application of using a local copy of the mutex.
267 * @return 0 if no error \n
268 * FRSH_ERR_BAD_ARGUMENT : if obj_handle or mutex are NULL or obj_handle
269 * is not correct or reference a wrong shared object \n
270 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
271 * scheduled under the FRSH \n
272 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
274 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
275 * has been cancelled or it is not valid
278 int frsh_sharedobj_get_mutex
279 (frsh_sharedobj_handle_t obj_handle,
280 frsh_mutex_t **mutex);
283 * frsh_sharedobj_get_objkind()
285 * Get the object kind (protected/unprotected) of the object handle.
287 * @param[in] obj_handle Handle of the shared object
289 * @param[out] obj_kind Placeholder for an enumeration variable of
290 * protected / unprotected.
292 * @return 0 if no error \n
293 * FRSH_ERR_BAD_ARGUMENT : if obj_handle or mutex are NULL or obj_handle
294 * is not correct or reference a wrong shared object \n
295 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
296 * scheduled under the FRSH \n
297 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
299 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
300 * has been cancelled or it is not valid
303 int frsh_sharedobj_get_objkind
304 (frsh_sharedobj_handle_t obj_handle,
305 frsh_sharedobj_kind_t *obj_kind);
308 * frsh_sharedobj_remove()
310 * Allows the implementation to remove a shared object when the last
311 * vres referencing it is cancelled. This removes the object id and
312 * other internal data associated with the object, but does not remove
313 * the mutex; this is done by the application through the common POSIX
316 * @return 0 if no error \n
317 * FRSH_ERR_BAD_ARGUMENT : if obj_handle is NULL or obj_handle
318 * is not correct or references a wrong shared object \n
319 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
320 * scheduled under the FRSH \n
321 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
323 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
324 * has been cancelled or it is not valid
327 int frsh_sharedobj_remove
328 (frsh_sharedobj_handle_t obj_handle);
334 /////////////////////////////////////////////////////
336 /////////////////////////////////////////////////////
338 * @defgroup so_critical Critical Sections
341 * These functions are used to create and manage the parameters
342 * of critical sections. Critical sections are operations that
343 * make use of a shared object in a mutually exclusive way.
351 * Initialize the critical section pointed to by csect
352 * with its kind of operation, a handle
353 * to its shared object, and the worst-case execution time.
355 * This function is common to critical sections bounded and unbounded.
357 * @param[in] obj_handle Shared object previously initialised.
359 * @param[in] wcet Execution time of the critical section. Note that
360 * normal budgets associated with contracts must NOT
363 * @param[out] cset Critical section memory placeholder.
365 * @return 0 if no error \n
366 * FRSH_ERR_BAD_ARGUMENT : if obj_handle is NULL or obj_handle
367 * is not correct or references a wrong shared object, or if
368 * op_kind is wrong, or if wcet is in the wrong format for
369 * specifying a time interval value, or if the shared object is
370 * unprotected and the kind of critical section is not unprotected,
371 * or if the shared object is protected and the kind of critical
372 * section is unprotected. \n
373 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
374 * scheduled under the FRSH \n
375 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
377 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
378 * has been cancelled or it is not valid
382 (frsh_sharedobj_handle_t obj_handle,
383 struct timespec wcet,
384 frsh_csect_t *csect);
388 * frsh_csect_get_sharedobj_handle()
390 * Get in the variable pointed to by obj_handle the handle to the
391 * shared object stored in the critical section referenced by csect
393 * @return 0 if no error \n
394 * FRSH_ERR_BAD_ARGUMENT : if cset or obj_handle are NULL or cset
396 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
397 * scheduled under the FRSH \n
398 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
400 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
401 * has been cancelled or it is not valid
404 int frsh_csect_get_sharedobj_handle
405 (const frsh_csect_t *cset,
406 frsh_sharedobj_handle_t * obj_handle);
409 * frsh_csect_get_wcet()
411 * Get in the variable pointed to by wcet the worst-case execution time
412 * of the operation stored in the critical section referenced by csect.
414 * @return 0 if no error \n
415 * FRSH_ERR_BAD_ARGUMENT : if cset or wcet are NULL or cset
417 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
418 * scheduled under FRSH \n
419 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
421 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
422 * has been cancelled or it is not valid
425 int frsh_csect_get_wcet
426 (const frsh_csect_t *cset,
427 struct timespec *wcet);
431 * frsh_csect_register_read_op()
433 * Set the read operation in the protected-read critical section
434 * referenced by cset.
436 * If a previously operation (read or write) was already registered
437 * the function returns an error. Operations cannot be changed, you
438 * need to destroy the csect and create a new one if you want to
439 * change the operation.
441 * @return 0 if no error \n
442 * FRSH_ERR_BAD_ARGUMENT : if cset is NULL or points to a wrong
443 * critical section, or to a critical section that is not of the
444 * FRSH_OP_READ kind, or to a critical section which already
445 * contains a registered operation \n
446 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
447 * scheduled under FRSH \n
448 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
450 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
451 * has been cancelled or it is not valid
454 int frsh_csect_register_read_op
459 * frsh_csect_register_write_op()
461 * Set the write operation and the associated memory areas to be backed-up
462 * in the protected-write critical section referenced by cset
464 * If the memory areas are empty the functions returns an error.
466 * If a previously operation (read or write) was already registered
467 * the function returns an error. Operations cannot be changed, you
468 * need to destroy the csect and create a new one if you want to
469 * change the operation.
471 * @return 0 if no error \n
472 * FRSH_ERR_BAD_ARGUMENT : if cset or areas are NULL or cset points
473 * to a wrong critical section, or to a critical section that is
474 * not of the FRSH_OP_WRITE kind, or to a critical section which already
475 * contains a registered operation, or if area points to a wrong
476 * memory areas variable \n
477 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
478 * scheduled under the FRSH \n
479 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
481 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
482 * has been cancelled or it is not valid
485 int frsh_csect_register_write_op
488 const frsh_memory_areas_t *areas);
492 * frsh_csect_get_op_kind()
494 * Returns the type of operation (read/write) of the critical section
495 * or FRSH_CSOT_NONE if no operation is currently defined.
497 * Get in the variable pointed to by op_kind the kind of
498 * operation (read or write) stored in the critical section referenced by csect
500 * @return 0 if no error \n
501 * FRSH_ERR_BAD_ARGUMENT : if cset or op_kind are NULL or cset
503 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
504 * scheduled under FRSH \n
505 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
507 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
508 * has been cancelled or it is not valid
511 int frsh_csect_get_op_kind
512 (const frsh_csect_t *cset,
513 frsh_csect_op_kind_t *op_kind);
517 * frsh_csect_get_read_op()
519 * Get into the variable pointed to by op the operation pointer stored
520 * in the critical section referenced by cset.
522 * If the operation is of write type it returns an error.
524 * If the operation has not yet been registered it returns a NULL value.
526 * @return 0 if no error \n
527 * FRSH_ERR_BAD_ARGUMENT : if cset is NULL or points to a wrong
528 * critical section, or to a critical section that is not of the
529 * FRSH_OP_READ kind \n
530 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
531 * scheduled under FRSH \n
532 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
534 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
535 * has been cancelled or it is not valid
538 int frsh_csect_get_read_op
539 (const frsh_csect_t *cset,
540 frsh_csect_op_t *op);
545 * frsh_csect_get_write_op()
547 * Get into the operation pointer and the memory areas associated to a
548 * write operation in a critical section.
550 * If the operation is of read type it returns an error.
552 * @return 0 if no error \n
553 * FRSH_ERR_BAD_ARGUMENT : if cset is NULL or points to a wrong
554 * critical section, or to a critical section that is not of the
555 * FRSH_OP_WRITE kind \n
556 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
557 * scheduled under FRSH \n
558 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
560 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
561 * has been cancelled or it is not valid \n
564 int frsh_csect_get_write_op
565 (const frsh_csect_t *cset,
567 frsh_memory_areas_t *areas);
571 * frsh_csect_invoke()
573 * Invoke the referenced protected critical section, with the pointers
574 * to the input and output parameters specified by input_arg and
575 * output arg, setting a budget for the operation and executing the
576 * registered operation.
578 * For read operations, the mutex is locked, the budget is set equal
579 * to the wcet, the registered read operation is invoked, and then the
580 * mutex is unlocked; if the budget expires, the operation is
581 * interrupted, the mutex is unlocked, and the function returns with
584 * For write operations, the mutex is locked, the registered memory
585 * areas are backed up, a budget is set equal to the wcet, the
586 * registered write operation is called, and the mutex is unlocked. If
587 * the budget expires, the operation is interrupted, the backed-up
588 * memory areas are recovered, the mutex is unlocked, and the function
589 * returns with an error code. The blocking time suffered by higher
590 * priority tasks is at most the wcet of the operation plus the backup
591 * time plus the recovery time.
593 * If the shared object in the critical section is not protected it
596 * If no operation has yet been registered it returns an error.
598 * @return 0 if no error \n
599 * FRSH_ERR_BAD_ARGUMENT : if cset is NULL or points to a wrong
600 * critical section, or to a critical section that is unprotected \n
601 * FRSH_ERR_BUDGET_EXPIRED : the budget expired and the protected
602 * operation was interrupted \n
603 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
604 * scheduled under FRSH \n
605 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
607 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
608 * has been cancelled or it is not valid
611 int frsh_csect_invoke
612 (const frsh_csect_t *cset,
613 const void * input_arg,
617 * frsh_csect_get_blocking_time()
619 * Get in the variable pointed to by blocking the maximum blocking
620 * time of the operation of the referenced protected critical section.
622 * For read operations, the maximum blocking time is the wcet.
624 * For write operations, the maximum blocking time suffered by higher
625 * priority tasks is the wcet of the operation plus the backup time
626 * plus the recovery time.
628 * @return 0 if no error \n
629 * FRSH_ERR_BAD_ARGUMENT : if cset or blocking are NULL or if csect
630 * points to a wrong critical section, or to a critical section
631 * that is unprotected \n
632 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
633 * scheduled under FRSH \n
634 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
636 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
637 * has been cancelled or it is not valid
640 int frsh_csect_get_blocking_time
641 (const frsh_csect_t *cset,
642 struct timespec *blocking);
645 /*@}*/ /* For so_critical group */
648 /////////////////////////////////////////////////////
649 // CONTRACT PARAMETERS
650 /////////////////////////////////////////////////////
652 * @defgroup so_contract Shared Objects & Contract Parameters
655 * These functions are used to link shared objects to contracts via
663 * frsh_contract_set_csects()
665 * The operation updates the specified contract parameters object by
666 * setting its critical sections to the specified input parameter.
668 * @return 0 if no error \n
669 * FRSH_ERR_BAD_ARGUMENT : if any of the pointers is NULL or
670 * the size of the critical_sections structure is less than zero
671 * or grater than FRSH_MAX_N_CRITICAL_SECTIONS
674 int frsh_contract_set_csects
675 (frsh_contract_t *contract,
676 const frsh_csects_group_t *critical_sections);
679 * frsh_contract_get_csects()
681 * The operation obtains from the specified contract parameters object
682 * its critical sections, and copies them to the places pointed to by
683 * the specified input parameter. Only those critical_section_data
684 * records that are in use in the critical_sections structure are
685 * copied (according to its size field).
687 * @return 0 if no error \n
688 * FRSH_ERR_BAD_ARGUMENT : if any of the pointers is NULL
691 int frsh_contract_get_csects
692 (const frsh_contract_t *contract,
693 frsh_csects_group_t *critical_sections);
695 /*@}*/ /* For so_contract group */
697 /*@}*/ /* For shared_objects group */
699 #endif // _FRSH_SHARED_OBJECTS_H_