]> rtime.felk.cvut.cz Git - frescor/fosa.git/blobdiff - src_marte_os/fosa_long_jump.c
Renaming fosa/src_marte to fosa/src_marte_os
[frescor/fosa.git] / src_marte_os / fosa_long_jump.c
diff --git a/src_marte_os/fosa_long_jump.c b/src_marte_os/fosa_long_jump.c
new file mode 100644 (file)
index 0000000..56a906b
--- /dev/null
@@ -0,0 +1,288 @@
+// -----------------------------------------------------------------------
+//  Copyright (C) 2006 - 2008 FRESCOR consortium partners:
+//
+//    Universidad de Cantabria,              SPAIN
+//    University of York,                    UK
+//    Scuola Superiore Sant'Anna,            ITALY
+//    Kaiserslautern University,             GERMANY
+//    Univ. Politécnica  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.
+//
+//
+//  based on previous work (FSF) done in the FIRST project
+//
+//   Copyright (C) 2005  Mälardalen University, SWEDEN
+//                       Scuola Superiore S.Anna, ITALY
+//                       Universidad de Cantabria, SPAIN
+//                       University of York, UK
+//
+//   FSF API web pages: http://marte.unican.es/fsf/docs
+//                      http://shark.sssup.it/contrib/first/docs/
+//
+//   This file is part of FOSA (Frsh Operating System Adaption)
+//
+//  FOSA is free software; you can redistribute it and/or modify it
+//  under terms of the GNU General Public License as published by the
+//  Free Software Foundation; either version 2, or (at your option) any
+//  later version.  FOSA 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 along with FOSA; see file
+//  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+//  Cambridge, MA 02139, USA.
+//
+//  As a special exception, including FOSA header files in a file,
+//  instantiating FOSA generics or templates, or linking other files
+//  with FOSA objects to produce an executable application, does not
+//  by itself cause the resulting executable application 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 Public License.
+// -----------------------------------------------------------------------
+//fosa_long_jump.c
+//==============================================
+//  ********  ******    ********  **********
+//  **///// /**    **  **//////  /**     /**
+//  **      /**    ** /**        /**     /**
+//  ******* /**    ** /********* /**********
+//  **////  /**    ** ////////** /**//////**
+//  **      /**    **        /** /**     /**
+//  **      /**    **  ********  /**     /**
+//  //       /******/  ////////   //      //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "fosa.h"
+#include <marte_non_local_jmp.h>
+
+/**
+ * Global variables
+ */
+
+static int handler_installed=0;
+static fosa_thread_id_t handler_tid;
+
+/**
+ *  fosa_long_jump_save_context
+ *
+ *  Save the context of the current thread for a future long jump
+ *
+ *  This function stores in context the information required to modify
+ *  the stack of the calling thread so that a later long jump may be 
+ *  executed in the future to restore this context
+ *
+ *  This function stores in 'context' the registers and the stack
+ *  frame of the calling thread. This information can be used by
+ *  'restorecontext' to change the stack of the task so that when it
+ *  is scheduled again it returns to the end of this function
+ *
+ *  Depending on the underlying implementation, the first invocation
+ *  of this function for a given thread may also install a signal
+ *  handler or a signal handler thread that is capable of executing
+ *  the actions required to restore the context of a thread from the
+ *  appropriate context. For instance, in POSIX it is necesaray that
+ *  the context is restored from the same thread being restored,
+ *  usually from a signal handler of that thread.
+ *
+ *  Returns 0 if successful; otherwise it returns an error code:
+ *     FOSA_EINVAL: the value of context 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_long_jump_save_context
+   (fosa_long_jump_context_t * context) 
+{
+  if (context==NULL) {
+    return FOSA_EINVAL;
+  } else {
+    marte_nonlocaljmp_savecontext (&(context->marte_context));
+    context->tid=pthread_self();
+    return 0;
+  }
+}
+
+
+/**
+ *  fosa_long_jump_was_performed
+ *
+ *  Check whether the current thread suffered a long jump or not
+ *
+ *  This function should be invoked after fosa_long_jump_save_context
+ *  to determine whether the current thread is executing normally, or
+ *  has suffered a long jump to the point where the context was
+ *  saved. If invoked after a direct invocation to
+ *  fosa_long_jump_save_context, the function shall return 0. If
+ *  invoked after returning from fosa_long_jump_save_context due to a
+ *  call to fosa_long_jump_restore_context, the function shall return
+ *  1.
+ *
+ *  Returns 0 if successful; otherwise it returns an error code:
+ *     FOSA_EINVAL: the value of context 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_long_jump_was_performed
+(const fosa_long_jump_context_t * context, int * jumped) 
+{
+  if (context==NULL) {
+    return FOSA_EINVAL;
+  } else {
+    *jumped=marte_nonlocaljmp_afterjmp (&(context->marte_context));
+    return 0;
+  }  
+}
+
+
+/** 
+ * Body of the long-jump handler thread 
+ */
+
+void * fosa_long_jump_handler (void * arg) {
+
+  fosa_signal_t set[1];
+  fosa_signal_t sig;
+  fosa_signal_info_t siginfo;
+
+  fosa_long_jump_context_t *info;
+
+  // initialize signal handling
+  set[0]=FOSA_LONG_JUMP_SIGNAL;
+  if (fosa_set_accepted_signals(set, 1) !=0) {
+      printf("FOSA_ERR_INTERNAL_ERROR, Error setting the signal mask\n");
+      exit(1); 
+  }
+
+  // main thread loop  
+  while (1) {
+    // Wait for a budget overrun signal
+    if ((fosa_signal_wait(set, 1, &sig, &siginfo)) == -1) {
+      printf("FOSA_ERR_INTERNAL_ERROR, signal wait in long jump handler\n");
+      exit(1);
+    }
+    // Restore thread's context
+    info=((fosa_long_jump_context_t*) (siginfo.sival_ptr));
+    marte_nonlocaljmp_restorecontext(info->tid,&(info->marte_context));
+  }
+}
+
+
+
+/**
+ *  fosa_long_jump_install_handler
+ *
+ *  Install a long jump handler for the calling thread
+ *
+ *  This function shall install a handler that is capable of causing a
+ *  long jump operation that restores the context of a thread to a
+ *  previously saved value. If the handler has already been installed
+ *  for this thread the previously installed handler will be used and
+ *  the call shall succeed.
+ *
+ *  The long-jump handler is waiting for a signal to notify that a
+ *  thread context should be restored. This signal must carry attached
+ *  to it a pointer to the variable where the thread context was
+ *  saved. The thread referenced in that context will have its
+ *  internal context restored to the point where it was saved. For
+ *  this restore operation to work properly, the program frame where
+ *  the thread saved its context must still be valid.
+ *
+ *  Depending on the implementation a given thread may also install a signal
+ *  handler or a signal handler thread that is capable of executing
+ *  the actions required to restore the context of a thread from the
+ *  appropriate context. For instance, in POSIX it is necesaray that
+ *  the context is restored from the same thread being restored,
+ *  usually from a signal handler of that thread.
+ *
+ *  The function shall store in the variable pointed to by signal the
+ *  identifier of the signal that must be used to notify the request
+ *  for a long jump to be executed. In the variable pointed to by
+ *  handler, it shall store the thread id to which the signal must be
+ *  sent. The signal must be sent with its attached information set to
+ *  a pointer to the variable of type fosa_long_jump_context_t where
+ *  the context of the thread to be restored was saved.
+ *
+ *  Returns 0 if successful; otherwise it returns an error code:
+ *     FOSA_EINVAL: the value of context is invalid
+ *     FOSA_ENOMEM: there are no resources to satisfy the call at this time
+ *
+ *  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_long_jump_install_handler
+(fosa_signal_t *signal, fosa_thread_id_t *handler)
+{
+  fosa_thread_attr_t attr;
+  int err;
+  
+  if (!handler_installed) {
+
+    handler_installed=1;
+
+    //////////////////////////////////////////////////
+    // create the long jump handler thread
+    //////////////////////////////////////////////////
+    
+    // Create the thread attributes object
+    err=fosa_thread_attr_init (&attr);
+    if (err != 0) {
+      printf("Error while initializing the attributes\n");
+      return err;
+    }
+    
+    // set the maximum priority level for the handler
+    err=fosa_thread_attr_set_prio (&attr,fosa_get_priority_max());
+    if (err != 0) {
+      printf("Error while setting schedparam\n");
+      return err;
+    }
+    
+    /* create the signal handler thread */
+    err = fosa_thread_create(&handler_tid, &attr, 
+                            fosa_long_jump_handler, NULL);
+    if (err) {
+      printf("pthread_create signal handler\n");
+      return err;
+    }
+    
+    // destroy the thread attributes object
+    err=fosa_thread_attr_destroy (&attr);
+    if (err != 0) {
+      printf("Error while destroying the attributes\n");
+      return err;
+    }
+  
+  } // if handler not installed
+
+  // return handler and signal information
+  *handler=handler_tid;
+  *signal=FOSA_LONG_JUMP_SIGNAL;
+  return 0;
+
+}
+
+
+
+/*@}*/
+