From: telleriam Date: Tue, 29 May 2007 19:29:04 +0000 (+0000) Subject: Including FOSA for MarTE-OS X-Git-Url: https://rtime.felk.cvut.cz/gitweb/frescor/fosa.git/commitdiff_plain/6dafea7f61de77a813c21cff9672ddd129291012 Including FOSA for MarTE-OS git-svn-id: http://www.frescor.org/private/svn/frescor/fosa/trunk@418 35b4ef3e-fd22-0410-ab77-dab3279adceb --- diff --git a/include/fosa_app_def_sched.h b/include/fosa_app_def_sched.h index 6d77a08..6ed45ff 100644 --- a/include/fosa_app_def_sched.h +++ b/include/fosa_app_def_sched.h @@ -62,6 +62,8 @@ #ifndef FOSA_APP_DEF_SCHED_H_ #define FOSA_APP_DEF_SCHED_H_ +#include "fosa_types.h" + /** * @defgroup appdefsched Application Defined Scheduling * @ingroup fosa diff --git a/include/fosa_clocks_and_timers.h b/include/fosa_clocks_and_timers.h index 346f560..5851f10 100644 --- a/include/fosa_clocks_and_timers.h +++ b/include/fosa_clocks_and_timers.h @@ -62,6 +62,9 @@ #ifndef FOSA_CLOCKS_AND_TIMERS_H_ #define FOSA_CLOCKS_AND_TIMERS_H_ +#include "fosa_types.h" +#include "fosa_configuration_parameters.h" + /** * @defgroup clocksandtimers Clocks and Timers * @ingroup fosa diff --git a/include/fosa_configuration_parameters.h b/include/fosa_configuration_parameters.h index b080482..916cbc1 100644 --- a/include/fosa_configuration_parameters.h +++ b/include/fosa_configuration_parameters.h @@ -85,4 +85,13 @@ #define FOSA_ADS_SCHEDINFO_MAX 32 +// the difference between the maximum SCHED_FIFO priority +// and the priority of the ADS scheduler thread +// value= 2 priority levels below the maximum + +#define FOSA_ADS_SCHEDULER_PRIO_DIFF 2 + +// The preemption level of the ADS scheduler thread +#define FOSA_ADS_SCHEDULER_LEVEL 0xffff + #endif // _FOSA_CONFIG_PARAM_H_ diff --git a/include/fosa_mutexes_and_condvars.h b/include/fosa_mutexes_and_condvars.h index c53e51a..e314a33 100644 --- a/include/fosa_mutexes_and_condvars.h +++ b/include/fosa_mutexes_and_condvars.h @@ -61,6 +61,9 @@ #ifndef FOSA_MUTEX_AND_CONDVARS_H_ #define FOSA_MUTEX_AND_CONDVARS_H_ + +#include "fosa_types.h" + /** * @defgroup mutexesandcondvars Mutexes and Condvars * @ingroup fosa @@ -335,7 +338,7 @@ int fosa_cond_wait(fosa_cond_t *cond, frsh_mutex_t *mutex); * then terminate the FRSH implementation and dependant applications **/ int fosa_cond_timedwait(fosa_cond_t *cond, frsh_mutex_t *mutex, - const struct timespec abstime); + const struct timespec *abstime); /*@}*/ diff --git a/include/fosa_opaque_types.h b/include/fosa_opaque_types.h index 68b48d8..055408d 100644 --- a/include/fosa_opaque_types.h +++ b/include/fosa_opaque_types.h @@ -71,6 +71,7 @@ #include #include #include +#include #ifdef RT_LINUX #include @@ -87,8 +88,7 @@ * ADS *********/ -#define FOSA_ADS_ACTIONS_T_OPAQUE int -/*should be posix_appsched_actions_t*/ +#define FOSA_ADS_ACTIONS_T_OPAQUE posix_appsched_actions_t #endif diff --git a/include/fosa_threads_and_signals.h b/include/fosa_threads_and_signals.h index b958a6a..6164bd0 100644 --- a/include/fosa_threads_and_signals.h +++ b/include/fosa_threads_and_signals.h @@ -62,6 +62,8 @@ #ifndef FOSA_THREAD_AND_SIGNALS_H_ #define FOSA_THREAD_AND_SIGNALS_H_ +#include "fosa_types.h" + /** * @defgroup threadandsignals Thread and Signals * @ingroup fosa @@ -138,7 +140,7 @@ frsh_thread_id_t fosa_thread_self(); /** * Note: no thread termination primitive is provided. The termination - * of a thread will be notifoed by the system to the FRSH scheduler + * of a thread will be notified by the system to the FRSH scheduler * through the scheduler API **/ @@ -275,7 +277,7 @@ int fosa_thread_attr_set_prio(frsh_thread_attr_t *attr, int prio); * Returns 0 **/ int fosa_thread_attr_get_prio - (const frsh_thread_attr_t *attr, size_t *prio); + (const frsh_thread_attr_t *attr, int *prio); /** * fosa_thread_set_prio() diff --git a/include/fosa_types.h b/include/fosa_types.h index 1865e33..e6b102b 100644 --- a/include/fosa_types.h +++ b/include/fosa_types.h @@ -63,7 +63,7 @@ #define _FOSA_TYPES_H_ #include "fosa_opaque_types.h" - +#include "frsh_fosa.h" /** * @addtogroup clocksandtimers * @@ -115,8 +115,9 @@ typedef FOSA_COND_T_OPAQUE fosa_cond_t; * * No comparison or assignment operators are defined for this type **/ -typedef FOSA_ADS_ACTIONS_T_OPAQUE fosa_ads_actions_t; +typedef FOSA_ADS_ACTIONS_T_OPAQUE fosa_ads_actions_t; +/* FOSA_ADS_ACTIONS_T_OPAQUE */ /** * Causes of error in the appsched_error primitive operation diff --git a/src_marte_linux/Makefile b/src_marte_linux/Makefile new file mode 100644 index 0000000..5b63bb6 --- /dev/null +++ b/src_marte_linux/Makefile @@ -0,0 +1,67 @@ + +## +## Makefile for FSF/FRSH C library +## by Miguel Telleria de Esteban +## Univ. de Cantabria +## telleriam@unican.es +## +## -------------------------------------------- + + +# Here we define FRSHPATH, IPATH, OBJOPT, LPATH, EXTRALIBS, CFLAGS, LDFLAGS + +PLATFORM = MARTE_OS + +include ../../frsh/frsh_rules.mk + +# List of files # +################# +NAME = libfosa_marte_linux.a + +SRC = fosa_clocks_and_timers.c fosa_threads_and_signals.c frsh_fosa.c fosa_mutexes_and_condvars.c \ + fosa_app_def_sched.c + +PUBLIC_H_FOSA = fosa_app_def_sched.h fosa.h fosa_opaque_types.h fosa_clocks_and_timers.h \ + fosa_configuration_parameters.h fosa_mutexes_and_condvars.h fosa_threads_and_signals.h \ + fosa_types.h + +PUBLIC_H_FRSH_FOSA = frsh_fosa.h frsh_fosa_opaque.h + +# PRIVATE_H = + +OBJS = $(SRC:.c=.o) +PUBLIC_H_LOCATIONS = $(addprefix $(FOSAPATH)/include/, $(PUBLIC_H_FOSA) ) $(addprefix $(FRSHPATH)/include, $(PUBLIC_H_FRSH_FOSA) ) + +# Library and linking rules # +############################## + +all: ../lib/$(NAME) + +../lib/$(NAME): $(OBJS) +# $@ represents the target (in this case ../lib/$(NAME) ) + $(AR) -rc $@ $(OBJS) + + +mprogram-test: test_fosa.o ../lib/$(NAME) + $(CC) -o $@ -lfosa_marte_linux $(LDFLAGS) $< + + + +# Compilation rule: For simplicity we make all sources # +# depend on all header files. # +######################################################### +%.o: %.c $(PUBLIC_H_FILE_LOCATIONS) $(PRIVATE_H) +# $< represents the first prerequisite (in this case %.c) + $(CC) $(CFLAGS) $(SRC_IPATH) -c $< + +# Clean up # +############ +clean: lib-uninstall + rm -f $(OBJS) *~ sizes.o mprogram-sizes + +lib-uninstall: + rm -f ../lib/$(NAME) + + +.PHONY: lib-uninstall clean sizes + diff --git a/src_marte_linux/fosa_app_def_sched.c b/src_marte_linux/fosa_app_def_sched.c new file mode 100644 index 0000000..fd5da82 --- /dev/null +++ b/src_marte_linux/fosa_app_def_sched.c @@ -0,0 +1,697 @@ +// ----------------------------------------------------------------------- +// Copyright (C) 2006 - 2007 FRESCOR consortium partners: +// +// Universidad de Cantabria, SPAIN +// University of York, UK +// Scuola Superiore Sant'Anna, ITALY +// Kaiserslautern University, GERMANY +// Univ. Politecnica Valencia, SPAIN +// Czech Technical University in Prague, CZECH REPUBLIC +// ENEA SWEDEN +// Thales Communication S.A. FRANCE +// Visual Tools S.A. SPAIN +// Rapita Systems Ltd UK +// Evidence ITALY +// +// See http://www.frescor.org for a link to partners' websites +// +// FRESCOR project (FP6/2005/IST/5-034026) is funded +// in part by the European Union Sixth Framework Programme +// The European Union is not liable of any use that may be +// made of this code. +// +// This file is part of the FRSH implementation +// +// FRSH is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// FRSH is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// distributed with FRSH; see file COPYING. If not, write to the +// Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +// ----------------------------------------------------------------------- +//fosa_app_def_sched.h +//============================================== +// ******** ****** ******** ********** +// **///// /** ** **////// /** /** +// ** /** ** /** /** /** +// ******* /** ** /********* /********** +// **//// /** ** ////////** /**//////** +// ** /** ** /** /** /** +// ** /** ** ******** /** /** +// // /******/ //////// // // +// +// FOSA(Frescor Operating System Adaptation layer) +//================================================ + +#include "fosa_app_def_sched.h" +#include "fosa_configuration_parameters.h" + +#include +#include +#include + +#include + +#include + +/******************************** + * Application-defined scheduling + ********************************/ + +/** + * We make the following ASSUMPTIONS: + * + * - The ADS always executes in the user memory space, so we don't + * need to manage the memory space translation. + * + * - Only one application scheduler exists, so we don't need an + * scheduler_id. + **/ + + +/** + * Data structures for the scheduler thread + **/ + +struct scheduler_thread_data { + fosa_ads_scheduler_ops_t scheduler_ops; + int other_data; + size_t scheduler_data_size; + void * scheduler_data; + void * init_args; + size_t init_args_size; +}; + +static struct scheduler_thread_data schedthreaddata; +static pthread_t scheduler_thread_id; + +/** + * Code of application-defined thread. The current version of MaRTE OS + * requires a thread to perform the scheduler actions. + * In the future it is expected that this thread will not be necessary. + **/ +void * scheduler_thread_code(void *arg) { + posix_appsched_actions_t sched_actions; + struct scheduler_thread_data *schedthreaddata= + (struct scheduler_thread_data *) arg; + + //schedthreaddata->scheduler_ops( +} + + +/** + * fosa_ads_scheduler_create() + * + * Create the application defined scheduler + * + * The application defined scheduler is created with the primitive + * operations specified in the object pointed to by scheduler_ops. + * + * The clock used to read the time immediately before the invocation + * of each primitive operation, to be reported to the scheduler via + * the current_time parameter of each primitive operation is the + * FOSA_CLOCK_REALTIME clock. + * + * The scheduler_data_size parameter is used to request that a memory + * area of this size must be created and reserved for the scheduler to + * store its state. A pointer to this area is passed to the scheduler + * operations in the sched_data parameter. + * + * Parameter init_arg points to an area that contains configuration + * information for the scheduler. The function creates a memory area + * of init_arg_size bytes and copies into it the area pointed by + * arg. A pointer to this new created area will be passed to the + * primitive operation init() in its arg parameter. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: The value of scheduler_ops was invalid + * EAGAIN: The system lacks enough resources to create the scheduler + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_ads_scheduler_create + (const fosa_ads_scheduler_ops_t * scheduler_ops, + size_t scheduler_data_size, + void * init_args, + size_t init_args_size) +{ + pthread_attr_t attr; + int err; + struct sched_param param; + + // check for NULL scheduler operations + if (scheduler_ops==NULL) { + return EINVAL; + } + + // copy arguments in scheduler data + schedthreaddata.scheduler_ops=*scheduler_ops; + schedthreaddata.scheduler_data_size=scheduler_data_size; + schedthreaddata.init_args=init_args; + schedthreaddata.init_args_size=init_args_size; + + // create scheduler memory area + schedthreaddata.scheduler_data=malloc(scheduler_data_size); + // check malloc return ... + + + // set the attributes for the scheduler thread + err=pthread_attr_init(&attr); + if (err!=0) { + return err; + } + CHK(pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED)); + CHK(pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED)); + CHK(pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED)); + CHK(pthread_attr_setschedpolicy(&attr,SCHED_FIFO)); + param.sched_priority=sched_get_priority_max(SCHED_FIFO)- + FOSA_ADS_SCHEDULER_PRIO_DIFF; + CHK(pthread_attr_setschedparam(&attr,¶m)); + CHK(pthread_attr_setappschedulerstate(&attr,PTHREAD_APPSCHEDULER)); + CHK(pthread_attr_setpreemptionlevel(&attr,FOSA_ADS_SCHEDULER_LEVEL)); + + // create the scheduler thread + return pthread_create(&scheduler_thread_id,&attr, + scheduler_thread_code, &schedthreaddata); +} + +/** + * fosa_thread_attr_set_appscheduled() + * + * Set the appscheduled attribute of a thread attributes object + * + * This function is used to set the appscheduled attribute in the + * object pointed to by attr. This attribute controls the kind of + * scheduling used for threads created with it. If true, the thread is + * scheduled by the application scheduler. If not, it is scheduled by + * the system under a fixed priority scheduler + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: The value of attr is invalid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_thread_attr_set_appscheduled + (frsh_thread_attr_t *attr, + bool appscheduled) +{ + return pthread_attr_setschedpolicy(attr,SCHED_APP); +} + +/** + * fosa_thread_attr_get_appscheduled() + * + * Get the appscheduled attribute of a thread attributes object + * + * This function is used to get the appscheduled attribute in the + * object pointed to by attr. This attribute controls the kind of + * scheduling used for threads created with it. If true, the thread is + * scheduled by the application scheduler. If not, it is scheduled by + * the system under a fixed priority scheduler. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: The value of attr is invalid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_thread_attr_get_appscheduled + (const frsh_thread_attr_t *attr, + bool *appscheduled) +{ + int policy, ret_value; + + ret_value=pthread_attr_getschedpolicy(attr,&policy); + if (ret_value==0) { + if (policy==SCHED_APP) { + *appscheduled=true; + } else { + *appscheduled=false; + } + } + return ret_value; +} + +/** + * fosa_thread_attr_set_appsched_params() + * + * Set the appsched_param attribute of a thread attributes object + * + * This function is used to set the appsched_param attribute in the + * object pointed to by attr. For those threads with appscheduled set + * to true, this attribute represents the application-specific + * scheduling parameters. If successful, the function shall set the + * size of the appsched_param attribute to the value specified by + * paramsize, and shall copy the scheduling parameters occupying + * paramsize bytes and pointed to by param into that attribute + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: The value of attr is invalid, or paramsize is less than + * zero or larger than FOSA_ADS_SCHEDPARAM_MAX + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_thread_attr_set_appsched_params + (frsh_thread_attr_t *attr, + const void *param, + size_t paramsize) +{ + return -1; +} + +/** + * fosa_thread_attr_get_appsched_params() + * + * Get the appsched_param attribute of a thread attributes object + * + * This function is used to get the appsched_param attribute from the + * object pointed to by attr. For those threads with appscheduled set + * to true, this attribute represents the application-specific + * scheduling parameters. If successful, the function shall set the + * value pointed to by paramsize to the size of the appsched_param + * attribute, and shall copy the scheduling parameters occupying + * paramsize bytes into the variable pointed to by param. This + * variable should be capable of storing a number of bytes equal to + * paramsize. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: The value of attr is invalid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_thread_attr_get_appsched_params + (const frsh_thread_attr_t *attr, + void *param, + size_t *paramsize) +{ + return -1; +} + +/** + * fosa_ads_set_appscheduled() + * + * Dynamically set the appscheduled attribute of a thread + * + * This function is used to dynamically set the appscheduled attribute + * of the thread identified by thread. This attribute controls the + * kind of scheduling used for threads created with it. If true, the + * thread is scheduled by the application scheduler. If not, it is + * scheduled by the system under a fixed priority scheduler. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: The value of thread is invalid + * + * EREJECT: the attachment of the thread to the frsh schehduler + * was rejected by the frsh scheduler possibly because of + * incorrect attributes, or because the requested minimum + * capacity cannot be guaranteed + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_ads_set_appscheduled + (frsh_thread_id_t thread, + bool appscheduled) +{ + return -1; +} + +/** + * fosa_ads_getappscheduled() + * + * Dynamically get the appscheduled attribute of a thread + * + * This function is used to dynamically get the appscheduled attribute + * of the thread identified by thread. This attribute controls the + * kind of scheduling used for threads created with it. If true, the + * thread is scheduled by the application scheduler. If not, it is + * scheduled by the system under a fixed priority scheduler + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: The value of thread is invalid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_ads_get_appscheduled + (frsh_thread_id_t thread, + bool *appscheduled) +{ + return -1; +} + + +/** + * fosa_ads_setappschedparam() + * + * Dynamically set the appsched_param attribute of a thread + * + * This function is used to dynamically set the appsched_param + * attribute of the thread identified by thread. For those threads + * with appscheduled set to true, this attribute represents the + * application-specific scheduling parameters. If successful, the + * function shall set the size of the appsched_param attribute to the + * value specified by paramsize, and shall copy the scheduling + * parameters occupying paramsize bytes and pointed to by param into + * that attribute + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: The value of thread is invalid, or paramsize is less than + * zero or larger than FOSA_ADS_SCHEDPARAM_MAX + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_ads_set_appsched_params + (frsh_thread_id_t thread, + const void *param, + size_t paramsize) +{ + return -1; +} + +/** + * fosa_ads_get_appsched_params() + * + * Dynamically get the appsched_param attribute of a thread + * + * This function is used to dynamically get the appsched_param + * attribute of the thread identified by thread. For those threads + * with appscheduled set to true, this attribute represents the + * application-specific scheduling parameters. If successful, the + * function shall set the variable pointed to by paramsize to the size + * of the appsched_param attribute, and shall copy the scheduling + * parameters occupying paramsize bytes into the variable pointed to + * by param. This variable should be capable of storing a number of + * bytes equal to paramsize. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: The value of thread is invalid, or paramsize is less than + * zero or larger than FOSA_ADS_SCHEDPARAM_MAX + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications. + **/ +int fosa_ads_get_appsched_params + (frsh_thread_id_t thread, + void *param, + size_t *paramsize) +{ + return -1; +} + + +/********************************* + * ADS actions + * + * A scheduling actions object is used to specify a series of actions + * to be performed by the system at the end of a scheduler primitive + * operation. The order of the actions added to the object shall be + * preserved. + * + *********************************/ + +/** + * fosa_adsactions_add_reject() + * + * Add a reject-thread action + * + * This function adds a thread-reject action to the object referenced + * by sched_actions, that will serve to notify that the thread + * identified by thread has not been accepted by the scheduler to be + * scheduled by it, possibly because the thread contained invalid + * application scheduling attributes, or because there are not enough + * resources for the new thread. At the end of the new_thread() + * scheduler primitive operation, the parent of the rejected thread + * waiting on a fosa_thread_create() or the rejected thread itself + * waiting on a fosa_ads_set_appscheduled() function shall complete the + * function with an error code of EREJECT. If no reject-thread action + * is added during the new_thread() scheduler primitive operation, the + * thread is accepted to be scheduled by the scheduler and the + * associated fosa_thread_create() or the fosa_ads_set_appscheduled() + * function shall be completed without error. For the function to + * succeed, it has to be called from the new_thread() primitive + * operation and for the thread that is requesting attachment to the + * scheduler. + * + * Returns 0 if successful; otherwise it returns an error code: + * ENOMEM: There is insufficient memory to add this action + * EPOLICY: The thread specified by thread is not the one requesting + * attachment to the scheduler, or the function is not being + * called from the new_thread primitive operation + * EINVAL: The value specified by sched_actions is invalid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_adsactions_add_reject( + fosa_ads_actions_t *sched_actions, + frsh_thread_id_t thread) +{ + return -1; +} + +/** + * fosa_adsactions_add_activate() + * + * Add a thread-activate action + * + * This function adds a thread-activate action to the object + * referenced by sched_actions. In case the thread had been previously + * suspended via posix_appsched_actions_addsuspend(), it will be + * activated at the end of the primitive operation. + * + * In those implementations that do not support urgency scheduling, + * the urgencu value is ignored. These implementations cannot support + * the frsh hierarchical scheduling module. + * + * In those implementations supporting urgency-scheduling, the action + * will cause the change of the urgency of the thread to the value + * specified in the urgency argument. Besides, if the thread was + * already active at the time the thread-activate action is executed, + * the change or urgency will imply a reordering of the thread in its + * priority queue, so that for threads of the same priority, those + * with more urgency will be scheduled before those of less urgency. + * + * Returns 0 if successful; otherwise it returns an error code: + * ENOMEM: There is insufficient memory to add this action + * EPOLICY: The thread specified by thread has its appscheduled + * attribute set to false, + * EINVAL: The value specified by sched_actions is invalid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_adsactions_add_activate( + fosa_ads_actions_t *sched_actions, + frsh_thread_id_t thread, + fosa_ads_urgency_t urgency) +{ + return -1; +} + +/** + * fosa_adsactions_add_suspend() + * + * Add a thread-suspend action + * + * This function adds a thread-suspend action to the object referenced + * by sched_actions, that will cause the thread identified by thread + * to be suspended waiting for a thread-activate action at the end of + * the scheduler operation. If the thread was already waiting for a + * thread-activate action the thread-suspend action has no effect. It + * is an error trying to suspend a thread that is blocked by the + * operating system. + * + * Returns 0 if successful; otherwise it returns an error code: + * ENOMEM: There is insufficient memory to add this action + * EPOLICY: The thread specified by thread has its appscheduled + * attribute set to false, + * EINVAL: The value specified by sched_actions is invalid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_adsactions_add_suspend( + fosa_ads_actions_t *sched_actions, + frsh_thread_id_t thread) +{ + return -1; +} + +/** + * fosa_adsactions_add_timeout() + * + * Add a timeout action + * + * This function adds a timeout action to the object referenced by + * sched_actions, that will cause the timeout() scheduler operation to + * be invoked if no other scheduler operation is invoked before + * timeout expires. The timeout shall expire when the clock specified by + * clock_id reaches the absolute time specified by the at_time + * argument. + * + * Returns 0 if successful; otherwise it returns an error code: + * ENOMEM: There is insufficient memory to add this action + * EPOLICY: The thread specified by thread has its appscheduled + * attribute set to false, + * EINVAL: The value specified by sched_actions is invalid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_adsactions_add_timeout( + fosa_ads_actions_t *sched_actions, + fosa_clock_id_t clock_id, + const struct timespec *at_time) +{ + return -1; +} + +/** + * fosa_adsactions_add_thread_notification() + * + * Add a timed-thread-notification action + * + * This function adds a thread-notification action associated with the + * thread specified in the thread argument that will cause the + * notification_for_thread() scheduler operation to be invoked at the + * time specified by at_time. This operation shall be invoked when the + * clock specified by clock_id reaches the absolute time specified by + * the at_time argument. In particular, a cpu-time clock may be used + * for parameter clock_id.Only one thread-notification can be active + * for each thread and clock. Calling the function shall remove the + * former thread-notification, if any, that had been programmed for + * the same thread and clock. A value of NULL for parameter at_time is + * used to cancel a previous thread-notification, if any, for the + * thread specified by thread and the clock specified by clock_id. + * + * Returns 0 if successful; otherwise it returns an error code: + * ENOMEM: There is insufficient memory to add this action + * EPOLICY: The thread specified by thread has its appscheduled + * attribute set to false, + * EINVAL: The value specified by sched_actions is invalid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_adsactions_add_thread_notification( + fosa_ads_actions_t *sched_actions, + frsh_thread_id_t thread, + fosa_clock_id_t clock_id, + const struct timespec *at_time) +{ + return -1; +} + + +/** + * fosa_ads_set_handled_signal_set() + * + * Specifiy the set of signals that will be handled by the application + * scheduler + * + * This function is used to dynamically set the set of signals that + * are handled by the application scheduler. When a signal included + * in this set is generated, the signal() primitive operation of the + * application scheduler shall be executed. When a signal in tis set + * is generated, it shall always imply the execution of the signal() + * primitive operation, regardless of whether that signal could be + * accepted by some other thread. Once the signal() primitive + * operation is executed the signal is consumed, so no signal handlers + * shall be executed and no threads using a sigwait operation shall + * return for that particular signal instance. For this function to + * succeed, it has to be called from a primitive operation of a + * scheduler. + * + * Returns 0 if successful; otherwise it returns an error code: + * EPOLICY: The function has not been called from a scheduler + * primitive operation + * EINVAL: The value specified by set is invalid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_ads_set_handled_signal_set(frsh_signal_t set[]) +{ + return -1; +} + + +/** + * fosa_ads_invoke_withdata() + * + * Explicitly invoke the scheduler, with data + * + * This function can be used by any thread in the process to invoke + * the ads scheduler or to share data with it. + * + * If successful, the function shall cause the execution of the + * primitive operation explicit_call_with_data() of the ads scheduler + * with its thread parameter equal to the thread ID of the calling + * thread, and its msg_size parameter equal to msg_size. In addition, + * if msg_size is larger than zero, the function shall make available + * to the scheduler a memory area whose contents are identical to the + * memory area pointed to by msg in the msg parameter of the + * explicit_call_with_data() primitive operation (note that copying + * the information is not needed). + * + * The function shall not return until the system has finished + * execution of the explicit_call_with_data() primitive operation. If + * the reply argument is non NULL, the memory area pointed to by the + * reply parameter of explicit_call_with_data() primitive operation is + * copied into the memory area pointed to by reply, and its size is + * copied into the variable pointed to by reply_size. The size of the + * reply information is limited to the value FOSA_ADS_SCHEDINFO_MAX. + * + * The function shall fail if the size specified by msg_size is larger + * than FOSA_ADS_SCHEDINFO_MAX. The function shall fail if primitive + * operation explicit_call_with_data() is set to NULL for the ads + * scheduler. + * + * Returns 0 if successful; otherwise it returns an error code: + * EPOLICY: The function been called from inside a scheduler + * primitive operation + * EINVAL: The value of msg_size is less than zero or larger than + * FOSA_ADS_SCHEDINFO_MAX + * EMASKED: The operation cannot be executed because the primitive + * operation explicit_call_with_data() is set to NULL + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_ads_invoke_withdata + (const void *msg, size_t msg_size, void *reply, size_t *reply_size) +{ + return -1; +} + diff --git a/src_marte_linux/fosa_clocks_and_timers.c b/src_marte_linux/fosa_clocks_and_timers.c new file mode 100644 index 0000000..2d0a210 --- /dev/null +++ b/src_marte_linux/fosa_clocks_and_timers.c @@ -0,0 +1,274 @@ +// ----------------------------------------------------------------------- +// Copyright (C) 2006 - 2007 FRESCOR consortium partners: +// +// Universidad de Cantabria, SPAIN +// University of York, UK +// Scuola Superiore Sant'Anna, ITALY +// Kaiserslautern University, GERMANY +// Univ. Politecnica Valencia, SPAIN +// Czech Technical University in Prague, CZECH REPUBLIC +// ENEA SWEDEN +// Thales Communication S.A. FRANCE +// Visual Tools S.A. SPAIN +// Rapita Systems Ltd UK +// Evidence ITALY +// +// See http://www.frescor.org for a link to partners' websites +// +// FRESCOR project (FP6/2005/IST/5-034026) is funded +// in part by the European Union Sixth Framework Programme +// The European Union is not liable of any use that may be +// made of this code. +// +// This file is part of the FRSH implementation +// +// FRSH is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// FRSH is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// distributed with FRSH; see file COPYING. If not, write to the +// Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +// ----------------------------------------------------------------------- +//fosa_clocks_and_timers.c +//============================================== +// ******** ****** ******** ********** +// **///// /** ** **////// /** /** +// ** /** ** /** /** /** +// ******* /** ** /********* /********** +// **//// /** ** ////////** /**//////** +// ** /** ** /** /** /** +// ** /** ** ******** /** /** +// // /******/ //////// // // +// +// FOSA(Frescor Operating System Adaptation layer) +//================================================ + + +#include +#include +#include +#include +#include + +static const struct timespec zero_time={0,0}; + + +/************************* + * Timing: Clocks + *************************/ + +/** + * fosa_get_time() + * + * Get the time from a clock + * + * This function sets the variable pointed to by current_time to the + * current value of the clock specified by clockid, which may be the + * FOSA_CLOCK_REALTIME constant or a value obtained with + * fosa_get_cputime_clock() + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of clockid is invalid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_clock_get_time(fosa_clock_id_t clockid, struct timespec *current_time) +{ + return clock_gettime(clockid,current_time); +} + + +/** + * fosa_get_cputime_clock() + * + * Get the identifier of a cpu-time clock + * + * This function stores in the variable pointed to by clockid the + * identifier of a cpu-time clock for the thread specified by tid. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of tid is invalid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_thread_get_cputime_clock + (frsh_thread_id_t tid, fosa_clock_id_t *clockid) +{ + return pthread_getcpuclockid(tid,clockid); +} + + +/************************* + * Timing: Timers + *************************/ + +/** + * fosa_create_timer() + * + * Create a one-shot timer + * + * This function creates a timer based on the clock specified by clock, + * and associates to this timer a notification mechanism consisting of + * a signal and associated information. Initially, the timer is in the + * disarmed state, i.e., not counting time. It can be armed to start + * counting time with fosa_timer_arm(). + * + * The function stores the identifier of the newly created timer in the + * variable pointed to by timerid. + * + * When the timer expires, the signal number specified by signal will be + * sent together with the information specified by info, to the thread + * that armed the timer (@see fosa_timer_arm()). + * + * In those implementations that do not support queueing a + * signal with information to a thread (such as POSIX), the signal may + * be sent to any thread that is waiting for this signal via + * fosa_signal_wait(). Portability can be ensured by having the receiver + * thread be the one who is waiting for the signal. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of clockid or signal is invalid + * + * EAGAIN: the system lacks enough resources to create the timer + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ + int fosa_timer_create + (fosa_clock_id_t clockid, frsh_signal_t signal, frsh_signal_info_t info, + fosa_timer_id_t *timerid) +{ + struct sigevent evp; + evp.sigev_notify=SIGEV_SIGNAL; + evp.sigev_signo=signal; + evp.sigev_value=*( (union sigval *) &info); + return timer_create(clockid,&evp,timerid); +} + +/** + * Delete a timer + * + * The function deletes the timer specified by timerid, which becomes + * unusable. If the timer was armed, it is automatically disarmed before + * deletion. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of timerid is not valid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_timer_delete(fosa_timer_id_t timerid) +{ + return timer_delete(timerid); +} + +/** + * fosa_timer_arm() + * + * Arm a timer + * + * The timer specified by timer is armed and starts counting time. + * + * If abstime is true, the value pointed to by value is the absolute + * time at which the timer will expire. If value specifies a time instant + * in the past, the timer expires immediately. + * + * If abstime is false, the value pointed to by value is the relative interval + * that must elapse for the timer to expire. + * + * In both cases, absolute or relative, the time is measured with the clock + * associated with the timer when it was created. + * + * If the timer was already armed, the previous time or interval is discarded + * and the timer is rearmed with the new value. + * + * When the timer expires, it is disarmed. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of timerid or value is invalid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_timer_arm + (fosa_timer_id_t timerid, bool abstime, + const struct timespec *value) +{ + int timer_abstime=0; + struct itimerspec timer_value; + + // set the abstime flag if necessary + if (abstime) { + timer_abstime=TIMER_ABSTIME; + } + + // set the timer to the specified value, one shot only + timer_value.it_value=*value; + timer_value.it_interval=zero_time; + + // arm the timer + return timer_settime(timerid,timer_abstime,&timer_value,NULL); +} + +/** + * fosa_timer_disarm() + * + * Disarm a timer + * + * The timer specified by timer is disarmed, and will not expire unless + * it is rearmed. If the timer was already disramed, the function has + * no effect. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of timerid or value is invalid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_timer_disarm(fosa_timer_id_t timerid, struct timespec *remaining_time) +{ + struct itimerspec timer_value; + struct itimerspec it_remaining_time; + int error = 0; + + memset(&it_remaining_time, 0, sizeof(it_remaining_time) ); + + timer_value.it_value=zero_time; + timer_value.it_interval=zero_time; + + if (remaining_time == NULL) + { + return timer_settime(timerid,0,&timer_value,NULL); + } + + /* We need to return the remaining time */ + error = timer_settime(timerid, 0, &timer_value, &it_remaining_time); + + if (error != 0) + { + return error; + } + + *remaining_time = it_remaining_time.it_value; + + return 0; + +} diff --git a/src_marte_linux/fosa_mutexes_and_condvars.c b/src_marte_linux/fosa_mutexes_and_condvars.c new file mode 100644 index 0000000..19ede0d --- /dev/null +++ b/src_marte_linux/fosa_mutexes_and_condvars.c @@ -0,0 +1,382 @@ +// ----------------------------------------------------------------------- +// Copyright (C) 2006 - 2007 FRESCOR consortium partners: +// +// Universidad de Cantabria, SPAIN +// University of York, UK +// Scuola Superiore Sant'Anna, ITALY +// Kaiserslautern University, GERMANY +// Univ. Politecnica Valencia, SPAIN +// Czech Technical University in Prague, CZECH REPUBLIC +// ENEA SWEDEN +// Thales Communication S.A. FRANCE +// Visual Tools S.A. SPAIN +// Rapita Systems Ltd UK +// Evidence ITALY +// +// See http://www.frescor.org for a link to partners' websites +// +// FRESCOR project (FP6/2005/IST/5-034026) is funded +// in part by the European Union Sixth Framework Programme +// The European Union is not liable of any use that may be +// made of this code. +// +// This file is part of the FRSH implementation +// +// FRSH is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// FRSH is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// distributed with FRSH; see file COPYING. If not, write to the +// Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +// ----------------------------------------------------------------------- +//fosa_mutexes_and_condvars.c +//============================================== +// ******** ****** ******** ********** +// **///// /** ** **////// /** /** +// ** /** ** /** /** /** +// ******* /** ** /********* /********** +// **//// /** ** ////////** /**//////** +// ** /** ** /** /** /** +// ** /** ** ******** /** /** +// // /******/ //////// // // +// +// FOSA(Frescor Operating System Adaptation layer) +//================================================ + +#include "fosa_mutexes_and_condvars.h" + +#include +#include + +#include + + + +/******************************************************* + * Mutexes with priority ceiling + ******************************************************/ + +/** + * fosa_mutex_init() + * + * Initialize a frsh mutex + * + * The mutex pointed to by mutex is initialized as a mutex using + * the priority ceiling protocol. A priority ceiling of prioceiling + * is assigned to this mutex. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of prioceiling is invalid + * EAGAIN: the system lacked the necessary resources to create the mutex + * ENOMEM: Insufficient memory exists to initialize the mutex + * EBUSY: The system has detected an attempt to reinitialize the mutex + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_mutex_init(frsh_mutex_t *mutex, int prioceiling) +{ + pthread_mutexattr_t attr; + int ret_value; + + // create the attributes object and set the mutes to use the + // priority ceiling protocol and the desired priority ceiling + CHK(pthread_mutexattr_init(&attr)); + CHK(pthread_mutexattr_setprotocol(&attr,PTHREAD_PRIO_PROTECT)); + CHK(pthread_mutexattr_setprioceiling(&attr,prioceiling)); + + // create the mutex + ret_value=pthread_mutex_init(mutex,&attr); + + // destroy the mutex attributes object + pthread_mutexattr_destroy(&attr); + + return ret_value; +} + +/** + * fosa_mutex_destroy() + * + * Destroy a frsh mutex + * + * The mutex pointed to by mutex is destroyed + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of mutex is invalid + * EBUSY: The mutex is in use (is locked) + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_mutex_destroy(frsh_mutex_t *mutex) +{ + return pthread_mutex_destroy(mutex); +} + +/** + * fosa_mutex_set_prioceiling() + * + * Dynamically set the priority ceiling of a mutex + * + * This function locks the mutex (blocking the calling thread if + * necessary) and after it is locked it changes its priority ceiling + * to the value specified by new_ceiling, and then it unlocks the + * mutex. The previous value of the ceiling is returned in + * old_ceiling. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of mutex or prioceiling is invalid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_mutex_set_prioceiling + (frsh_mutex_t *mutex, int new_ceiling, int *old_ceiling) +{ + return pthread_mutex_setprioceiling(mutex,new_ceiling,old_ceiling); +} + +/** + * fosa_mutex_get_prioceiling() + * + * Dynamically get the priority ceiling of a mutex + * + * This function copies into the variable pointed to by ceiling the + * current priority ceiling of the mutex referenced by mutex + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of mutex is invalid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_mutex_get_prioceiling(const frsh_mutex_t *mutex, int *ceiling) +{ + return pthread_mutex_getprioceiling(mutex,ceiling); +} + +/** + * fosa_mutex_lock() + * + * Lock a mutex + * + * This function locks the mutex specified by mutex. If it is already + * locked, the calling thread blocks until the mutex becomes + * available. The operation returns with the mutex in the locked + * state, with the calling thread as its owner. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of mutex is invalid, or the priority of the + * calling thread is higher than the priority ceiling of the mutex + * EDEADLK: the current thread already owns this mutex + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_mutex_lock(frsh_mutex_t *mutex) +{ + return pthread_mutex_lock(mutex); +} + +/** + * fosa_mutex_trylock() + * + * Try locking a mutex + * + * This function is identical to fosa_mutex_lock() except that if the + * mutex is already locked the call returns immediately with an error + * indication. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of mutex is invalid, or the priority of the + * calling thread is higher than the priority ceiling of the mutex + * EBUSY: the mutex was already locked + * + * Alternatively, except for EBUSY, in case of error the + * implementation is allowed to notify it to the system console and + * then terminate the FRSH implementation and dependant applications + **/ +int fosa_mutex_trylock(frsh_mutex_t *mutex) +{ + return pthread_mutex_trylock(mutex); +} + +/** + * fosa_mutex_unlock() + * + * Unlock a mutex + * + * This function must be called by the owner of the mutex referenced + * by mutex, to unlock it. If there are threads blocked on the mutex + * the mutex becomes available and the highest priority thread is + * awakened to acquire the mutex. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of mutex is invalid + * EPERM: the calling thread is not the owner of the mutex + * + * Alternatively, except for EBUSY, in case of error the + * implementation is allowed to notify it to the system console and + * then terminate the FRSH implementation and dependant applications + **/ +int fosa_mutex_unlock(frsh_mutex_t *mutex) +{ + return pthread_mutex_unlock(mutex); +} + + +/********************** + * Condition variables + *********************/ + +/** + * fosa_cond_init() + * + * Initiatize a condition variable + * + * The condition variable referenced by cond is initialized with + * the attributes required by the FOSA implementation. + * + * Returns 0 if successful; otherwise it returns an error code: + * EAGAIN: the system lacked the necessary resources to create the + * condition variable + * ENOMEM: Insufficient memory exists to initialize the condition variable + * EBUSY: The system has detected an attempt to reinitialize the + * condition variable + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_cond_init(fosa_cond_t *cond) +{ + // initialize condition variable with default attributes + return pthread_cond_init(cond,NULL); +} + +/** + * fosa_cond_destroy() + * + * Destroy a condition variable + * + * The condition variable pointed to by cond is destroyed + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of cond is invalid + * EBUSY: The condition variable is in use (a thread is waiting on it) + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_cond_destroy(fosa_cond_t *cond) +{ + return pthread_cond_destroy(cond); +} + +/** + * fosa_cond_signal() + * + * Signal a condition variable + * + * This call unblocks at least one of the threads that are waiting on + * the condition variable referenced by cond. If there are no threads + * waiting, the function has no effect + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of cond is invalid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_cond_signal(fosa_cond_t *cond) +{ + return pthread_cond_signal(cond); +} + +/** + * fosa_cond_broadcast() + * + * Broadcast a condition variable + * + * This call unblocks all of the threads that are waiting on the + * condition variable referenced by cond. If there are no threads + * waiting, the function has no effect. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of cond is invalid + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_cond_broadcast(fosa_cond_t *cond) +{ + return pthread_cond_broadcast(cond); +} + +/** + * fosa_cond_wait() + * + * Wait at a condition variable + * + * This call is used to block on the condition variable referenced by + * cond. It shall be called with the mutex referenced by mutex + * locked. The function releases the mutex and blocks the calling + * thread until the condition is signalled by some other thread and + * the calling thread is awakened. Then it locks the mutex and + * returns with the mutex locked by the calling thread. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of cond or mutex is invalid, or different + * mutexes were used for concurrent wait operations on cond, or + * the mutex was not owned by the calling thread + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_cond_wait(fosa_cond_t *cond, frsh_mutex_t *mutex) +{ + return pthread_cond_wait(cond,mutex); +} + +/** + * fosa_cond_timedwait() + * + * Wait at a condition variable, with a timeout + * + * This function is equal to fosa_cond_wait(), except that the maximum + * wait time is limited to the absolute time referenced by abstime, as + * measured by the FOSA_CLOCK_REALTIME clock. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of cond or mutex or abstime is invalid, or different + * mutexes were used for concurrent wait operations on cond, or + * the mutex was not owned by the calling thread + * ETIMEDOUT: the timeout expired + * + * Alternatively, except for ETIMEDOUT, in case of error the + * implementation is allowed to notify it to the system console and + * then terminate the FRSH implementation and dependant applications + **/ +int fosa_cond_timedwait(fosa_cond_t *cond, frsh_mutex_t *mutex, + const struct timespec *abstime) +{ + return pthread_cond_timedwait(cond,mutex,abstime); +} diff --git a/src_marte_linux/fosa_threads_and_signals.c b/src_marte_linux/fosa_threads_and_signals.c new file mode 100644 index 0000000..8476307 --- /dev/null +++ b/src_marte_linux/fosa_threads_and_signals.c @@ -0,0 +1,627 @@ +// ----------------------------------------------------------------------- +// Copyright (C) 2006 - 2007 FRESCOR consortium partners: +// +// Universidad de Cantabria, SPAIN +// University of York, UK +// Scuola Superiore Sant'Anna, ITALY +// Kaiserslautern University, GERMANY +// Univ. Politecnica Valencia, SPAIN +// Czech Technical University in Prague, CZECH REPUBLIC +// ENEA SWEDEN +// Thales Communication S.A. FRANCE +// Visual Tools S.A. SPAIN +// Rapita Systems Ltd UK +// Evidence ITALY +// +// See http://www.frescor.org for a link to partners' websites +// +// FRESCOR project (FP6/2005/IST/5-034026) is funded +// in part by the European Union Sixth Framework Programme +// The European Union is not liable of any use that may be +// made of this code. +// +// This file is part of the FRSH implementation +// +// FRSH is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// FRSH is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// distributed with FRSH; see file COPYING. If not, write to the +// Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +// ----------------------------------------------------------------------- +//fosa_threads_and_signals.c +//============================================== +// ******** ****** ******** ********** +// **///// /** ** **////// /** /** +// ** /** ** /** /** /** +// ******* /** ** /********* /********** +// **//// /** ** ////////** /**//////** +// ** /** ** /** /** /** +// ** /** ** ******** /** /** +// // /******/ //////// // // +// +// FOSA(Frescor Operating System Adaptation layer) +//================================================ + +#include "fosa_threads_and_signals.h" +#include "fosa_configuration_parameters.h" + +#include +#include +#include + +#include + +/** + * @defgroup threadandsignals Thread and Signals + * @ingroup fosa + * + * This module defines the functions that manipulate frsh_threads and + * frsh_signals inside FRSH implementation. + * + * Applications can refer to FRSH threads but they cannot create them + * directly, instead they must use frsh_thread_create*() which in turn + * use fosa_thread_create(). + * + * For signals, we assume that the OS provides a direct mapping + * for frsh_signal_t and frsh_signal_info_t in the native interface. + * + * @{ + **/ + +////////////////////////////////////////////////////////////////// +// Storage of thread-specific keys +// - key_list is an array containing the keys +// - key_in_use is an array of booleans +// - key_lock is a mutex that locks the data structure +// while creating a new key +// - keys_initialized indicates whether the key_in_use array and +// the key_lock mutex are initialized or not; it is declared +// volatile as it may be accessed concurrently +////////////////////////////////////////////////////////////////// + +static pthread_key_t key_list[FOSA_MAX_KEYS]; +static bool key_in_use[FOSA_MAX_KEYS]; +static pthread_once_t keys_initialized=PTHREAD_ONCE_INIT; +static pthread_mutex_t key_lock; + + +// Initialize the keys data structure +// This function should be called from pthread_once() to ensure +// one single initialization + +void init_keys() { + pthread_mutexattr_t attr; + int i; + + // initialize the key_in_use array and the mutex + for(i=0; i + * values. + *******************************************************************/ + +/** + * fosa_set_accepted_signals() + * + * Establish the set of signals that may be synchronously accepted + * by the calling thread + * + * The function uses the array of signal numbers specified by set, + * which must be of size equal to size + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the array contains one or more values which are not + * between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX, or size + * is less than 0 + * + * Alternatively, in case of error the implementation is allowed to + * notify it to the system console and then terminate the FRSH + * implementation and dependant applications + **/ +int fosa_set_accepted_signals(frsh_signal_t set[], int size) +{ + sigset_t signalset; + int i; + + CHKE(sigemptyset(&signalset)); + for(i=0;i +#include + +#include + +/************************* + * Thread attributes + *************************/ + +/** + * frsh_thread_attr_init() + * + * Initialize a thread attributes object + * + * This function initializes the object pointed to by attr to all + * the default values defined by FRSH + * + * @return 0 if successful; otherwise it returns \n + * FOSA_ENOMEM: insufficient memory exists to initialize the thread + * attributes object + **/ +int frsh_thread_attr_init(frsh_thread_attr_t *attr) +{ + int ret_value; + + ret_value=pthread_attr_init(attr); + if (ret_value==0) { + // set the default values + + // detachstate = detached thread (no join operation allowed) + CHK(pthread_attr_setdetachstate(attr,PTHREAD_CREATE_DETACHED)); + + // inheritsched = explicit, so that we can explicitly set the attributes + CHK(pthread_attr_setinheritsched(attr,PTHREAD_EXPLICIT_SCHED)); + + // schedpolicy = fixed priorities + CHK(pthread_attr_setschedpolicy(attr,SCHED_FIFO)); + + // detachstate = detached thread (no join operation allowed) + CHK(pthread_attr_setdetachstate(attr,PTHREAD_CREATE_DETACHED)); + + } + return ret_value; +} + +/** + * frsh_thread_attr_destroy() + * + * Destroy a thread attributes object + * + * This function is used to destroy the thread attributes object, + * pointed to by attr, and deallocate any system resources allocated for it + * + * Returns 0 + */ +int frsh_thread_attr_destroy(frsh_thread_attr_t *attr) +{ + return pthread_attr_destroy(attr); +} + +/** + * frsh_thread_attr_set_stacksize() + * + * Set the thread minimum stack size in a thread attributes object + * + * This function sets the minimum stack size of the thread attributes + * object attr to the value given by stacksize, in bytes. This + * function has no runtime effect on the stack size, except when the + * attributes object is used to create a thread, when it will be + * created with the specified minimum stack size + * + * @return 0 if successful, or the following error code: + * FOSA_EINVAL: the specified stacksize value is not supported in + * this implementation + */ +int frsh_thread_attr_set_stacksize + (frsh_thread_attr_t *attr, size_t stacksize) +{ + return pthread_attr_setstacksize(attr,stacksize); +} + +/** + * frsh_thread_attr_get_stacksize() + * + * Get the thread minimum stack size from a thread attributes object + * + * This function sets the variable pointed to by stacksize to the + * minimum stack size stored in the thread attributes object attr. + * + * @return 0 + */ +int frsh_thread_attr_get_stacksize + (const frsh_thread_attr_t *attr, size_t *stacksize) +{ + return pthread_attr_getstacksize(attr,stacksize); +} diff --git a/src_marte_linux/test_fosa.c b/src_marte_linux/test_fosa.c new file mode 100644 index 0000000..b0d076b --- /dev/null +++ b/src_marte_linux/test_fosa.c @@ -0,0 +1,299 @@ +#include "fosa_threads_and_signals.h" +#include "fosa_clocks_and_timers.h" +#include "fosa_mutexes_and_condvars.h" +#include "fosa_app_def_sched.h" +#include +#include + + +void * thread_code(void *arg) { + printf("Thread executing\n"); + sleep(1); + printf("Thread terminating\n"); + return NULL; +} + +///////////////////////////////////////////////////////////// +// Simple test program for FOSA +// +// It just checks that the different functions can be called +// and that they return appropriate values +///////////////////////////////////////////////////////////// + +int main () { + + struct timespec current_time; + int err; + void * obtained; + fosa_clock_id_t cpu_clock; + + int stsize, prio; + + frsh_thread_attr_t th_attr; + + frsh_thread_id_t tid1=fosa_thread_self(); + frsh_thread_id_t tid2=fosa_thread_self(); + + frsh_signal_t received; + frsh_signal_info_t sigvalue, value_received; + struct timespec timeout; + frsh_signal_t sig=FOSA_SIGNAL_MIN+1; + frsh_signal_t timer_sig=FOSA_SIGNAL_MIN+3; + frsh_signal_t siglist[2]; + + + frsh_signal_info_t timer_info; + fosa_timer_id_t timerid; + struct timespec timerval; + + int value=333; + int key; + frsh_thread_id_t tid=fosa_thread_self(); + + frsh_mutex_t lock; + int old; + + fosa_cond_t cond; + + frsh_thread_attr_t th1_attr; + bool is_appsched; + + + + + ////////////////////////////////// + // Test clock functions + ////////////////////////////////// + + printf("--------------------------------------------------\n"); + printf("test get_time\n"); + + + err=fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time); + printf("fosa_clock_get_time for CLOCK_REALTIME sec=%d nsec=%d err=%d\n", + current_time.tv_sec, current_time.tv_nsec,err); + + fosa_thread_get_cputime_clock(fosa_thread_self(), &cpu_clock); + err=fosa_clock_get_time(cpu_clock, ¤t_time); + printf("fosa_clock_get_time for CPU-time clock sec=%d nsec=%d err=%d\n", + current_time.tv_sec, current_time.tv_nsec,err); + + + ///////////////////////////////////////////// + // Test thread ids, attributes and creation + //////////////////////////////////////////// + + + printf("--------------------------------------------------\n"); + printf("test thread ids and thread creation\n"); + + + printf("equal thread comparison=%d\n",fosa_thread_equal(tid1,tid2)); + + + err=frsh_thread_attr_init(&th_attr); + printf("thread attributes object initialized, err=%d\n",err); + + err=frsh_thread_attr_set_stacksize(&th_attr,40000); + printf("thread attr set stack size to 40000, err=%d\n",err); + + err=frsh_thread_attr_get_stacksize(&th_attr,&stsize); + printf("thread attr get stack size=%d, err=%d\n",stsize,err); + + err=fosa_thread_attr_set_prio(&th_attr,27); + printf("thread attr set prio to 27, err=%d\n",err); + + err=fosa_thread_attr_get_prio(&th_attr,&prio); + printf("thread attr get prio=%d, err=%d\n",prio,err); + + err=fosa_thread_create (&tid2, &th_attr, thread_code, NULL); + printf("creating thread with default attributes err=%d\n",err); + + sleep(2); + + err=frsh_thread_attr_destroy(&th_attr); + printf("thread attributes object destroyed, err=%d\n",err); + + ////////////////////////////////// + // Test signals + ////////////////////////////////// + + printf("--------------------------------------------------\n"); + printf("test signals\n"); + + siglist[0]=sig; + siglist[1]=timer_sig; + + timeout.tv_sec=1; + timeout.tv_nsec=0; + + sigvalue.sival_int=55; + + err=fosa_set_accepted_signals(siglist,2); + printf("two signals in set of accepted signals, err=%d\n",err); + + err=fosa_signal_timedwait(siglist,1,&received,&value_received,&timeout); + printf("timed wait not implemented; timeoutcode=%d\n",err); + + err=fosa_signal_queue(sig, sigvalue,fosa_thread_self()); + printf("signal queued with value 55, err=%d\n",err); + + err=fosa_signal_wait(siglist,1,&received, &value_received); + printf("timeoutcode=%d signal received=%d value=%d\n", + err,received,value_received.sival_int); + + + ////////////////////////////////// + // Test timers and signals + ////////////////////////////////// + + printf("--------------------------------------------------\n"); + printf("test timers and signals\n"); + + timer_info.sival_int=88; + timerval.tv_sec=1; + timerval.tv_nsec=300000000; + + + err=fosa_timer_create + (FOSA_CLOCK_REALTIME, timer_sig, timer_info,&timerid); + printf("timer created, err=%d\n",err); + + err=fosa_timer_arm(timerid,false,&timerval); + printf("timer armed for 1.3 secs, err=%d\n",err); + + fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time); + printf("current time sec=%d nsec=%d\n", + current_time.tv_sec, current_time.tv_nsec); + printf("wait for timer to expire...\n"); + + siglist[0]=timer_sig; + err=fosa_signal_wait(siglist,1,&received, &value_received); + printf("timeoutcode=%d signal received=%d value=%d\n", + err,received,value_received.sival_int); + + fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time); + printf("current time sec=%d nsec=%d\n", + current_time.tv_sec, current_time.tv_nsec); + + fosa_timer_delete(timerid); + + + ////////////////////////////////// + // Test thread-specific data + ////////////////////////////////// + + printf("--------------------------------------------------\n"); + printf("test thread-specific data\n"); + + err=fosa_key_create(&key); + printf("key created=%d. err=%d\n",key,err); + + fosa_thread_set_specific_data (key, tid, (void *) (&value)); + printf("specific data set to 333. err=%d\n",err); + + fosa_thread_get_specific_data (key, tid, &obtained); + printf("obtained thread specific data=%d\n",*((int *)obtained)); + + + ////////////////////////////////// + // Test Priorities + ////////////////////////////////// + + printf("--------------------------------------------------\n"); + printf("test priorities\n"); + + + err=fosa_thread_set_prio(fosa_thread_self(),44); + printf("priority set to 44. err=%d\n",err); + + err=fosa_thread_get_prio(fosa_thread_self(),&prio); + printf("prio=%d. err=%d\n",prio,err); + + + ////////////////////////////////// + // Test Mutexes + ////////////////////////////////// + + printf("--------------------------------------------------\n"); + printf("test mutexes\n"); + + err=fosa_mutex_init(&lock,46); + printf("mutex initialized with ceiling 46. err=%d\n",err); + + err=fosa_mutex_set_prioceiling(&lock,47,&old); + printf("mutex priority ceiling changed to 47. old=%d. err=%d\n",old,err); + + err=fosa_mutex_get_prioceiling(&lock,&old); + printf("mutex priority ceiling is=%d. err=%d\n",old,err); + + err=fosa_mutex_lock(&lock); + printf("mutex locked. err=%d\n",err); + + err=fosa_mutex_unlock(&lock); + printf("mutex unlocked. err=%d\n",err); + + err=fosa_mutex_trylock(&lock); + printf("mutex try locked. err=%d\n",err); + + err=fosa_mutex_unlock(&lock); + printf("mutex unlocked. err=%d\n",err); + + ////////////////////////////////// + // Test Condition variables + ////////////////////////////////// + + printf("--------------------------------------------------\n"); + printf("test condition variables\n"); + + err=fosa_cond_init(&cond); + printf("condvar initialized. err=%d\n",err); + + err=fosa_cond_signal(&cond); + printf("cond signalled. err=%d\n",err); + + err=fosa_cond_broadcast(&cond); + printf("cond broadcast. err=%d\n",err); + + fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time); + printf("current time sec=%d nsec=%d\n", + current_time.tv_sec, current_time.tv_nsec); + + current_time.tv_sec=current_time.tv_sec+2; + + fosa_mutex_lock(&lock); + err=fosa_cond_timedwait(&cond,&lock,¤t_time); + fosa_mutex_unlock(&lock); + printf("cond timedwait with timeout=2 sec. err=%d\n",err); + + fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time); + printf("current time sec=%d nsec=%d\n", + current_time.tv_sec, current_time.tv_nsec); + + err=fosa_mutex_destroy(&lock); + printf("mutex destroyed. err=%d\n",err); + + err=fosa_cond_destroy(&cond); + printf("cond destroyed. err=%d\n",err); + + //////////////////////////////////////// + // Test Application-defined scheduling + /////////////////////////////////////// + + printf("--------------------------------------------------\n"); + printf("test application-defined scheduling\n"); + + err=frsh_thread_attr_init(&th1_attr); + printf("thread attributes object initialized, err=%d\n",err); + + err=fosa_thread_attr_set_appscheduled(&th_attr,true); + printf("thread attr set appsched, err=%d\n",err); + + err=fosa_thread_attr_get_appscheduled(&th_attr,&is_appsched); + printf("thread attr get appsched=%d, err=%d\n",is_appsched,err); + + + + return 0; + +}