]> rtime.felk.cvut.cz Git - frescor/fosa.git/commitdiff
Including FOSA for MarTE-OS
authortelleriam <telleriam@35b4ef3e-fd22-0410-ab77-dab3279adceb>
Tue, 29 May 2007 19:29:04 +0000 (19:29 +0000)
committertelleriam <telleriam@35b4ef3e-fd22-0410-ab77-dab3279adceb>
Tue, 29 May 2007 19:29:04 +0000 (19:29 +0000)
git-svn-id: http://www.frescor.org/private/svn/frescor/fosa/trunk@418 35b4ef3e-fd22-0410-ab77-dab3279adceb

14 files changed:
include/fosa_app_def_sched.h
include/fosa_clocks_and_timers.h
include/fosa_configuration_parameters.h
include/fosa_mutexes_and_condvars.h
include/fosa_opaque_types.h
include/fosa_threads_and_signals.h
include/fosa_types.h
src_marte_linux/Makefile [new file with mode: 0644]
src_marte_linux/fosa_app_def_sched.c [new file with mode: 0644]
src_marte_linux/fosa_clocks_and_timers.c [new file with mode: 0644]
src_marte_linux/fosa_mutexes_and_condvars.c [new file with mode: 0644]
src_marte_linux/fosa_threads_and_signals.c [new file with mode: 0644]
src_marte_linux/frsh_fosa.c [new file with mode: 0644]
src_marte_linux/test_fosa.c [new file with mode: 0644]

index 6d77a085afcc3c99fe3c224c169e0e1da6ab09d3..6ed45ffe8ca4fa53ac2f4e0e014832bbb128ef4f 100644 (file)
@@ -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
index 346f56070ab41f697eece5faf7e39cc956d649a0..5851f1078975e94d76bf27126ad32ac9a9930bdc 100644 (file)
@@ -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
index b0804824c701d85f014cc10f73ecfff53bfb3669..916cbc15421038727b4043ec03fe000ddc005564 100644 (file)
 #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_
index c53e51a0b783cc6bee5805d8a3a0825ed97051bc..e314a33a48fb304c9b0445a07b0befa6333944cf 100644 (file)
@@ -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);
 
 /*@}*/ 
  
index 68b48d86b8f0d754332d9a38ad5cc635035d3e8d..055408dfb7b7ff768e12b264e4cc46e6fae63420 100644 (file)
@@ -71,6 +71,7 @@
 #include <pthread.h>
 #include <signal.h>
 #include <time.h>
+#include <sched.h>
 
 #ifdef RT_LINUX
 #include <rtl_timer.h>
@@ -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
 
