-/** 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);
+}