--- /dev/null
+// -----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+// 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
+//
+// The 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.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or
+// without modification, are permitted provided that the
+// following conditions are met:
+//
+// * Redistributions of source code must retain the above
+// copyright notice, this list of conditions and the
+// following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the
+// following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+// * Neither the name of FRESCOR nor the names of its
+// contributors may be used to endorse or promote products
+// derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+// CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+// -----------------------------------------------------------------------
+//fosa_app_def_sched.c
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include "string.h"
+#include "malloc.h"
+#include "heapapi.h"
+#include "ose.h"
+
+#include "fosa.h"
+#include "fosa_app_def_sched.h"
+#include "fosa_ose_implementation_specific.h"
+
+#include "frsh_internal.h"
+
+//Debug purpose only.................
+#include "stdio.h"
+
+/**
+ * @defgroup appdefsched Application Defined Scheduling
+ * @ingroup fosa
+ *
+ * This module defines the function and types for an abstraction of
+ * the Application Defined Scheduling.
+ *
+ * @{
+ **/
+
+
+
+/********************************
+ * 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.
+ **/
+
+/*
+ * author erth
+ *
+ * Creation of the ads scheduler that takes the events from OSE calls the
+ * right scheduler callback that returns a list of actions that is
+ * executed in the right order by this function.
+ *
+ * author erth swedish:
+ *
+ * Denna funktion skall kunna ta emot event (att process nu blivit
+ * blockad, terminerad, signallerad eller ready) från "OSE" eller annan
+ * del av FOSA. Därefter skall rätt funktion i structen med
+ * funktionspekare anropas. Vilket ÄR FRSH schemaläggaren. Sedan fyller
+ * FRSH schemaläggaren på med action noder i action listan. När anropet
+ * till "rätt funktion" returnerar så skall den nu inte längre tomma
+ * listan med actions utföras. Efter detta loopas det tillbaka till att
+ * vänta på en ny action, alternativt ta emot nästa meddelande i action
+ * kön (OSE:s signal kö till denna process).
+ */
+OS_PROCESS(fosa_scheduler_process)
+{
+ struct timespec current_time;
+ fosa_ose_scheduler_startup_t *sig;
+ fosa_ads_scheduler_ops_t scheduler_ops;
+ frsh_sched_data_t* frsh_sched_data;
+
+ SIGSELECT sel_any[] = { 0 };
+ SIGSELECT sel_start_sig[] = {1, FOSA_OSE_STARTUP_SIGNAL};
+ SIGSELECT event = 0;
+ PROCESS asking_pid = 0;
+ PROCESS event_pid = 0;
+
+
+ // Receive the scheduler startup signal
+ sig = (fosa_ose_scheduler_startup_t *) receive(sel_start_sig);
+
+ scheduler_ops = sig->scheduler_ops;
+ frsh_sched_data = (frsh_sched_data_t *)
+ malloc(sig->scheduler_data_size);
+
+ // Initialize the scheduler
+ //scheduler_ops.frsh_callback_init(frsh_sched_data, sig->init_args);
+ free_buf((union SIGNAL**)&sig);
+
+ // Initialize the queue of actions
+ fosa_ose_action_t* tmp_action;
+ fosa_ads_actions_t actions;
+ fosa_ose_ads_actions_init(&actions);
+
+ fosa_ose_event_signal_t *event_sig;
+ while(1) {
+ //Recieve the event
+ event_sig = (fosa_ose_event_signal_t *) receive(sel_any);
+ event = event_sig->sig_no;
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, ¤t_time);
+
+ //Call the right scheduler callback function.
+ switch (event) {
+
+ case FOSA_OSE_BLOCK_SIGNAL:
+ event_pid = event_sig->pid;
+ printf("FOSA SCHEDULER: Process %x blocked.\n",
+ event_pid); //Debug purpose only...................
+ //scheduler_ops.frsh_callback_thread_block(
+ // frsh_sched_data,
+ // frsh_thread_id_t thread,
+ // &actions,
+ // ¤t_time)
+ break;
+
+ case FOSA_OSE_READY_SIGNAL:
+ event_pid = event_sig->pid;
+ printf("FOSA SCHEDULER: Process %x ready.\n",
+ event_pid); //Debug purpose only...................
+ //scheduler_ops.frsh_callback_thread_ready(
+ // frsh_sched_data,
+ // frsh_thread_id_t thread,
+ // &actions,
+ // ¤t_time)
+ break;
+
+ case FOSA_OSE_SIGNAL_SCHED_SIGNAL:
+ //scheduler_ops.frsh_callback_signal(
+ // frsh_sched_data,
+ // frsh_signal_t signal,
+ // frsh_signal_info_t signal_info,
+ // &actions,
+ // ¤t_time)
+ break;
+
+ case FOSA_OSE_TERMINATE_SIGNAL:
+ event_pid = event_sig->pid;
+ printf("FOSA SCHEDULER: Process %x terminated.\n",
+ event_pid); //Debug purpose only...................
+ //scheduler_ops.frsh_callback_thread_terminate(
+ // frsh_sched_data,
+ // event_sig->tid,
+ // &actions,
+ // ¤t_time)
+ break;
+
+ case FOSA_OSE_NEW_THREAD_SIGNAL:
+ event_pid = event_sig->pid;
+ asking_pid = sender((union SIGNAL**)&event_sig);
+ printf("FOSA SCHEDULER: Process %x new.\n", event_pid); //Debug purpose only...................
+ //scheduler_ops.frsh_callback_new_thread(
+ // frsh_sched_data,
+ // event_sig->tid,
+ // &actions,
+ // ¤t_time);
+ /*
+ * author erth
+ *
+ * We also need to save the process that the question was
+ * sent from. To be able to reply with a reject or activate
+ * in the action below. Since the action type can't save
+ * it, it's stored in the variable asking_pid.
+ *
+ * If the thread is rejected a REJECT action is added to
+ * the actions list. But if accepted, no REJECT action is
+ * added. Instead of adding a ACCEPT action if there were
+ * one. Now you need to search through the list
+ * of actions to see if there is any reject action. If
+ * none, it is accepted. Bad design of FOSA API.
+ */
+ tmp_action = actions.FirstAction;
+ while (tmp_action != NULL)
+ {
+ if (tmp_action->action == REJECT)
+ break;
+ tmp_action = tmp_action->NextAction;
+ }
+ if (tmp_action == NULL)
+ fosa_ose_execute_action_accept(asking_pid);
+ break;
+
+ /*case FOSA_OSE_EMPTY:
+ //scheduler_ops.frsh_callback_explicit_call_with_data((void *) frsh_sched_data,
+ // frsh_thread_id_t thread_id,
+ // const void * msg,
+ // size_t msg_size,
+ // void **reply,
+ // size_t *reply_size,
+ // fosa_ads_actions_t * actions,
+ // ¤t_time)
+ break;
+
+ case FOSA_OSE_EMPTY:
+ //scheduler_ops.frsh_callback_change_sched_param_thread(
+ // frsh_sched_data,
+ // frsh_thread_id_t thread,
+ // &actions,
+ // ¤t_time)
+ break;
+
+ case FOSA_OSE_EMPTY:
+ //scheduler_ops.frsh_callback_appsched_error(
+ // frsh_sched_data,
+ // frsh_thread_id_t thread,
+ // fosa_ads_error_cause_t cause,
+ // &actions)
+ break;
+
+ case FOSA_OSE_SHUTDOWN_FRSH:
+ //Shutdown the possible parts of frsh and fosa and return
+ //all allocated memory. Restart FRSH again?
+ free(frsh_sched_data);
+ kill_proc(current_process());
+ break;
+ */
+ case FOSA_OSE_TEST_EVENT_SIGNAL:
+ ramlog_printf("FOSA: Sucess by: receive an event in the \
+ scheduler.\n");
+ fosa_ose_adsactions_add_test(&actions, (action_t)SUSPEND);
+ break;
+
+ default:
+ ramlog_printf("FOSA: Unknown event (sig_no: %d) given to \
+ scheduler. The scheduler process shutdown.\n", event);
+ kill_proc(current_process());
+ break;
+ }
+ free_buf((union SIGNAL **)&event_sig);
+
+ //Execute the received actions in the action list, returned from
+ //the callback scheduler functions above.
+ while(actions.LastAction != NULL){
+ switch (actions.FirstAction->action) {
+ case ACTIVATE:
+ //fosa_ose_execute_action_activate(
+ // actions.FirstAction->thread);
+ break;
+
+ case REJECT:
+ //fosa_ose_execute_action_reject(
+ // asking_pid, actions.FirstAction->thread);
+ break;
+
+ case SUSPEND:
+ printf("Sucess by: Action %d executed.\n",
+ actions.FirstAction->action); //Debug purpose only...................
+ //fosa_ose_execute_action_suspend(
+ // actions.FirstAction->thread);
+ break;
+
+ case THREAD_NOTIFICATION:
+ //fosa_ose_execute_action_thread_notification(
+ // actions.FirstAction);
+ break;
+
+ case TIMEOUT:
+ //fosa_ose_execute_action_timeout(
+ // actions.FirstAction);
+ break;
+
+ default:
+ ramlog_printf("FOSA SCHEDULER: Unknown action (no: %d\
+ ) given to scheduler. The scheduler process shutdown.\
+ \n", actions.FirstAction->action);
+ kill_proc(current_process());
+ break;
+ }
+ fosa_ose_adsactions_remove_first(&actions);
+ }
+ }
+ kill_proc(current_process());
+}
+
+/**
+ * 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)
+{
+ /*
+ * author erth
+ *
+ * There are no way to kill this process and to turn off the fosa
+ * implementation. That would be nice to have, actually almost need to
+ * have! Other wise ther will be many schedulers if this function are
+ * called several times. Michael Gonzales sais that there are no
+ * reason to turn of the scheduler... I think there should be a way to
+ * turn off as many tings as possible anyway.
+ */
+
+ // Error check.
+ if (scheduler_ops == NULL) return FOSA_EINVAL;
+ //Can better check be performed?
+
+ // Create scheduler startup signal
+ fosa_ose_scheduler_startup_t *sig;
+ sig = (fosa_ose_scheduler_startup_t *)alloc(
+ sizeof(fosa_ose_scheduler_startup_t) + init_args_size +
+ scheduler_data_size,
+ FOSA_OSE_STARTUP_SIGNAL);
+
+ //Stupid to make copy here????........................................
+ sig->scheduler_ops = *scheduler_ops;
+ sig->scheduler_data_size = scheduler_data_size;
+ sig->init_args = init_args;
+ sig->init_args_size = init_args_size;
+
+ //Make ose priority from fosa priority, and set attr.
+ OSPRIORITY prio = (OSPRIORITY) fosa_get_priority_max()
+ + fosa_get_priority_min() - FRSH_SCHEDULER_PRIORITY;
+
+
+ // Create the scheduler
+ char name[] = "fosa_scheduler_process";
+ PROCESS pid = create_process(
+ OS_PRI_PROC, // Process type.
+ name, // Name.
+ fosa_scheduler_process, // Entrypoint.
+ 1000, // Stacksize.
+ prio, // Priority. 28+3-29=2 To low?
+ 0, // Timeslice.
+ 0, // 0 = Part of callers block.......??
+ NULL, // No signal redirection.
+ 0, // OSvector.
+ 0); // OSuser.
+
+ send((union SIGNAL **)&sig, pid);
+ start(pid);
+
+ // EAGAIN error check taken care of by OSE.
+ return 0;
+}
+
+
+/**
+ * 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)
+{
+ if (attr == NULL) return FOSA_EINVAL;
+
+ attr->app_scheduled = appscheduled;
+
+ return 0;
+}
+
+/**
+ * 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)
+{
+ if (attr == NULL) return FOSA_EINVAL;
+
+ *appscheduled = attr->app_scheduled;
+
+ return 0;
+}
+
+/**
+ * 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)
+{
+ if (attr == NULL) return FOSA_EINVAL;
+
+ attr->appsched_param = heap_realloc_shared(
+ attr->appsched_param, paramsize, __FILE__, __LINE__);
+ if (attr->appsched_param == NULL) return ENOMEM;
+
+ // Copy *param to above allocated memory
+ memcpy( attr->appsched_param, param, paramsize );
+ attr->appsched_param_size = paramsize;
+
+ return 0;
+}
+
+/**
+ * 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)
+{
+ if (attr == NULL)
+ return FOSA_EINVAL;
+ else if (attr->appsched_param == NULL)
+ return FOSA_EINVAL;
+
+ if (attr->app_scheduled) {
+ /*
+ * author erth
+ *
+ * This is not logical. The size of the memory area
+ * should be returned, but memory of (at least) the same size need
+ * to be already reserved, by the one who calls this function.
+ * This means the caller need to already know the size of the
+ * memory. Then why return the size? Or why not reserve the memory
+ * here? Reasoning in circles!!!...................................
+ */
+
+ //param = (void *) malloc(attr->appsched_param_size); // Should not be done here!?!!
+ //in that case a (void **param) are needed, not a (void *param).
+ memcpy( param, attr->appsched_param, attr->appsched_param_size );
+ *paramsize = attr->appsched_param_size;
+ } else {
+ return FOSA_EINVAL;
+ }
+
+ /*
+ * author erth
+ *
+ * Since allocated memory at attr->appsched_param are not freed here
+ * this is possibly a memoryleak,
+ * where or when are this memory returned?...........................
+ */
+
+ return 0;
+}
+
+/**
+ * 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)
+{
+ fosa_ose_process_info_t* process = fosa_ose_process_get_node(thread);
+ if (process == NULL) return FOSA_EINVAL;
+
+ //Ask the scheduler if ok to add the thread?..........................
+ //Or possible to use the user area variable of the process?...........
+
+ process->app_scheduled = appscheduled;
+ return 0;
+}
+
+/**
+ * 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)
+{
+ fosa_ose_process_info_t* process = fosa_ose_process_get_node(thread);
+ if (process == NULL) return FOSA_EINVAL;
+
+ *appscheduled = process->app_scheduled;
+ return 0;
+}
+
+
+/**
+ * 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)
+{
+ fosa_ose_process_info_t* process = fosa_ose_process_get_node(thread);
+ if ((paramsize < 0) ||
+ (paramsize > FOSA_ADS_SCHEDPARAM_MAX) ||
+ (process == NULL)) {
+ return FOSA_EINVAL;
+ }
+
+ process->appsched_param = heap_realloc_shared(
+ process->appsched_param, paramsize, __FILE__, __LINE__);
+ memcpy(process->appsched_param, param, paramsize);
+ process->appsched_param_size = paramsize;
+
+ return 0;
+}
+
+/**
+ * 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)
+{
+ fosa_ose_process_info_t* process = fosa_ose_process_get_node(thread);
+ if (process == NULL) return FOSA_EINVAL;
+
+ *paramsize = process->appsched_param_size;
+ memcpy(param, process->appsched_param, process->appsched_param_size);
+
+ return 0;
+}
+
+
+/*********************************
+ * 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.
+ *
+ *********************************/
+
+/*
+ * author erth
+ *
+ * This function are introcuded to avoid code multiplication in the
+ * fosa_adsactions_add_* functions and it should also only be called by
+ * these functions. It returns 0 if successful, otherwise the errors given
+ * by its calling function.
+ */
+int fosa_ose_adsactions_add(fosa_ads_actions_t* sched_actions,
+ action_t action,
+ frsh_thread_id_t thread,
+ fosa_ads_urgency_t urgency,
+ fosa_clock_id_t clock_id,
+ time_t sec,
+ long nsec)
+{
+ // How to initialize fosa_ads_actions_t? Set pointers to NULL............
+ bool sched_actions_first_element = false;
+
+ // Chcek for errors.
+ if (sched_actions->LastAction == NULL) {
+ sched_actions_first_element = true;
+ } else if (sched_actions->LastAction->NextAction != NULL)
+ return FOSA_EINVAL;
+
+ // Make new action node.
+ fosa_ose_action_t* NewAction = (fosa_ose_action_t*)
+ heap_alloc_shared(sizeof(fosa_ose_action_t), __FILE__, __LINE__);
+ if (NewAction == NULL) return FOSA_ENOMEM;
+
+ NewAction->action = action;
+ NewAction->tid = thread;
+ NewAction->urgency = urgency;
+ NewAction->clock_id = clock_id;
+ NewAction->at_time.tv_sec = sec;
+ NewAction->at_time.tv_nsec = nsec;
+ NewAction->NextAction = NULL;
+
+ // Add action node to list.
+ if (sched_actions_first_element)
+ sched_actions->FirstAction = NewAction;
+ else
+ (sched_actions->LastAction)->NextAction = NewAction;
+
+ sched_actions->LastAction = NewAction;
+
+ return 0;
+}
+
+/**
+ * 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)
+{
+ if (thread != current_process()) return FOSA_EPOLICY;
+
+ return fosa_ose_adsactions_add( sched_actions, //sched_actions
+ REJECT, //action
+ thread, //thread
+ 0, //urgency
+ 0, //clock_id
+ 0, //sec
+ 0); //nsec
+}
+
+/**
+ * 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 fosa_ose_adsactions_add( sched_actions, //sched_actions
+ ACTIVATE, //action
+ thread, //thread
+ urgency, //urgency
+ 0, //clock_id
+ 0, //sec
+ 0); //nsec
+}
+
+/**
+ * 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 fosa_ose_adsactions_add( sched_actions, //sched_actions
+ SUSPEND, //action
+ thread, //thread
+ 0, //urgency
+ 0, //clock_id
+ 0, //sec
+ 0); //nsec
+}
+
+/**
+ * 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 fosa_ose_adsactions_add( sched_actions, //sched_actions
+ TIMEOUT, //action
+ current_process(), //thread
+ 0, //urgency
+ clock_id, //clock_id
+ at_time->tv_sec, //sec
+ at_time->tv_nsec); //nsec
+}
+
+/**
+ * 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 fosa_ose_adsactions_add( sched_actions, //sched_actions
+ THREAD_NOTIFICATION,//action
+ thread, //thread
+ 0, //urgency
+ clock_id, //clock_id
+ at_time->tv_sec, //sec
+ at_time->tv_nsec); //nsec
+}
+
+
+/**
+ * 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[])
+{
+ /*
+ * author erth
+ *
+ * This function is not neccisary in OSE since set[] is used as an
+ * argument in the calls to fosa_signal_wait() and
+ * fosa_signal_timedwait() functions. Also decided to be empty in
+ * Barcelona meeting 2007-01-31.
+ */
+ return 0;
+}
+
+/**
+ * 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)
+{
+ //Not implemented yet!!...........................................
+
+ /*
+ * author erth
+ *
+ * This function should send a message to the fosa_scheduler_process,
+ * that calls the frsh_callback_explicit_call_with_data(),
+ * that creates a reply message that are
+ * sent back to this process from fosa_scheduler_process,
+ * here we then set the reply message and
+ * this function return
+ *
+ * For example a call to frsh_contract_negotiate() results in a call
+ * to this function. If the messages were not sent the execution of the
+ * callback would be made of the calling processes. Which are not good.
+ */
+
+ return 0;
+ }
+
+/*}*/
+
+