index b958a6af451b5c7ca2420452bdbe92176ddee5c6..6164bd0e0139cd2ecab5f35bec8978fbb2962b99 100644 (file)
@@ -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()
index 1865e333cd95b629b55a6feac07f42dca0c44c21..e6b102b2557ad018440382326cc218910d8870a1 100644 (file)
@@ -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 (file)
index 0000000..5b63bb6
--- /dev/null
@@ -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 (file)
index 0000000..fd5da82
--- /dev/null
@@ -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 <pthread.h>
+#include <stdio.h>
+#include <sched.h>
+
+#include <malloc.h>
+
+#include <misc/error_checks.h>
+
+/********************************
+ * 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,&param));
+  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 (file)
index 0000000..2d0a210
--- /dev/null
@@ -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 <fosa_clocks_and_timers.h>
+#include <pthread.h>
+#include <time.h>
+#include <stdio.h>
+#include <string.h>
+
+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 (file)
index 0000000..19ede0d
--- /dev/null
@@ -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 <pthread.h>
+#include <stdio.h>
+
+#include <misc/error_checks.h>
+
+
+
+/*******************************************************
+ * 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 (file)
index 0000000..8476307
--- /dev/null
@@ -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 <pthread.h>
+#include <stdio.h>
+#include <sched.h>
+
+#include <misc/error_checks.h>
+
+/**
+ * @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<FOSA_MAX_KEYS;i++) {
+    key_in_use[i]=false;
+  }
+  // Initialize the mutex
+  pthread_mutexattr_init(&attr);
+  // we use the priority inheritance protocol because we don't know which
+  // tasks will be using the mutex
+  pthread_mutexattr_setprotocol(&attr,PTHREAD_PRIO_INHERIT);
+  pthread_mutex_init(&key_lock,&attr);
+  pthread_mutexattr_destroy(&attr);
+}
+
+/*************************
+ * Thread identification
+ *************************/ 
+
+/**
+ * fosa_thread_equal()
+ *
+ * Compare two thread identifiers to determine if they refer to the 
+ * same thread
+ **/
+bool fosa_thread_equal(frsh_thread_id_t t1, frsh_thread_id_t t2)
+{
+  return pthread_equal(t1,t2);
+}
+
+
+/**
+ * fosa_thread_self()
+ *
+ * Return the thread id of the calling thread
+ **/
+frsh_thread_id_t fosa_thread_self()
+{
+  return pthread_self();
+}
+
+
+/*************************
+ * Thread creation and termination
+ *************************/ 
+
+/**
+ * fosa_thread_create()
+ *
+ * This function creates a new thread using the attributes specified
+ * in attr. If attr is NULL, default attributes are used. The new
+ * thread starts running immediately, executing the function specified
+ * by code, with an argument equal to arg. Upon successful return, the
+ * variable pointed to by tid will contain the identifier of the newly
+ * created thread. The set of signals that may be synchronously
+ * accepted is inherited from the parent thread.
+ *
+ * Returns 0 if successful; otherwise it returs a code error:
+ *
+ *     EAGAIN: the system lacks the necessary resources to create a
+ *             new thread or the maximum number of threads has been
+ *             reached
+ *
+ *     EINVAL: the value specified by attr is invalid (for instance,
+ *              it has not been correctly initialized)
+ *
+ *     EREJECT: the cretion of the thread was rejected by the frsh scheduler
+ *               possibly because of incorrect attributes, or because the 
+ *               requested minimum capacity cannot be guaranteed
+ *
+ **/
+ int fosa_thread_create
+    (frsh_thread_id_t *tid, const frsh_thread_attr_t *attr, 
+     frsh_thread_code_t code, void * arg)
+{
+  return pthread_create(tid,attr,code,arg);
+}
+
+
+/**
+ * Note: no thread termination primitive is provided. The termination
+ * of a thread will be notified by the system to the FRSH scheduler
+ * through the scheduler API
+ **/
+
+
+/**************************************************
+ * Thread-specific data
+ *  (extended with access from a different thread)
+ *
+ * Several data items (pointers) may be associated with each thread
+ * Each item is identified through a key, an integer value between 0
+ * and FOSA_MAX_KEYS-1. The caller is responsible of allocating and
+ * deallocating the memory area pointed to by the pointer
+ **************************************************/ 
+
+/**
+ * fosa_key_create()
+ *
+ * Create a new key for thread specific data.
+ *
+ * Prior to setting data in a key, we need ask the system to create
+ * one for us.
+ *
+ * @return 0 if successful \n
+ *   FOSA_EINVAL If we already have reached the FOSA_MAX_KEYS limit.
+ *   FOSA_ENOMEM If there are no enough memory resources to 
+ *               create the key.
+ **/
+int fosa_key_create(int *key)
+{
+  int i,ret_value;
+  bool found=false;
+
+  // initialize the keys data structure if needed
+  CHK(pthread_once(&keys_initialized, init_keys));
+
+  // lock the mutex
+  CHK(pthread_mutex_lock(&key_lock));
+
+  // find an unused key
+  for(i=0; i<FOSA_MAX_KEYS;i++) {
+    if (!key_in_use[i]) {
+      *key=i;
+      key_in_use[i]=true;
+      ret_value=pthread_key_create(&(key_list[i]),NULL);
+      found=true;
+      break;
+    }
+  }
+  // unlock the mutex before returning
+  CHK(pthread_mutex_unlock(&key_lock));
+  if (!found) {
+    // all keys are in use; max keys reached
+    ret_value=FOSA_EINVAL;
+  }
+  return ret_value;
+}
+
+/**
+ * fosa_key_destroy()
+ *
+ * Destroy a key
+ *
+ * This destroys the key and isables its use in the system
+ *
+ * @return 0 if successful \n
+ *   FOSA_EINVAL The key is not initialised or is not in FOSA key range.
+ **/
+int fosa_key_destroy(int key)
+{
+  int ret_value;
+
+  // lock the mutex
+  CHK(pthread_mutex_lock(&key_lock));
+
+  // destroy the key and mark it as available
+  ret_value=pthread_key_delete(key_list[key]);
+  if (ret_value==0) {
+    key_in_use[key]=false;
+  }
+
+  // unlock the mutex before returning
+  CHK(pthread_mutex_unlock(&key_lock));
+  return ret_value;
+}
+
+
+/**
+ * fosa_thread_set_specific_data()
+ *
+ * Set thread-specific data
+ *
+ * For the thread identified by tid, the thread-specifid data field
+ * identified by key will be set to the value specified by value
+ *
+ * Returns 0 if successful; otherwise, an error code is returned
+ *     EINVAL: the value of key is not between 0 and FOSA_MAX_KEYS-1
+ *
+ * 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_set_specific_data
+       (int key, frsh_thread_id_t tid, const void * value)
+{
+  return pthread_setspecific_for(key_list[key],tid,value);
+}
+
+/**
+ * fosa_thread_get_specific_data()
+ *
+ * Get thread-specific data
+ *
+ * For the thread identified by tid, the thread-specifid data field
+ * identified by key will be copied to the variable pointed to by value
+ *
+ * Returns 0 if successful; otherwise, an error code is returned
+ *     EINVAL: the value of key is not between 0 and FOSA_MAX_KEYS-1
+ *
+ * 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_specific_data(int key, frsh_thread_id_t tid, 
+                                  void ** value)
+{
+  return pthread_getspecific_from(key_list[key],tid,value);
+}
+
+
+/******************************************************************
+ * Thread scheduling
+ * 
+ * This implementation of FRSH assumes an underlying fixed priority
+ * scheduler with priorities in a range, with a minimum and a
+ * maximumm, a number of priority levels with at least 31
+ * priorities. A larger number implies a larger priority. In systems
+ * in which the underlying scheduler uses the opposite convention, a
+ * mapping is automatically provided by the OS adaptation layer.
+ *******************************************************************/
+
+/**
+ * fosa_get_priority_max()
+ *
+ * Return the maximum priority value used in this implementation
+ **/
+int fosa_get_priority_max()
+{
+  return sched_get_priority_max(SCHED_APP);
+}
+
+/**
+ * fosa_get_priority_min()
+ *
+ * Return the minimum priority value used in this implementation
+ **/
+int fosa_get_priority_min()
+{
+  return sched_get_priority_min(SCHED_APP);
+}
+
+/**
+ * fosa_thread_attr_set_prio()
+ *
+ * Change the priority of a thread attributes object
+ *
+ * The priority of the thread attriutes object specified by attr is
+ * set to the value specified by prio. This function has no runtime
+ * effect on the priority, except when the attributes object is used
+ * to create a thread, when it will be created with the specified
+ * priority
+ * 
+ * Returns 0 if successful, or the following error code:
+ *    EINVAL: the specified priority value is not between the 
+ *            minimum and the maximum priorities defined in this
+ *            FRSH implementation
+ * 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_prio(frsh_thread_attr_t *attr, int prio)
+{
+  struct sched_param param;
+
+  param.sched_priority=prio;
+  return pthread_attr_setschedparam(attr,&param);
+}
+
+/**
+ * fosa_thread_attr_get_prio()
+ *
+ * Get the priority from a thread attributes object
+ *
+ * This function sets the variable pointed to by prio to the
+ * priority stored in the thread attributes object attr.
+ * 
+ * Returns 0
+ **/
+int fosa_thread_attr_get_prio
+          (const frsh_thread_attr_t *attr, int *prio)
+{
+  struct sched_param param;
+  int ret_value;
+  
+  ret_value=pthread_attr_getschedparam(attr,&param);
+  if (ret_value==0) {
+    *prio=param.sched_priority;
+  }
+  return ret_value;
+}
+
+/**
+ * fosa_thread_set_prio()
+ *
+ * Dynamically change the priority of a thread
+ *
+ * The priority of the thread identified by tid is
+ * set to the value specified by prio. 
+ * 
+ * Returns 0 if successful, or the following error code:
+ *    EINVAL: the specified priority value is not between the 
+ *            minimum and the maximum priorities defined in this
+ *            FRSH implementation
+ * 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_set_prio(frsh_thread_id_t tid, int prio)
+{
+  struct sched_param param;
+  int policy;
+
+  CHK(pthread_getschedparam(tid,&policy,&param));
+  param.sched_priority=prio;
+  return pthread_setschedparam(tid,policy,&param);
+}
+
+/**
+ * fosa_thread_get_prio()
+ *
+ * Dynamically get the priority of a thread
+ *
+ * This function sets the variable pointed to by prio to the
+ * priority of the thread identified by tid
+ * 
+ * Returns 0
+ **/
+int fosa_thread_get_prio (frsh_thread_id_t tid, int *prio)
+{
+  struct sched_param param;
+  int policy, ret_value;
+
+  ret_value=pthread_getschedparam(tid,&policy,&param);
+  if (ret_value==0) {
+    *prio=param.sched_priority;
+  }
+  return ret_value;
+}
+
+
+
+/*******************************************************************
+ * Signals
+ *
+ * Signals represent events that may be notified by the system, or
+ * sent explicitly by the application, and for which a thread may
+ * synchronously wait. Signals carry an associated piece of
+ * information (an integer or a pointer) and are queued until they are
+ * accepted.  Signals are identified by an integer signal number (of
+ * the type frsh_signal_t) in the range FOSA_SIGNAL_MIN,
+ * FOSA_SIGNAL_MAX.  This range is required to have at least <tbd>
+ * 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<size;i++) {
+    CHKE(sigaddset(&signalset,set[i]));
+    // falta configurar la seƱal para que se pueda encolar........
+  } 
+  return pthread_sigmask(SIG_BLOCK,&signalset,NULL);
+}
+
+/**
+ * fosa_signal_queue()
+ *
+ * Queue a signal
+ *
+ * This function is used to explicitly send a signal with a specified
+ * value
+ * 
+ * The signal number specified by signal is sent together with the
+ * information specified by info, to the thread identified by
+ * receiver. 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 signal specified by signal is not
+ *              between FOSA_SIGNAL_MIN and FOSA_SIGNAL_MAX
+ *
+ *     EAGAIN: no resources are available to queue the signal; the
+ *             maximum number of queued signals has been reached, or a
+ *             systemwide resource limit has been exceeded
+ *
+ * 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_signal_queue
+       (frsh_signal_t signal, frsh_signal_info_t info,
+        frsh_thread_id_t receiver)
+{
+  // note: in MaRTE OS the signal is sent to any interested thread
+  pid_t pid=1; // dummy value; the pid is ignored in MaRTE OS
+  int err;
+
+  err=sigqueue(pid,signal, *( (union sigval *) &info) );
+  if (err==0) {
+    return 0;
+  } else {
+    return errno;
+  }
+}
+
+
+/**
+ * fosa_signal_wait()
+ *
+ * Wait for a signal
+ * 
+ * The function waits for the arrival of one of the signals in the
+ * array of signal numbers specified by set, which must be of size
+ * equal to size. If there is a signal already queued, the function
+ * returns immediately. If there is no signal of the specified set
+ * queued, the calling thread is suspended until a signal from that
+ * set arrives. Upon return, if signal_received is not NULL the number
+ * of the signal received is stored in the variable pointed to by
+ * signal_received; and if info is not NULL the associated information
+ * is stored in the variable pointed to by info.
+ *
+ * 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_signal_wait
+      (frsh_signal_t set[], int size, frsh_signal_t *signal_received, 
+       frsh_signal_info_t *info)
+{
+  int err,i;
+  sigset_t signalset;
+  siginfo_t siginfo;
+
+  CHKE(sigemptyset(&signalset));
+  for(i=0;i<size;i++) {
+    CHKE(sigaddset(&signalset,set[i]));
+  } 
+
+  err=sigwaitinfo(&signalset,&siginfo);
+  if (err!=-1) {
+    *signal_received=siginfo.si_signo;
+    *info= *( (frsh_signal_info_t *) &siginfo.si_value);
+    return 0;
+  } else {
+    return errno;
+  }
+}
+
+/**
+ * fosa_signal_timedwait()
+ *
+ * Timed wait for a signal
+ * 
+ * This function behaves the same as fosa_signal_wait(), except that
+ * the suspension time is limited to the time interval specified in
+ * the timespec structure referenced by timeout.
+ * 
+ * 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, or timeout is invalid
+ *     EAGAIN: The timeout expired
+ *
+ * Alternatively, in case of the EINVAL error the implementation is
+ * allowed to notify it to the system console and then terminate the
+ * FRSH implementation and dependant applications
+ **/
+ int fosa_signal_timedwait
+      (frsh_signal_t set[], int size, frsh_signal_t *signal_received, 
+       frsh_signal_info_t *info, const struct timespec *timeout)
+{
+
+  // the implementation of sigtimedwait is not yet available in MaRTE OS
+  return ENOSYS;
+
+/*   int err,i; */
+/*   sigset_t signalset; */
+/*   siginfo_t siginfo; */
+
+/*   CHKE(sigemptyset(&signalset)); */
+/*   for(i=0;i<size;i++) { */
+/*     CHKE(sigaddset(&signalset,set[i])); */
+/*   }  */
+
+/*   err=sigtimedwait(&signalset,&siginfo,timeout); */
+/*   if (err==0) { */
+/*     *signal_received=siginfo.si_signo; */
+/*     *info=siginfo.si_value; */
+/*     return 0; */
+/*   } else { */
+/*     return errno; */
+/*   } */
+}
+
diff --git a/src_marte_linux/frsh_fosa.c b/src_marte_linux/frsh_fosa.c
new file mode 100644 (file)
index 0000000..03ceddf
--- /dev/null
@@ -0,0 +1,151 @@
+// -----------------------------------------------------------------------
+//  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.
+//
+// -----------------------------------------------------------------------
+//frsh_fosa.c
+//==============================================
+//  ********  ******    ********  **********
+//  **///// /**    **  **//////  /**     /**
+//  **      /**    ** /**        /**     /**
+//  ******* /**    ** /********* /**********
+//  **////  /**    ** ////////** /**//////**
+//  **      /**    **        /** /**     /**
+//  **      /**    **  ********  /**     /**
+//  //       /******/  ////////   //      // 
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include "frsh_fosa.h"
+#include <pthread.h>
+#include <stdio.h>
+
+#include <misc/error_checks.h>
+
+/*************************
+ * 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 (file)
index 0000000..b0d076b
--- /dev/null
@@ -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 <unistd.h>
+#include <stdio.h>
+
+
+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, &current_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, &current_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, &current_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, &current_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, &current_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,&current_time);
+  fosa_mutex_unlock(&lock);
+  printf("cond timedwait with timeout=2 sec. err=%d\n",err);
+
+  fosa_clock_get_time(FOSA_CLOCK_REALTIME, &current_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;
+
+}