From 9fb0709cbcefdd987093f758910a6d63e0d8d900 Mon Sep 17 00:00:00 2001 From: telleriam Date: Fri, 9 Feb 2007 09:20:55 +0000 Subject: [PATCH] New API for protected shared objects by Michael Gonzalez Harbour (MGH). git-svn-id: http://www.frescor.org/private/svn/frescor/frsh/trunk/include@290 35b4ef3e-fd22-0410-ab77-dab3279adceb --- frsh_configuration_parameters.h | 5 + frsh_error.h | 3 +- frsh_opaque_types.h | 20 ++ frsh_shared_objects.h | 337 ++++++++++++++++++++++++++++++-- frsh_shared_objects_types.h | 49 ++++- 5 files changed, 395 insertions(+), 19 deletions(-) diff --git a/frsh_configuration_parameters.h b/frsh_configuration_parameters.h index 263db92..2198e50 100644 --- a/frsh_configuration_parameters.h +++ b/frsh_configuration_parameters.h @@ -115,6 +115,11 @@ **/ #define FRSH_MAX_N_CRITICAL_SECTIONS 25 +/** + * Maximum number of memory areas that can be specified for a + * wite operation in a critical section + **/ +#define FRSH_MAX_N_MEMORY_AREAS 4 /** * Maximum number of utilization values (pairs of budget and period) diff --git a/frsh_error.h b/frsh_error.h index 870b5af..1c99706 100644 --- a/frsh_error.h +++ b/frsh_error.h @@ -114,8 +114,9 @@ #define FRSH_ERR_SYSTEM_NOT_INITIALIZED 0x0200401F #define FRSH_ERR_TOO_MANY_SHARED_OBJS 0x02004020 #define FRSH_ERR_CONTRACT_ID_ALREADY_EXISTS 0x02004021 +#define FRSH_ERR_BUDGET_EXPIRED 0x02004022 -#define FRSH_ERR_LAST_VALUE 0x02004020 +#define FRSH_ERR_LAST_VALUE 0x02004023 int frsh_strerror (int error, char *message, size_t size); diff --git a/frsh_opaque_types.h b/frsh_opaque_types.h index 2b3b6b6..ae8a595 100644 --- a/frsh_opaque_types.h +++ b/frsh_opaque_types.h @@ -180,6 +180,26 @@ #define FRSH_SHARED_OBJ_HANDLE_T_OPAQUE int +/** + * Critical section data + * - comon parameters + * op_kind; // kind of operation + * obj_handle; // handle to shared object + * wcet; // Execution time + * - attributes used only for protected shared objects + * op; // pointer to the operation + * - attributes used only for protected write operations + * areas; // memory areas to be protected + * + **/ +#define FRSH_CRITICAL_SECTION_DATA_T_OPAQUE struct { \ + frsh_shared_obj_op_kind_t op_kind; \ + frsh_shared_obj_handle_t obj_handle; \ + struct timespec wcet; \ + frsh_shared_obj_op_t op; \ + frsh_memory_areas_t areas; \ +} + //opaque types for frsh endpoints #define FRSH_SEND_ENDPOINT_T_OPAQUE int diff --git a/frsh_shared_objects.h b/frsh_shared_objects.h index d90e1b9..c53c7ad 100644 --- a/frsh_shared_objects.h +++ b/frsh_shared_objects.h @@ -100,6 +100,7 @@ * * FRSH_MAX_N_SHARED_OBJECTS 100 * FRSH_MAX_N_CRITICAL_SECTIONS 20 + * FRSH_MAX_N_MEMORY_AREAS 4 * * @{ **/ @@ -118,7 +119,6 @@ * @{ **/ - /** * frsh_init_shared_object() * @@ -127,9 +127,10 @@ * returned in the variable pointed to by obj_handle, and the * specified mutex is initialized with the appropriate attributes * necessary for the current implementation. If the object already - * exists, the function fails. + * exists, the function fails. The object is created according to the + * kind of object (protected or unprotected) specified by obj_kind * - * [@return: + * @return * FRSH_ERR_BAD_ARGUMENT : if obj_id, obj_handle, or mutex are NULL * FRSH_ERR_SHARED_OBJ_ALREADY_INITIALIZED : if the object identified * by obj_id already exists @@ -141,13 +142,14 @@ * the pthread_mutex_init(), pthread_mutexattr_init(), * pthread_mutexattr_destroy(), pthread_mutexattr_setprotocol() or * pthread_mutexattr_setprioceiling() POSIX function calls - * ] + * **/ int frsh_init_shared_object (frsh_shared_obj_id_t obj_id, frsh_shared_obj_handle_t *obj_handle, - bool protected, - pthread_mutex_t *mutex); + pthread_mutex_t *mutex, + frsh_shared_obj_kind_t obj_kind); + /** @@ -184,7 +186,7 @@ int frsh_get_shared_obj_handle * pointer to its associated mutex is returned in the variable pointed * to by mutex. Otherwise, an error code is returned by the function. * - * [@return: + * @return: * FRSH_ERR_BAD_ARGUMENT : if obj_handle or mutex are NULL or obj_handle * is not correct or reference a wrong shared object * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not @@ -192,14 +194,325 @@ int frsh_get_shared_obj_handle * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running * FRSH_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread * has been cancelled or it is not valid - * ] + * **/ int frsh_get_shared_obj_mutex (frsh_shared_obj_handle_t obj_handle, pthread_mutex_t **mutex); +/** + * frsh_remove_shared_obj() + * + * Allows the implementation to remove a shared object when the last + * server referencing it is cancelled. This removes the object id and + * other internal data associated with the object, but does not remove + * the mutex; this is done by the application through the common POSIX + * API + * + * @return: + * FRSH_ERR_BAD_ARGUMENT : if obj_handle is NULL or obj_handle + * is not correct or references a wrong shared object + * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not + * scheduled under the FRSH + * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running + * FRSH_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread + * has been cancelled or it is not valid + * + **/ +int frsh_remove_shared_obj + (frsh_shared_obj_handle_t obj_handle); + + + /*@}*/ +///////////////////////////////////////////////////// +// CRITICAL SECTIONS +///////////////////////////////////////////////////// +/** + * @defgroup so_critical Critical Sections + * @ingroup sharedobj + * + * These functions are used to create and manage the parameters + * of critical sections. Critical sections are operations that + * make use of a shared object in a mutually exclusive way. + * + * @{ + **/ + +/** + * frsh_init_csect() + * + * Initialize the critical section pointed to by csect + * with its kind of operation, a handle + * to its shared object, and the worst-case execution time + * + * @return + * FRSH_ERR_BAD_ARGUMENT : if obj_handle is NULL or obj_handle + * is not correct or references a wrong shared object, or if + * op_kind is wrong, or if wcet is in the wrong format for + * specifying a time interval value, or if the shared object is + * unprotected and the kind of critical section is not unprotected, + * or if the shared object is protected and the kind of critical + * section is unprotected. + * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not + * scheduled under the FRSH + * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running + * FRSH_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread + * has been cancelled or it is not valid + * + **/ +int frsh_init_csect + (frsh_critical_section_data_t *cset, + frsh_shared_obj_op_kind_t op_kind, + frsh_shared_obj_handle_t obj_handle, + struct timespec wcet); + +/** + * frsh_get_csect_op_kind() + * + * Get in the variable pointed to by op_kind the kind of + * operation stored in the critical section referenced by csect + * + * @return: + * FRSH_ERR_BAD_ARGUMENT : if cset or op_kind are NULL or cset + * is not correct + * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not + * scheduled under the FRSH + * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running + * FRSH_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread + * has been cancelled or it is not valid + * + **/ +int frsh_get_csect_op_kind + (const frsh_critical_section_data_t *cset, + frsh_shared_obj_op_kind_t * op_kind); + +/** + * frsh_get_csect_obj_handle() + * + * Get in the variable pointed to by obj_handle the handle to the + * shared object stored in the critical section referenced by csect + * + * @return: + * FRSH_ERR_BAD_ARGUMENT : if cset or obj_handle are NULL or cset + * is not correct + * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not + * scheduled under the FRSH + * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running + * FRSH_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread + * has been cancelled or it is not valid + * + **/ +int frsh_get_csect_obj_handle + (const frsh_critical_section_data_t *cset, + frsh_shared_obj_handle_t * obj_handle); + +/** + * frsh_get_csect_wcet() + * + * Get in the variable pointed to by wcet the worst-case execution time + * of the operation stored in the critical section referenced by csect + * + * @return: + * FRSH_ERR_BAD_ARGUMENT : if cset or wcet are NULL or cset + * is not correct + * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not + * scheduled under the FRSH + * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running + * FRSH_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread + * has been cancelled or it is not valid + * + **/ +int frsh_get_csect_wcet + (const frsh_critical_section_data_t *cset, + struct timespec *wcet); + + +/** + * frsh_register_csect_read_op() + * + * Set the read operation in the protected-read critical section + * referenced by cset + * + * @return: + * FRSH_ERR_BAD_ARGUMENT : if cset is NULL or points to a wrong + * critical section, or to a critical section that is not of the + * FRSH_OP_READ kind, or to a critical section which already + * contains a registered operation + * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not + * scheduled under the FRSH + * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running + * FRSH_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread + * has been cancelled or it is not valid + * + **/ +int frsh_register_csect_read_op + (frsh_critical_section_data_t *cset, + frsh_shared_obj_op_t op); + + +/** + * frsh_get_csect_read_op() + * + * Get into the variable pointed to by op the read operation stored in + * the protected-read critical section referenced by cset + * + * [@return: + * FRSH_ERR_BAD_ARGUMENT : if cset is NULL or points to a wrong + * critical section, or to a critical section that is not of the + * FRSH_OP_READ kind + * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not + * scheduled under the FRSH + * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running + * FRSH_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread + * has been cancelled or it is not valid + * + **/ +int frsh_get_csect_read_op + (const frsh_critical_section_data_t *cset, + frsh_shared_obj_op_t *op); + + +/** + * frsh_register_csect_write_op() + * + * Set the write operation and the associated memory areas to be backed-up + * in the protected-write critical section referenced by cset + * + * @return + * FRSH_ERR_BAD_ARGUMENT : if cset or areas are NULL or cset points + * to a wrong critical section, or to a critical section that is + * not of the FRSH_OP_WRITE kind, or to a critical section which already + * contains a registered operation, or if area points to a wrong + * memory areas variable. + * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not + * scheduled under the FRSH + * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running + * FRSH_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread + * has been cancelled or it is not valid + * + **/ +int frsh_register_csect_write_op + (frsh_critical_section_data_t *cset, + frsh_shared_obj_op_t op, + const frsh_memory_areas_t *areas); + + +/** + * frsh_get_csect_write_op() + * + * Get into the variable pointed to by op the write operation stored in + * the protected-write critical section referenced by cset + * + * @return + * FRSH_ERR_BAD_ARGUMENT : if cset is NULL or points to a wrong + * critical section, or to a critical section that is not of the + * FRSH_OP_WRITE kind + * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not + * scheduled under the FRSH + * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running + * FRSH_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread + * has been cancelled or it is not valid + * + **/ +int frsh_get_csect_write_op + (const frsh_critical_section_data_t *cset, + frsh_shared_obj_op_t *op); + +/** + * frsh_get_csect_memory_areas() + * + * Get into the variable pointed to by areas the memory areas associated + * with the write operation stored in the protected-write critical section + * referenced by cset + * + * @return: + * FRSH_ERR_BAD_ARGUMENT : if cset is NULL or points to a wrong + * critical section, or to a critical section that is not of the + * FRSH_OP_WRITE kind + * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not + * scheduled under the FRSH + * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running + * FRSH_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread + * has been cancelled or it is not valid + * + **/ +int frsh_get_csect_memory_areas + (const frsh_critical_section_data_t *cset, + frsh_memory_areas_t *areas); + +/** + * frsh_csect_invoke() + * + * Invoke the referenced protected critical section, with the pointers + * to the input and output parameters specified by input_arg and + * output arg, setting a budget for the operation and executing the + * registered operation. + * + * For read operations, the mutex is locked, the budget is set equal + * to the wcet, the registered read operation is invoked, and then the + * mutex is unlocked; if the budget expires, the operation is + * interrupted, the mutex is unlocked, and the function returns with + * an error code. + * + * For write operations, the mutex is locked, the registered memory + * areas are backed up, a budget is set equal to the wcet, the + * registered write operation is called, and the mutex is unlocked. If + * the budget expires, the operation is interrupted, the backed-up + * memory areas are recovered, the mutex is unlocked, and the function + * returns with an error code. The blocking time suffered by higher + * priority tasks is at most the wcet of the operation plus the backup + * time plus the recovery time. + * + * @return: + * FRSH_ERR_BAD_ARGUMENT : if cset is NULL or points to a wrong + * critical section, or to a critical section that is unprotected + * FRSH_ERR_BUDGET_EXPIRED : the budget expired and the protected + * operation was interrupted + * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not + * scheduled under the FRSH + * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running + * FRSH_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread + * has been cancelled or it is not valid + * + **/ +int frsh_csect_invoke + (const frsh_critical_section_data_t *cset, + const void * input_arg, + void * output_arg); + +/** + * frsh_get_csect_blocking_time() + * + * Get in the variable pointed to by blocking the maximum blocking + * time of the operation of the referenced protected critical section. + * + * For read operations, the maximum blocking time is the wcet. + * + * For write operations, the maximum blocking time suffered by higher + * priority tasks is the wcet of the operation plus the backup time + * plus the recovery time. + * + * @return: + * FRSH_ERR_BAD_ARGUMENT : if cset or blocking are NULL or if csect + * points to a wrong critical section, or to a critical section + * that is unprotected + * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not + * scheduled under the FRSH + * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running + * FRSH_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread + * has been cancelled or it is not valid + * + **/ +int frsh_csect_get_blocking_time + (const frsh_critical_section_data_t *cset, + struct timespec *blocking); + + +/*@}*/ /* For so_critical group */ + + ///////////////////////////////////////////////////// // CONTRACT PARAMETERS ///////////////////////////////////////////////////// @@ -220,11 +533,11 @@ int frsh_get_shared_obj_mutex * The operation updates the specified contract parameters object by * setting its critical sections to the specified input parameter. * - * [@return: + * @return * FRSH_ERR_BAD_ARGUMENT : if any of the pointers is NULL or * the size of the critical_sections structure is less than zero * or grater than FRSH_MAX_N_CRITICAL_SECTIONS - * ] + * **/ int frsh_set_contract_synchronization_parameters (frsh_contract_parameters_t *contract, @@ -239,9 +552,9 @@ int frsh_set_contract_synchronization_parameters * records that are in use in the critical_sections structure are * copied (according to its size field). * - * [@return: + * @return: * FRSH_ERR_BAD_ARGUMENT : if any of the pointers is NULL - * ] + * **/ int frsh_get_contract_synchronization_parameters (const frsh_contract_parameters_t *contract, diff --git a/frsh_shared_objects_types.h b/frsh_shared_objects_types.h index bfa155f..e86df42 100644 --- a/frsh_shared_objects_types.h +++ b/frsh_shared_objects_types.h @@ -94,14 +94,51 @@ typedef FRSH_SHARED_OBJ_HANDLE_T_OPAQUE frsh_shared_obj_handle_t; /** - * Critical section data: Shared object + execution time - **/ + * Kind of shared object + */ +typedef enum {FRSH_UNPROTECTED, FRSH_PROTECTED} + frsh_shared_obj_kind_t; + +/** + * Kind of protected operation + */ +typedef enum {FRSH_OP_UNPROTECTED, FRSH_OP_READ, FRSH_OP_WRITE} + frsh_shared_obj_op_kind_t; + +/** + * Pointer to protected operation, which takes a pointer to + * the input parameters, and a pointer to the output + * parameters; the user is responsible for not exceeding the + * sizes of the respective input and output parameters data structures + */ +typedef void (*frsh_shared_obj_op_t) + (const void * input_arg, void * output_arg); + +/** + * A memory area + */ typedef struct { - frsh_shared_obj_handle_t obj_handle; - struct timespec wcet; //Execution time -} frsh_critical_section_data_t; + size_t size; + void * area; +} frsh_memory_area_data_t; -/** Critical section container **/ +/** Memory areas container **/ +typedef struct { + int size; // = 0 + frsh_memory_area_data_t section[FRSH_MAX_N_MEMORY_AREAS]; +} frsh_memory_areas_t; + + +/** + * Critical section data (opaque type) + **/ +typedef FRSH_CRITICAL_SECTION_DATA_T_OPAQUE + frsh_critical_section_data_t; + + +/** + * Critical section container + **/ typedef struct { int size; // = 0 frsh_critical_section_data_t section[FRSH_MAX_N_CRITICAL_SECTIONS]; -- 2.39.2