-SOURCES = $(wildcard *.c)
-NAMES = $(basename $(SOURCES))
-OBJS = $(addsuffix .o,$(NAMES))
+FOSA_MODULES=fosa_clocks_and_timers fosa_threads_and_signals fosa_app_def_sched fosa_mutexes_and_condvars fosa_misc
+FOSA_OBJS = $(addsuffix .o,$(FOSA_MODULES))
FOSA_INC=../include
-FRSH_INC=../../../frsh/trunk/include
-PRTK_INC=../../../partikle/user/ulibc/include
-# Hack to avoid missing rtl_timer.h compilation issue
-RTL_TIMER_INC=.
+PRTK=$(HOME)/FRESCOR/FRSHv2/partikle/trunk
+PRTK_INC=$(PRTK)/user/ulibc/include
-CFLAGS+=-I$(FOSA_INC) -I$(FRSH_INC) -DRT_LINUX -I$(PRTK_INC) -I$(RTL_TIMER_INC)
-LIBFOSA=libfosa_PARTIKLE.a
+check_gcc = $(shell \
+ if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1 ;\
+ then \
+ echo "$(1)";\
+ else \
+ echo "$(2)";\
+ fi)
+
+CFLAGS+=-I$(FOSA_INC)\
+ -DPARTIKLE\
+ -I$(PRTK_INC)\
+# -DCONFIG_URGENCY\
+CFLAGS += $(call check_gcc, -fno-stack-protector,)
+LIBFOSA=libfosa_PARTIKLE.a
+CC=gcc
-all: libfosa.a
+all: $(LIBFOSA)
-libfosa.a: $(OBJS)
- $(AR) -r $(LIBFOSA) $(OBJS)
+$(LIBFOSA): $(FOSA_OBJS)
+ $(AR) -r $(LIBFOSA) $(FOSA_OBJS)
cp $(LIBFOSA) ../lib
-# test_fosa_c.o: test_fosa.o
-# ld -r -o test_fosa_c.o test_fosa.o $(LIBFOSA)
+test_fosa.prtk: test_fosa.c $(LIBFOSA)
+ $(CC) -c test_fosa.c $(CFLAGS)
+ ldkernel -o test_fosa.prtk test_fosa.o $(LIBFOSA)
# test_fosa.o: test_fosa.c
clean:
- $(RM) -f *.o *~ *.a
+ $(RM) -f *.o *~ *.a *.prtk
-/** fosa_app_def_sched.h
- *
- * < description >
- * < author >
- * < date >
- */
+// -----------------------------------------------------------------------
+// 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.
+//
+// As a special exception, if you include this header file into source
+// files to be compiled, this header file does not by itself cause
+// the resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+// -----------------------------------------------------------------------
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include <fosa_configuration_parameters.h>
+#include <fosa_app_def_sched.h>
+#include <sched.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+// #include <fosa_configuration_parameters.h>
+
+#define REACHS(str) printf ("%s: %s: %d: %s\n", __FILE__, __FUNCTION__, __LINE__, str)
+
+static pthread_t fosa_scheduler_th; // Scheduler thread
+static fosa_ads_scheduler_ops_t fosa_scheduler_ops; // Scheduler operations
+static void * fosa_scheduler_data; // Scheduler parameters
+static size_t fosa_scheduler_data_size;
+static void * fosa_init_args; // Scheduler initialisation args
+static size_t fosa_init_args_size;
+static sigset_t fosa_handled_signals; // Signals handled by the scheduler
+
+// Reply info for 'fosa_ads_invoke_withdata ()'
+struct reply_info{
+ void * msg;
+ size_t * size_ptr;
+};
+static int fosa_reply_key;
+
+void clear_actions (fosa_ads_actions_t *act)
+{
+ posix_appsched_actions_destroy (&(act -> actions));
+ posix_appsched_actions_init (&(act -> actions));
+ act -> activated = false;
+ act -> suspended = false;
+ act -> rejected = false;
+ act -> timeout_ptr = NULL;
+}
+
+void *fosa_scheduler_main (void * args)
+{
+ fosa_ads_actions_t actions;
+ struct posix_appsched_event event;
+ struct timespec current_time;
+ posix_appsched_eventset_t accepted_events;
+ bool active;
+
+
+ // accept events which have a callback associated
+ posix_appsched_fillset (&accepted_events);
+ if (fosa_scheduler_ops.new_thread)
+ posix_appsched_delset (&accepted_events,POSIX_APPSCHED_NEW);
+
+ if (fosa_scheduler_ops.thread_terminate)
+ posix_appsched_delset (&accepted_events,POSIX_APPSCHED_TERMINATE);
+
+ if (fosa_scheduler_ops.thread_ready)
+ posix_appsched_delset (&accepted_events,POSIX_APPSCHED_READY);
+
+ if (fosa_scheduler_ops.thread_block)
+ posix_appsched_delset (&accepted_events,POSIX_APPSCHED_BLOCK);
+
+ if (fosa_scheduler_ops.change_sched_param_thread)
+ posix_appsched_delset (&accepted_events, POSIX_APPSCHED_CHANGE_SCHED_PARAM);
+
+ if (fosa_scheduler_ops.explicit_call_with_data)
+ posix_appsched_delset (&accepted_events, POSIX_APPSCHED_EXPLICIT_CALL_WITH_DATA);
+
+// if (fosa_scheduler_ops.notification_for_thread)
+// posix_appsched_delset (&accepted_events,POSIX_APPSCHED_TASK_NOTIFICATION);
+
+ if (fosa_scheduler_ops.timeout)
+ posix_appsched_delset (&accepted_events,POSIX_APPSCHED_TIMEOUT);
+
+ if (fosa_scheduler_ops.signal)
+ posix_appsched_delset (&accepted_events,POSIX_APPSCHED_SIGNAL);
+
+// if (fosa_scheduler_ops.signal)
+// posix_appsched_delset (&accepted_events,POSIX_APPSCHED_ERRROR);
+
+ posix_appschedattr_seteventmask(&accepted_events);
+
+ // Set the clock (and its) flags used by the scheduler
+ posix_appschedattr_setclock (FOSA_CLOCK_REALTIME);
+ posix_appschedattr_setflags (POSIX_APPSCHED_ABSTIMEOUT);
+
+ // init scheduler
+ fosa_scheduler_ops.init (fosa_scheduler_data, fosa_init_args);
+ clear_actions (&actions);
+
+ while (1) { // scheduler loop
+// printf ("ACTIONS: timeout(0x%x), handled_signals=0x%x\n", actions.timeout_ptr, fosa_handled_signals.sig);
+ if (posix_appsched_execute_actions(&(actions.actions), &fosa_handled_signals, actions.timeout_ptr,
+ ¤t_time, &event))
+ perror ("posix_appsched_execute_actions");
+
+// printf ("\nReceived event=%d. current_time={%ld,%ld}\n", event.event_code, current_time.tv_sec, current_time.tv_nsec);
+ clear_actions (&actions);
+
+ switch (event.event_code) {
+ case POSIX_APPSCHED_NEW:
+ fosa_scheduler_ops.new_thread
+ (fosa_scheduler_data,
+ event.thread,
+ &actions,
+ ¤t_time);
+
+ if (!actions.rejected) {
+
+/* active = actions.activated;
+ int suspend = actions.suspended; */
+#ifdef CONFIG_URGENCY
+ #error "Urgency not supported. Disable this feature in the Makefile"
+#else
+ clear_actions (&actions);
+// printf ("NEW: activate (%d), suspend (%d)\n", actions.activated, actions.suspended);
+#endif
+
+ posix_appsched_actions_addaccept (&actions.actions, event.thread);
+
+// printf ("activated\n");
+// if (active)
+// fosa_adsactions_add_activate (&actions, event.thread, 0);
+// if (suspend)
+// fosa_adsactions_add_suspend (&actions, event.thread);
+
+
+ // alloc memory for reply info of 'fosa_ads_invoke_with_data ()'
+ struct reply_info *reply_mem = malloc (sizeof (struct reply_info));
+ if (!reply_mem) {
+ printf ("BUG: not enougth dynamic memory\n");
+ exit (-20);
+ }
+ pthread_setspecific_for (fosa_reply_key, event.thread, reply_mem);
+ }
+ break;
+ case POSIX_APPSCHED_TERMINATE:
+ fosa_scheduler_ops.thread_terminate
+ (fosa_scheduler_data,
+ event.thread,
+ &actions,
+ ¤t_time);
+ break;
+ case POSIX_APPSCHED_READY:
+ fosa_scheduler_ops.thread_ready
+ (fosa_scheduler_data,
+ event.thread,
+ &actions,
+ ¤t_time);
+ break;
+ case POSIX_APPSCHED_BLOCK:
+ fosa_scheduler_ops.thread_block
+ (fosa_scheduler_data,
+ event.thread,
+ &actions,
+ ¤t_time);
+ break;
+ case POSIX_APPSCHED_CHANGE_SCHED_PARAM:
+ fosa_scheduler_ops.change_sched_param_thread
+ (fosa_scheduler_data,
+ event.thread,
+ &actions,
+ ¤t_time);
+ break;
+ case POSIX_APPSCHED_EXPLICIT_CALL_WITH_DATA:
+ {
+ struct reply_info *fosa_reply;
+
+ // Get reply memory pointer
+// printf ("CALL_WITH_DATA: caller 0x%x\n", event.thread);
+ pthread_getspecific_from (fosa_reply_key, event.thread, (void **) &fosa_reply);
+// printf ("reply_size (0x%x)=%d\n", fosa_reply -> size_ptr, (fosa_reply -> size_ptr)? *(fosa_reply -> size_ptr):-1);
+ fosa_scheduler_ops.explicit_call_with_data
+ (fosa_scheduler_data,
+ event.thread,
+ event.event_info.info,
+ event.info_size,
+ fosa_reply -> msg,
+ fosa_reply -> size_ptr,
+ &actions,
+ ¤t_time);
+
+// printf ("CALL_WITH_DATA: activate (%d), suspend (%d)\n", actions.activated, actions.suspended);
+ // activate the thread unless suspended or already activated
+ if (!actions.suspended && !actions.activated) {
+ posix_appsched_actions_addactivate
+ (&actions.actions, event.thread);
+ }
+
+ } break;
+ case POSIX_APPSCHED_TIMEOUT:
+ fosa_scheduler_ops.timeout
+ (fosa_scheduler_data,
+ &actions,
+ ¤t_time);
+ break;
+ case POSIX_APPSCHED_SIGNAL:
+ fosa_scheduler_ops.signal
+ (fosa_scheduler_data,
+ event.event_info.siginfo.si_signo,
+ (fosa_signal_info_t)event.event_info.siginfo.si_value.sival_ptr,
+ &actions,
+ ¤t_time);
+ break;
+/* - NOT IMPLEMENTED
+
+ case POSIX_APPSCHED_THREAD_NOTIFICATION:
+ fosa_scheduler_ops.notification_for_thread
+ (fosa_scheduler_data, event.thread,(fosa_clock_id_t) event.event_info.info, &actions, ¤t_time);
+ break;
+
+ case POSIX_APPSCHED_ERROR:
+ fosa_scheduler_ops.appsched_error
+ (fosa_scheduler_data,
+ event.thread,
+ 0,
+ &actions);
+ break;
+
+ */
+ }
+// printf ("ENd LOOP\n");
+ }
+}
/********************************
* Application-defined scheduling
(const fosa_ads_scheduler_ops_t * scheduler_ops,
size_t scheduler_data_size,
void * init_args,
- size_t init_args_size);
+ size_t init_args_size)
+{
+ pthread_attr_t attr;
+ struct sched_param sp;
+
+ if (!scheduler_ops)
+ return EINVAL;
+ fosa_scheduler_ops = *scheduler_ops;
+
+ // Alloc memory for init args and scheduler data
+ fosa_init_args_size = init_args_size;
+ fosa_init_args = malloc (init_args_size);
+ if (!init_args)
+ return EAGAIN;
+
+ memcpy (fosa_init_args, init_args, init_args_size);
+
+ fosa_scheduler_data_size = scheduler_data_size;
+ fosa_scheduler_data = malloc (scheduler_data_size);
+ if (!fosa_scheduler_data) {
+ free (init_args);
+ return EAGAIN;
+ }
+ memset (fosa_scheduler_data, 0, scheduler_data_size);
+
+ // Key for reply information index of 'fosa_reply' for each thread
+ pthread_key_create (&fosa_reply_key, NULL);
+
+ // Set scheduler thread parameters
+ pthread_attr_init (&attr);
+ sp.sched_priority = sched_get_priority_max (SCHED_FIFO) + FOSA_ADS_SCHEDULER_PRIO_DIFF;
+ pthread_attr_setschedparam (&attr, &sp);
+ pthread_attr_setschedpolicy (&attr, SCHED_FIFO);
+ pthread_attr_setappschedulerstate (&attr, PTHREAD_APPSCHEDULER);
+ pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
+ pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED);
+
+ if (pthread_create (&fosa_scheduler_th, &attr, fosa_scheduler_main, NULL))
+ return errno;
+ else
+ return 0;
+}
int fosa_thread_attr_set_appscheduled
- (frsh_thread_attr_t *attr,
- bool appscheduled);
+ (fosa_thread_attr_t *attr,
+ bool appscheduled)
+{
+ int err;
+
+ if (err = pthread_attr_setappscheduler (attr, fosa_scheduler_th))
+ return err;
+
+ if (appscheduled)
+ return pthread_attr_setschedpolicy (attr, SCHED_APP);
+ else
+ return pthread_attr_setschedpolicy (attr, SCHED_FIFO);
+}
+
int fosa_thread_attr_get_appscheduled
- (const frsh_thread_attr_t *attr,
- bool *appscheduled);
-
+ (const fosa_thread_attr_t *attr,
+ bool *appscheduled)
+{
+ int policy, err;
+
+ if (err = pthread_attr_getschedpolicy (attr, &policy))
+ return err;
+
+ *appscheduled = (policy == SCHED_APP);
+ return 0;
+}
+
+
int fosa_thread_attr_set_appsched_params
- (frsh_thread_attr_t *attr,
+ (fosa_thread_attr_t *attr,
const void *param,
- size_t paramsize);
+ size_t paramsize)
+{
+#if FOSA_ADS_SCHEDPARAM_MAX > POSIX_APPSCHEDPARAM_MAX
+#error FOSA_ADS_SCHEDPARAM_MAX > POSIX_APPSCHEDPARAM_MAX
+#endif
+ if (paramsize > FOSA_ADS_SCHEDPARAM_MAX)
+ return FOSA_EINVAL;
+
+ return pthread_attr_setappschedparam (attr, param, paramsize);
+}
+
int fosa_thread_attr_get_appsched_params
- (const frsh_thread_attr_t *attr,
+ (const fosa_thread_attr_t *attr,
void *param,
- size_t *paramsize);
+ size_t *paramsize)
+{
+ return pthread_attr_getappschedparam (attr, param, paramsize);
+}
+
int fosa_ads_set_appscheduled
- (frsh_thread_id_t thread,
- bool appscheduled);
+ (fosa_thread_id_t thread,
+ bool appscheduled)
+{
+ struct sched_param sp;
+ int policy_old, policy_new, err;
+
+ if (err = pthread_getschedparam (thread, &policy_old, &sp))
+ return err;
+
+ if (appscheduled) {
+ if (err = pthread_setappscheduler (thread, fosa_scheduler_th))
+ return err;
+
+ policy_new = SCHED_APP;
+ } else {
+ policy_new = SCHED_FIFO;
+ }
+
+ if (policy_new != policy_old)
+ return pthread_setschedparam (thread, policy_new, &sp);
+
+ return 0;
+}
+
int fosa_ads_get_appscheduled
- (frsh_thread_id_t thread,
- bool *appscheduled);
+ (fosa_thread_id_t thread,
+ bool *appscheduled)
+{
+ struct sched_param sp;
+ int policy, err;
+
+ if (err = pthread_getschedparam (thread, &policy, &sp))
+ return err;
+
+ *appscheduled = (policy == SCHED_APP);
+ return 0;
+}
+
int fosa_ads_set_appsched_params
- (frsh_thread_id_t thread,
+ (fosa_thread_id_t thread,
const void *param,
- size_t paramsize);
+ size_t paramsize)
+{
+ return pthread_setappschedparam (thread, param, paramsize);
+}
+
int fosa_ads_get_appsched_params
- (frsh_thread_id_t thread,
+ (fosa_thread_id_t thread,
void *param,
- size_t *paramsize);
+ size_t *paramsize)
+{
+ return pthread_getappschedparam (thread, param, paramsize);
+}
*********************************/
int fosa_adsactions_add_reject
(fosa_ads_actions_t *sched_actions,
- frsh_thread_id_t thread);
+ fosa_thread_id_t thread)
+{
+ sched_actions -> rejected = true;
+ return posix_appsched_actions_addreject (&(sched_actions -> actions), thread);
+}
int fosa_adsactions_add_activate
(fosa_ads_actions_t *sched_actions,
- frsh_thread_id_t thread,
- fosa_ads_urgency_t urgency);
+ fosa_thread_id_t thread,
+ fosa_ads_urgency_t urgency)
+{
+ sched_actions -> activated = true;
+#ifdef CONFIG_URGENCY
+ #error "Urgency not supported. Disable this feature in the Makefile"
+#endif
+// printf ("0x%x: Activate thread 0x%x\n", pthread_self (), thread);
+ return posix_appsched_actions_addactivate (&(sched_actions -> actions), thread);
+}
-int fosa_adsactions_add_suspend
+int fosa_adsactions_add_suspend
(fosa_ads_actions_t *sched_actions,
- frsh_thread_id_t thread);
+ fosa_thread_id_t thread)
+{
+// printf ("0x%x: Suspend thread 0x%x\n", pthread_self (), thread);
+ sched_actions -> suspended = true;
+ return posix_appsched_actions_addsuspend (&(sched_actions -> actions), thread);
+}
int fosa_adsactions_add_timeout
(fosa_ads_actions_t *sched_actions,
fosa_clock_id_t clock_id,
- const struct timespec *at_time);
+ const struct timespec *at_time)
+{
+ sched_actions -> timeout = *at_time;
+ sched_actions -> timeout_ptr = &(sched_actions -> timeout);
+ return 0;
+}
int fosa_adsactions_add_thread_notification
(fosa_ads_actions_t *sched_actions,
- frsh_thread_id_t thread,
+ fosa_thread_id_t thread,
fosa_clock_id_t clock_id,
- const struct timespec *at_time);
+ const struct timespec *at_time)
+{
+ printf ("BUG: fosa_adsactions_add_thread_notification: Not implemented\n");
+ exit (-21);
+ return 0;
+}
+
+
+int fosa_ads_set_handled_signal_set (fosa_signal_t set[], int size)
+{
+ int i;
+
+ if (!pthread_equal (pthread_self (), fosa_scheduler_th))
+ return EPOLICY;
+
+ printf ("\n\nHANDLED\n");
+ sigemptyset (&fosa_handled_signals);
+ for (i = 0; i < size; i++) {
+ if (FOSA_SIGNAL_MIN > set [i] || set [i] > FOSA_SIGNAL_MAX)
+ return EINVAL;
+ sigaddset (&fosa_handled_signals, set[i]);
+ }
+ return fosa_set_accepted_signals (set, size);
+}
+
+
+int fosa_signal_queue_scheduler (fosa_signal_t signal, fosa_signal_info_t info)
+{
+ return fosa_signal_queue (signal, info, 0);
+}
+
-int fosa_ads_set_handled_signal_set (frsh_signal_t set[], int size);
-int fosa_signal_queue_scheduler (frsh_signal_t signal, frsh_signal_info_t info);
int fosa_ads_invoke_withdata
- (const void *msg, size_t msg_size, void *reply, size_t *reply_size);
+ (const void *msg, size_t msg_size, void *reply, size_t *reply_size)
+{
+ struct reply_info *fosa_reply;
+
+#if FOSA_ADS_SCHEDINFO_MAX > POSIX_APPSCHEDINFO_MAX
+#error FOSA_ADS_SCHEDINFO_MAX > POSIX_APPSCHEDINFO_MAX
+#endif
+
+ if (msg_size > FOSA_ADS_SCHEDINFO_MAX)
+ return EINVAL;
+
+ fosa_reply = (struct reply_info *) pthread_getspecific (fosa_reply_key);
+ fosa_reply -> msg = reply;
+ fosa_reply -> size_ptr = reply_size;
+
+ return posix_appsched_invoke_withdata (msg, msg_size, NULL, NULL);
+}
-/** fosa_clocks_and_timers.c
- *
- * < description >
- * < author >
- * < date >
- */
+// -----------------------------------------------------------------------
+// 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.
+//
+// As a special exception, if you include this header file into source
+// files to be compiled, this header file does not by itself cause
+// the resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+// -----------------------------------------------------------------------
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
#include <fosa_clocks_and_timers.h>
}
-
-int fosa_thread_get_cputime_clock(frsh_thread_id_t tid, fosa_clock_id_t *clockid)
+int fosa_thread_get_cputime_clock(fosa_thread_id_t tid, fosa_clock_id_t *clockid)
{
-// if (tid == thread_invalid)
-// return FOSA_EINVAL;
-
- *clockid = CLOCK_THREAD_CPUTIME_ID;
- return 0;
+ return pthread_getcpuclockid (tid, clockid);
}
+
+
+
/*************************
* Timing: Timers
*************************/
+// #define FRSH_DEADLINE_NEWJOB_TIMEOUT 0x00050000
+void void_handler (int signo) {};
int fosa_timer_create
- (fosa_clock_id_t clockid, frsh_signal_t signal, frsh_signal_info_t info,
- fosa_timer_id_t *timerid);
+ (fosa_clock_id_t clockid, fosa_signal_t signal, fosa_signal_info_t info,
+ fosa_timer_id_t *timerid)
+ {
+ struct sigevent se;
+ struct sigaction act;
+
+ // Assumption: the signal should accept queued values
+ act.sa_handler = void_handler;
+ sigfillset (&act.sa_mask);
+ act.sa_flags = SA_SIGINFO; // accept signal queuing
+ sigaction (signal, &act, NULL);
+
+ se.sigev_notify = SIGEV_SIGNAL;
+ se.sigev_signo = signal;
+
+ se.sigev_value.sival_int = info.sival_int;
+ se.sigev_value.sival_ptr = info.sival_ptr;
+
+ return timer_create (clockid, &se, timerid);
+/*
+ if ((info.sival_int & 0xFFFF0000) == FRSH_DEADLINE_NEWJOB_TIMEOUT)
+ printf ("\n\ndeadline %d timer created: info=0x%x, signal=%d ()\n\n", *timerid, info.sival_int, signal);
+*/
+}
+
int fosa_timer_delete(fosa_timer_id_t timerid)
{
- if (timer_delete (timerid))
- return FOSA_EINVAL;
- return 0;
+ return timer_delete (timerid);
}
(fosa_timer_id_t timerid, bool abstime,
const struct timespec *value)
{
- struct itimerspec value =
+ struct timespec now;
+
+ clock_gettime (CLOCK_REALTIME, &now);
+
+// printf ("(0x%x): Arm timer (%d). abstime=%d, value={%ld,%ld}, now={%ld, %ld}\n",\
+// pthread_self (), timerid, abstime, value -> tv_sec, value -> tv_nsec, now.tv_sec, now.tv_nsec);
+
+ struct itimerspec tvalue =
{
.it_value = (struct timespec) *value,
- .it_interval = 0,
- }
+ .it_interval = {0,0},
+ };
- if (timer_settime (timerid, abstime, &value, NULL))
+ if (timer_settime (timerid, abstime, &tvalue, NULL))
return EINVAL;
return 0;
}
-// TODO: CPU-clock ???
int fosa_timer_get_remaining_time
(fosa_timer_id_t timerid, struct timespec *remaining_time)
{
return 0;
}
+
int fosa_timer_disarm(fosa_timer_id_t timerid, struct timespec
*remaining_time)
{
struct itimerspec null_timer, old;
// NULL timer -> disarm
- value = (struct itimerspec) {
+ null_timer = (struct itimerspec) {
.it_value = {0, 0},
.it_interval = 0,
- }
+ };
if (timer_settime (timerid, 0, &null_timer, &old))
return EINVAL;
return 0;
}
+
-/** fosa_mutexes_and_condvars.h
- *
- * < description >
- * < author >
- * < date >
- */
+// -----------------------------------------------------------------------
+// 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.
+//
+// As a special exception, if you include this header file into source
+// files to be compiled, this header file does not by itself cause
+// the resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+// -----------------------------------------------------------------------
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
#include <fosa_mutexes_and_condvars.h>
/*******************************************************
* Mutexes with priority ceiling
******************************************************/
-int fosa_mutex_init(frsh_mutex_t *mutex, int prioceiling);
-int fosa_mutex_destroy(frsh_mutex_t *mutex);
+int fosa_mutex_init(fosa_mutex_t *mutex, int prioceiling)
+{
+ pthread_mutexattr_t attr;
+ int err;
+
+ if (err = pthread_mutexattr_init (&attr))
+ return err;
+
+ pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK);
+ pthread_mutexattr_setprotocol (&attr, PTHREAD_PRIO_PROTECT);
+ if (err = pthread_mutexattr_setprioceiling (&attr, prioceiling))
+ return err;
+
+ return pthread_mutex_init (mutex, &attr);
+}
+
+int fosa_mutex_destroy(fosa_mutex_t *mutex)
+{
+ return pthread_mutex_destroy (mutex);
+}
+
int fosa_mutex_set_prioceiling
- (frsh_mutex_t *mutex, int new_ceiling, int *old_ceiling);
-int fosa_mutex_get_prioceiling(const frsh_mutex_t *mutex, int *ceiling);
-int fosa_mutex_lock(frsh_mutex_t *mutex);
-int fosa_mutex_trylock(frsh_mutex_t *mutex);
-int fosa_mutex_unlock(frsh_mutex_t *mutex);
+ (fosa_mutex_t *mutex, int new_ceiling, int *old_ceiling)
+{
+ return pthread_mutex_setprioceiling (mutex, new_ceiling, old_ceiling);
+}
+
+int fosa_mutex_get_prioceiling(const fosa_mutex_t *mutex, int *ceiling)
+{
+ return pthread_mutex_getprioceiling (mutex, ceiling);
+}
+
+int fosa_mutex_lock(fosa_mutex_t *mutex)
+{
+ return pthread_mutex_lock (mutex);
+}
+
+int fosa_mutex_trylock(fosa_mutex_t *mutex)
+{
+ return pthread_mutex_trylock (mutex);
+}
+
+int fosa_mutex_unlock(fosa_mutex_t *mutex)
+{
+ return pthread_mutex_unlock (mutex);
+}
/**********************
* Condition variables
*********************/
-int fosa_cond_init(fosa_cond_t *cond);
-int fosa_cond_destroy(fosa_cond_t *cond);
-int fosa_cond_signal(fosa_cond_t *cond);
-int fosa_cond_broadcast(fosa_cond_t *cond);
-int fosa_cond_wait(fosa_cond_t *cond, frsh_mutex_t *mutex);
-int fosa_cond_timedwait(fosa_cond_t *cond, frsh_mutex_t *mutex,
- const struct timespec *abstime);
+int fosa_cond_init(fosa_cond_t *cond)
+{
+ pthread_condattr_t attr;
+ int err;
+
+ if (err = pthread_condattr_init (&attr))
+ return err;
+
+ return pthread_cond_init (cond, NULL);
+}
+
+int fosa_cond_destroy(fosa_cond_t *cond)
+{
+ return pthread_cond_destroy (cond);
+}
+
+int fosa_cond_signal(fosa_cond_t *cond)
+{
+ return pthread_cond_signal (cond);
+}
+
+int fosa_cond_broadcast(fosa_cond_t *cond)
+{
+ return pthread_cond_broadcast (cond);
+}
+
+int fosa_cond_wait(fosa_cond_t *cond, fosa_mutex_t *mutex)
+{
+ return pthread_cond_wait (cond, mutex);
+}
+
+int fosa_cond_timedwait
+ (fosa_cond_t *cond,
+ fosa_mutex_t *mutex,
+ const struct timespec *abstime)
+{
+ int err;
+
+ err = pthread_cond_timedwait (cond, mutex, abstime);
+ if (err == ETIMEDOUT)
+ return ETIMEDOUT;
+
+ if (err)
+ return EINVAL;
+
+ return 0;
+}
-/** fosa_threads_and_signals.h
- *
- * < description >
- * < author >
- * < date >
- */
+// -----------------------------------------------------------------------
+// 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.
+//
+// As a special exception, if you include this header file into source
+// files to be compiled, this header file does not by itself cause
+// the resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+// -----------------------------------------------------------------------
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+#include <fosa_configuration_parameters.h>
#include <fosa_threads_and_signals.h>
+#include <unistd.h>
+#include <signal.h>
/*************************
* Thread identification
*************************/
-bool fosa_thread_equal(frsh_thread_id_t t1, frsh_thread_id_t t2);
-frsh_thread_id_t fosa_thread_self();
-
+bool fosa_thread_equal(fosa_thread_id_t t1, fosa_thread_id_t t2)
+{
+ return pthread_equal (t1, t2);
+}
+
+fosa_thread_id_t fosa_thread_self()
+{
+ return pthread_self();
+}
+
+/*************************
+ * Thread attributes
+ *************************/
+
+int fosa_thread_attr_init(fosa_thread_attr_t *attr)
+{
+ return pthread_attr_init (attr);
+}
+
+int fosa_thread_attr_destroy(fosa_thread_attr_t *attr)
+{
+ return pthread_attr_destroy (attr);
+}
+
+int fosa_thread_attr_set_stacksize(fosa_thread_attr_t *attr,
+ size_t stacksize)
+{
+ return pthread_attr_setstacksize (attr, stacksize);
+}
+
+
+int fosa_thread_attr_get_stacksize(const fosa_thread_attr_t *attr,
+ size_t *stacksize)
+{
+ return pthread_attr_getstacksize (attr, stacksize);
+}
+
+
/*************************
* Thread creation and termination
*************************/
-int fosa_thread_create
- (frsh_thread_id_t *tid, const frsh_thread_attr_t *attr,
- frsh_thread_code_t code, void * arg);
+ int fosa_thread_create
+ (fosa_thread_id_t *tid,
+ const fosa_thread_attr_t *attr,
+ fosa_thread_code_t code,
+ void * arg)
+{
+ return pthread_create (tid, attr, code, arg);
+}
/**************************************************
* Thread-specific data
* (extended with access from a different thread)
**************************************************/
-int fosa_key_create(int *key);
-int fosa_key_destroy(int key);
-int fosa_thread_set_specific_data
- (int key, frsh_thread_id_t tid, const void * value);
-int fosa_thread_get_specific_data(int key, frsh_thread_id_t tid,
- void ** value);
+int fosa_key_create(int *key)
+{
+ switch (pthread_key_create (key, NULL)) {
+ case 0:
+ break;
+ case ENOMEM:
+ return ENOMEM;
+ break;
+ case EAGAIN:
+ default:
+ return FOSA_EINVAL;
+ }
+
+ if (*key >= FOSA_MAX_KEYS + 1) {
+ pthread_key_delete (*key);
+ return FOSA_EINVAL;
+ }
+
+ return 0;
+}
+
+int fosa_key_destroy(int key)
+{
+ if (key < 0 || key >= FOSA_MAX_KEYS + 1)
+ return FOSA_EINVAL;
+
+ return pthread_key_delete (key);
+}
+
+ int fosa_thread_set_specific_data
+ (int key, fosa_thread_id_t tid, const void * value)
+{
+ if (key < 0 || key >= FOSA_MAX_KEYS + 1)
+ return FOSA_EINVAL;
+
+ return pthread_setspecific_for (key, tid, value);
+}
+
+int fosa_thread_get_specific_data(int key, fosa_thread_id_t tid,
+ void ** value)
+{
+ if (key < 0 || key >= FOSA_MAX_KEYS + 1)
+ return FOSA_EINVAL;
+
+ return pthread_getspecific_from (key, tid, value);
+}
/**********************
* Thread scheduling
**********************/
-int fosa_get_priority_max();
-int fosa_get_priority_min();
-int fosa_thread_attr_set_prio(frsh_thread_attr_t *attr, int prio);
-int fosa_thread_attr_get_prio
- (const frsh_thread_attr_t *attr, int *prio);
-int fosa_thread_set_prio(frsh_thread_id_t tid, int prio);
-int fosa_thread_get_prio (frsh_thread_id_t tid, int *prio);
+// PaRTiKle uses decreasing values for increasing priority (0 -> maxprio)
+// TODO: planificació jerà rquica
+
+int fosa_get_priority_max()
+{
+ return sched_get_priority_min (SCHED_FIFO);
+}
+
+int fosa_get_priority_min()
+{
+ return sched_get_priority_max (SCHED_FIFO);
+}
+
+int fosa_thread_attr_set_prio(fosa_thread_attr_t *attr, int prio)
+{
+ struct sched_param sp;
+
+ if (prio > fosa_get_priority_max () || prio < fosa_get_priority_min ())
+ return EINVAL;
+
+ sp.sched_priority = sched_get_priority_min (SCHED_FIFO) - prio;
+
+ return pthread_attr_setschedparam (attr, &sp);
+}
+
+ int fosa_thread_attr_get_prio
+ (const fosa_thread_attr_t *attr, int *prio)
+{
+ struct sched_param sp;
+
+ pthread_attr_getschedparam (attr, &sp);
+
+ *prio = sched_get_priority_min (SCHED_FIFO) - sp.sched_priority;
+
+ return 0;
+}
+
+int fosa_thread_set_prio(fosa_thread_id_t tid, int prio)
+{
+ struct sched_param sp;
+ int policy;
+
+ if (prio > fosa_get_priority_max () || prio < fosa_get_priority_min ())
+ return EINVAL;
+
+ pthread_getschedparam (tid, &policy, &sp);
+ sp.sched_priority = sched_get_priority_min (SCHED_FIFO) - prio;
+
+ return pthread_setschedparam (tid, policy, &sp);
+}
+
+int fosa_thread_get_prio (fosa_thread_id_t tid, int *prio)
+{
+ struct sched_param sp;
+ int policy;
+
+ pthread_getschedparam (tid, &policy, &sp);
+ *prio = sched_get_priority_min (SCHED_FIFO) - sp.sched_priority;
+
+ return 0;
+}
/*************
* Signals
*************/
-int fosa_set_accepted_signals(frsh_signal_t set[], int size);
+int fosa_set_accepted_signals(fosa_signal_t set[], int size)
+{
+ int i;
+ sigset_t accept_set;
+ struct sigaction act;
+
+ if (size < 0)
+ return EINVAL;
+
+ sigemptyset (&accept_set);
+ act.sa_mask = accept_set;
+ act.sa_flags = SA_SIGINFO;
+ act.sa_handler = SIG_DFL;
+
+// printf ("Handled\n");
+// printf ("Fosa signal range [%d,%d]\n", FOSA_SIGNAL_MIN, FOSA_SIGNAL_MAX);
+ for (i = 0; i < size; i ++) {
+// printf ("signal num=%d\n", set [i]);
+ if (FOSA_SIGNAL_MIN > set [i] || set [i] > FOSA_SIGNAL_MAX)
+ return EINVAL;
+
+ sigaction (set [i], &act, NULL);
+ sigaddset (&accept_set, set [i]);
+ }
+
+// printf ("Added to accept set\n");
+ return pthread_sigmask (SIG_BLOCK, &accept_set, NULL);
+}
+
+
int fosa_signal_queue
- (frsh_signal_t signal, frsh_signal_info_t info,
- frsh_thread_id_t receiver);
+ (fosa_signal_t signal, fosa_signal_info_t info,
+ fosa_thread_id_t receiver)
+{
+ union sigval *nfo = (union sigval *) &info;
+
+ if (sigqueue (1, signal, *nfo))
+ return errno;
+ else
+ return 0;
+}
+
+
int fosa_signal_wait
- (frsh_signal_t set[], int size, frsh_signal_t *signal_received,
- frsh_signal_info_t *info);
+ (fosa_signal_t set[], int size, fosa_signal_t *signal_received,
+ fosa_signal_info_t *info)
+{
+ return fosa_signal_timedwait (set, size, signal_received, info, NULL);
+}
+
int fosa_signal_timedwait
- (frsh_signal_t set[], int size, frsh_signal_t *signal_received,
- frsh_signal_info_t *info, const struct timespec *timeout);
+ (fosa_signal_t set[], int size, fosa_signal_t *signal_received,
+ fosa_signal_info_t *info, const struct timespec *timeout)
+{
+ int i, sig;
+ sigset_t wset;
+ siginfo_t nfo;
+
+ if (size < 0)
+ return EINVAL;
+
+ sigemptyset (&wset);
+ for (i = 0; i < size; i ++) {
+ if (FOSA_SIGNAL_MIN > set [i] || set [i] > FOSA_SIGNAL_MAX)
+ return EINVAL;
+ sigaddset (&wset, set [i]);
+ }
+
+ sig = sigtimedwait (&wset, &nfo, timeout);
+ if (sig == -1)
+ return errno;
+
+ if (info)
+ *info = *((fosa_signal_info_t*) (&nfo.si_value));
+
+ if (signal_received)
+ *signal_received = sig;
+
+ return 0;
+}