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_adaption.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
86 * This file contains the types, definitions and function prototypes
87 * for usage of shared objects and critical sections in the FRSH
88 * Scheduling Framework.
92 * @defgroup sharedobj Shared Objects module
94 * This module includes the functions to declare and use shared
95 * objects in different critical sections.
97 * A shared object is an abstraction of a mutex giving it a name and a
98 * possible priority ceiling.
100 * A critical section associates a shared object with a wcet.
101 * One or more critical sections can be included in a contract.
103 * There are two types of shared_objects: protected and unprotected.
104 * Protected shared objects have FRSH alone managing the mutex while
105 * unprotected shared objects have the mutex residing in the
106 * application memory space.
108 * There are also two types of critical sections:
110 * - UNBOUNDED critical sections:
111 * - They are considered in FRSH only for analysis purposes. They
112 * inform FRSH about which shared objects are used in which
113 * contracts in order to compute blocking times.
114 * - These critical sections are executed directly by the
115 * application and it is the designer's responsibility to
116 * respect the specified wcet.
117 * - They can only contain unprotected shared objects because
118 * their mutex must be visible to the application.
120 * - BOUNDED cricital sections:
121 * - They provide not only analysis information but also the
122 * needed means for FRSH to enforce the wcet of the critical
123 * section in a clean way.
124 * - For a bounded critical section FRSH aborts its execution if
125 * its wcet gets exceeded. A backup-rollback mechanism of
126 * pre-declared memory areas preserves the original values of
127 * those areas in case the critical section is aborted.
128 * - The application cannot modify directly the memory areas and
129 * therefore cannot execute the critical section directly.
130 * Instead it executes it indirectly via frsh_csect_invoke()
131 * providing a callback to the critical section.
132 * - This time protection comes at a penalty of extra blocking
133 * blocking time accounted for the backup and the possible need
134 * of restoration of the modified memory areas.
137 * We allow bounded critical sections to be used with protected
138 * or unprotected shared objects although we recommend to use
139 * protected shared objects whenever possible.
141 * The reason to allow unprotected shared objects in bounded
142 * critical sections is to allow the sharing of the mutex with legacy
143 * applications that cannot be rearranged into callback functions.
144 * This is not possible with protected shared objects because shared
145 * objects don't give visibility of the mutex to the application.
148 * A FRSH shared object is an association of:
149 * - a mutex with an optional priority celing.
150 * - a name (obj_id) and
151 * - a type (protected or unprotected).
153 * A FRSH critical section is an association of:
155 * - a wcet (which is EXTRA from the allocated budget).
156 * - An operation pointer (NULL if unbounded).
157 * - An attribute operation kind (unbounded, write or read).
158 * - A list of memory areas modified by the operation (when it is
161 * This module makes use of the following constants defined in
162 * frsh_configuration_parameters.h. We list them with our proposed
165 * FRSH_MAX_N_SHARED_OBJECTS 100
166 * FRSH_MAX_N_CRITICAL_SECTIONS 20
167 * FRSH_MAX_N_MEMORY_AREAS 4
173 /////////////////////////////////////////////////////
174 // SHARED OBJECTS & OPERATIONS MANAGEMENT
175 /////////////////////////////////////////////////////
177 * @defgroup so_opp_mgmnt Shared Objects & Operations
180 * These functions are used to declare shared objects and link them
187 * frsh_sharedobj_init()
189 * Initialization of shared objects. If the object identified by
190 * obj_id does not yet exist it is created, a handle to the object is
191 * returned in the variable pointed to by obj_handle, and the
192 * specified mutex is initialized with the appropriate attributes
193 * necessary for the current implementation. If the object already
194 * exists, the function fails. The object is created according to the
195 * kind of object (protected or unprotected) specified by obj_kind
197 * @param[in] obj_id Object ID defined by the application.
199 * @param[in] obj_kind Whether it is protected or unprotected.
201 * @param[out] obj_handle Placeholder for the shared object handle.
203 * @param[out] mutex Placeholder for the mutex. (Ignored for
204 * protected shared objects).
207 * FRSH_ERR_BAD_ARGUMENT : if obj_id, obj_handle, or mutex are NULL
208 * FRSH_ERR_SHARED_OBJ_ALREADY_INITIALIZED : if the object identified
209 * by obj_id already exists
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.
214 * It may also return any of the error codes that are returned by
215 * the pthread_mutex_init(), pthread_mutexattr_init(),
216 * pthread_mutexattr_destroy(), pthread_mutexattr_setprotocol() or
217 * pthread_mutexattr_setprioceiling() POSIX function calls
220 int frsh_sharedobj_init
221 (frsh_sharedobj_id_t obj_id,
222 frsh_sharedobj_kind_t obj_kind,
223 frsh_sharedobj_handle_t *obj_handle,
224 pthread_mutex_t *mutex);
229 * frsh_sharedobj_get_handle()
231 * Getting the handle of shared objects. If the object already exists
232 * a handle to the object is returned in the variable pointed to by
233 * obj_handle. Otherwise, an error code is returned by the function.
235 * @param[in] obj_id Defined by the application at object creation
238 * @param[out] obj_handle Placeholder for the object handle.
241 * FRSH_ERR_BAD_ARGUMENT : if obj_id or obj_handle are NULL
242 * FRSH_ERR_SHARED_OBJ_NOT_INITIALIZED : if the shared object identified
243 * by obj_id does not exist
244 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
245 * scheduled under the FRSH
246 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
247 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
248 * has been cancelled or it is not valid
250 * It may also return any of the error codes that are returned by the
251 * pthread_mutex_init() POSIX function call
254 int frsh_sharedobj_get_handle
255 (frsh_sharedobj_id_t obj_id,
256 frsh_sharedobj_handle_t *obj_handle);
260 * frsh_sharedobj_get_mutex()
262 * Getting the mutex of shared objects.
264 * This function returns an error if the shared object is protected.
266 * @param[in] obj_handle Handle of the shared object
268 * @param[out] mutex Placeholder for A POINTER to a pointer of the
269 * mutex. We give the pointer to discourage the
270 * application of using a local copy of the mutex.
273 * FRSH_ERR_BAD_ARGUMENT : if obj_handle or mutex are NULL or obj_handle
274 * is not correct or reference a wrong shared object
275 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
276 * scheduled under the FRSH
277 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
278 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
279 * has been cancelled or it is not valid
282 int frsh_sharedobj_get_mutex
283 (frsh_sharedobj_handle_t obj_handle,
284 pthread_mutex_t **mutex);
287 * frsh_sharedobj_get_objkind()
289 * Get the object kind (protected/unprotected) of the object handle.
291 * @param[in] obj_handle Handle of the shared object
293 * @param[out] obj_kind Placeholder for an enumeration variable of
294 * protected / unprotected.
297 * FRSH_ERR_BAD_ARGUMENT : if obj_handle or mutex are NULL or obj_handle
298 * is not correct or reference a wrong shared object
299 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
300 * scheduled under the FRSH
301 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
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_objkind
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
320 * FRSH_ERR_BAD_ARGUMENT : if obj_handle is NULL or obj_handle
321 * is not correct or references a wrong shared object
322 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
323 * scheduled under the FRSH
324 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
325 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
326 * has been cancelled or it is not valid
329 int frsh_sharedobj_remove
330 (frsh_sharedobj_handle_t obj_handle);
336 /////////////////////////////////////////////////////
338 /////////////////////////////////////////////////////
340 * @defgroup so_critical Critical Sections
343 * These functions are used to create and manage the parameters
344 * of critical sections. Critical sections are operations that
345 * make use of a shared object in a mutually exclusive way.
353 * Initialize the critical section pointed to by csect
354 * with its kind of operation, a handle
355 * to its shared object, and the worst-case execution time.
357 * This function is common to critical sections bounded and unbounded.
359 * @param[in] obj_handle Shared object previously initialised.
361 * @param[in] wcet Execution time of the critical section. Note that
362 * normal budgets associated with contracts must NOT
365 * @param[out] cset Critical section memory placeholder.
368 * FRSH_ERR_BAD_ARGUMENT : if obj_handle is NULL or obj_handle
369 * is not correct or references a wrong shared object, or if
370 * op_kind is wrong, or if wcet is in the wrong format for
371 * specifying a time interval value, or if the shared object is
372 * unprotected and the kind of critical section is not unprotected,
373 * or if the shared object is protected and the kind of critical
374 * section is unprotected.
375 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
376 * scheduled under the FRSH
377 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
378 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
379 * has been cancelled or it is not valid
383 (frsh_sharedobj_handle_t obj_handle,
384 struct timespec wcet,
385 frsh_csect_t *csect);
389 * frsh_csect_get_sharedobj_handle()
391 * Get in the variable pointed to by obj_handle the handle to the
392 * shared object stored in the critical section referenced by csect
395 * FRSH_ERR_BAD_ARGUMENT : if cset or obj_handle are NULL or cset
397 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
398 * scheduled under the FRSH
399 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
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.
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 the FRSH
419 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
420 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
421 * has been cancelled or it is not valid
424 int frsh_csect_get_wcet
425 (const frsh_csect_t *cset,
426 struct timespec *wcet);
430 * frsh_csect_register_read_op()
432 * Set the read operation in the protected-read critical section
433 * referenced by cset.
435 * If a previously operation (read or write) was already registered
436 * the function returns an error. Operations cannot be changed, you
437 * need to destroy the csect and create a new one if you want to
438 * change the operation.
441 * FRSH_ERR_BAD_ARGUMENT : if cset is NULL or points to a wrong
442 * critical section, or to a critical section that is not of the
443 * FRSH_OP_READ kind, or to a critical section which already
444 * contains a registered operation
445 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
446 * scheduled under the FRSH
447 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
448 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
449 * has been cancelled or it is not valid
452 int frsh_csect_register_read_op
457 * frsh_csect_register_write_op()
459 * Set the write operation and the associated memory areas to be backed-up
460 * in the protected-write critical section referenced by cset
462 * If the memory areas are empty the functions returns an error.
464 * If a previously operation (read or write) was already registered
465 * the function returns an error. Operations cannot be changed, you
466 * need to destroy the csect and create a new one if you want to
467 * change the operation.
470 * FRSH_ERR_BAD_ARGUMENT : if cset or areas are NULL or cset points
471 * to a wrong critical section, or to a critical section that is
472 * not of the FRSH_OP_WRITE kind, or to a critical section which already
473 * contains a registered operation, or if area points to a wrong
474 * memory areas variable.
475 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
476 * scheduled under the FRSH
477 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
478 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
479 * has been cancelled or it is not valid
482 int frsh_csect_register_write_op
485 const frsh_memory_areas_t *areas);
489 * frsh_csect_get_op_kind()
491 * Returns the type of operation (read/write) of the critical section
492 * or FRSH_CSOT_NONE if no operation is currently defined.
494 * Get in the variable pointed to by op_kind the kind of
495 * operation (read or write) stored in the critical section referenced by csect
498 * FRSH_ERR_BAD_ARGUMENT : if cset or op_kind are NULL or cset
500 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
501 * scheduled under the FRSH
502 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
503 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
504 * has been cancelled or it is not valid
507 int frsh_csect_get_op_kind
508 (const frsh_csect_t *cset,
509 frsh_csect_op_kind_t *op_kind);
513 * frsh_csect_get_read_op()
515 * Get into the variable pointed to by op the operation pointer stored
516 * in the critical section referenced by cset.
518 * If the operation is of write type it returns an error.
520 * If the operation has not yet been registered it returns a NULL value.
523 * FRSH_ERR_BAD_ARGUMENT : if cset is NULL or points to a wrong
524 * critical section, or to a critical section that is not of the
526 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
527 * scheduled under the FRSH
528 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
529 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
530 * has been cancelled or it is not valid
533 int frsh_csect_get_read_op
534 (const frsh_csect_t *cset,
535 frsh_csect_op_t *op);
540 * frsh_csect_get_write_op()
542 * Get into the operation pointer and the memory areas associated to a
543 * write operation in a critical section.
545 * If the operation is of read type it returns an error.
548 * FRSH_ERR_BAD_ARGUMENT : if cset is NULL or points to a wrong
549 * critical section, or to a critical section that is not of the
551 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
552 * scheduled under the FRSH
553 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
554 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
555 * has been cancelled or it is not valid
558 int frsh_csect_get_write_op
559 (const frsh_csect_t *cset,
561 frsh_memory_areas_t *areas);
564 * frsh_csect_get_memory_areas()
566 * Get into the variable pointed to by areas the memory areas associated
567 * with the write operation stored in the protected-write critical section
568 * referenced by cset.
570 * If the operation is of read type it returns an error.
573 * FRSH_ERR_BAD_ARGUMENT : if cset is NULL or points to a wrong
574 * critical section, or to a critical section that is not of the
576 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
577 * scheduled under the FRSH
578 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
579 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
580 * has been cancelled or it is not valid
583 int frsh_csect_get_memory_areas
584 (const frsh_csect_t *cset,
585 frsh_memory_areas_t *areas);
588 * frsh_csect_invoke()
590 * Invoke the referenced protected critical section, with the pointers
591 * to the input and output parameters specified by input_arg and
592 * output arg, setting a budget for the operation and executing the
593 * registered operation.
595 * For read operations, the mutex is locked, the budget is set equal
596 * to the wcet, the registered read operation is invoked, and then the
597 * mutex is unlocked; if the budget expires, the operation is
598 * interrupted, the mutex is unlocked, and the function returns with
601 * For write operations, the mutex is locked, the registered memory
602 * areas are backed up, a budget is set equal to the wcet, the
603 * registered write operation is called, and the mutex is unlocked. If
604 * the budget expires, the operation is interrupted, the backed-up
605 * memory areas are recovered, the mutex is unlocked, and the function
606 * returns with an error code. The blocking time suffered by higher
607 * priority tasks is at most the wcet of the operation plus the backup
608 * time plus the recovery time.
610 * If the shared object in the critical section is not protected it
613 * If no operation has yet been registered it returns an error.
616 * FRSH_ERR_BAD_ARGUMENT : if cset is NULL or points to a wrong
617 * critical section, or to a critical section that is unprotected
618 * FRSH_ERR_BUDGET_EXPIRED : the budget expired and the protected
619 * operation was interrupted
620 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
621 * scheduled under the FRSH
622 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
623 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
624 * has been cancelled or it is not valid
627 int frsh_csect_invoke
628 (const frsh_csect_t *cset,
629 const void * input_arg,
633 * frsh_csect_get_blocking_time()
635 * Get in the variable pointed to by blocking the maximum blocking
636 * time of the operation of the referenced protected critical section.
638 * For read operations, the maximum blocking time is the wcet.
640 * For write operations, the maximum blocking time suffered by higher
641 * priority tasks is the wcet of the operation plus the backup time
642 * plus the recovery time.
645 * FRSH_ERR_BAD_ARGUMENT : if cset or blocking are NULL or if csect
646 * points to a wrong critical section, or to a critical section
647 * that is unprotected
648 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
649 * scheduled under the FRSH
650 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
651 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
652 * has been cancelled or it is not valid
655 int frsh_csect_get_blocking_time
656 (const frsh_csect_t *cset,
657 struct timespec *blocking);
660 /*@}*/ /* For so_critical group */
663 /////////////////////////////////////////////////////
664 // CONTRACT PARAMETERS
665 /////////////////////////////////////////////////////
667 * @defgroup so_contract Shared Objects & Contract Parameters
670 * These functions are used to link shared objects to contracts via
678 * frsh_contract_set_csects()
680 * The operation updates the specified contract parameters object by
681 * setting its critical sections to the specified input parameter.
684 * FRSH_ERR_BAD_ARGUMENT : if any of the pointers is NULL or
685 * the size of the critical_sections structure is less than zero
686 * or grater than FRSH_MAX_N_CRITICAL_SECTIONS
689 int frsh_contract_set_csects
690 (frsh_contract_t *contract,
691 const frsh_csects_group_t *critical_sections);
694 * frsh_contract_get_csects()
696 * The operation obtains from the specified contract parameters object
697 * its critical sections, and copies them to the places pointed to by
698 * the specified input parameter. Only those critical_section_data
699 * records that are in use in the critical_sections structure are
700 * copied (according to its size field).
703 * FRSH_ERR_BAD_ARGUMENT : if any of the pointers is NULL
706 int frsh_contract_get_csects
707 (const frsh_contract_t *contract,
708 frsh_csects_group_t *critical_sections);
710 /*@}*/ /* For so_contract group */
712 /*@}*/ /* For shared_objects group */
714 #endif // _FRSH_SHARED_OBJECTS_H_