]> rtime.felk.cvut.cz Git - frescor/fosa.git/blob - src_aquosa/fosa_long_jump.c
Updating header text in FOSA files for the incoming final project
[frescor/fosa.git] / src_aquosa / fosa_long_jump.c
1 // -----------------------------------------------------------------------
2 //  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
3 //
4 //    Universidad de Cantabria,              SPAIN
5 //    University of York,                    UK
6 //    Scuola Superiore Sant'Anna,            ITALY
7 //    Kaiserslautern University,             GERMANY
8 //    Univ. Politécnica  Valencia,           SPAIN
9 //    Czech Technical University in Prague,  CZECH REPUBLIC
10 //    ENEA                                   SWEDEN
11 //    Thales Communication S.A.              FRANCE
12 //    Visual Tools S.A.                      SPAIN
13 //    Rapita Systems Ltd                     UK
14 //    Evidence                               ITALY
15 //
16 //    See http://www.frescor.org for a link to partners' websites
17 //
18 //           FRESCOR project (FP6/2005/IST/5-034026) is funded
19 //        in part by the European Union Sixth Framework Programme
20 //        The European Union is not liable of any use that may be
21 //        made of this code.
22 //
23 //
24 //  based on previous work (FSF) done in the FIRST project
25 //
26 //   Copyright (C) 2005  Mälardalen University, SWEDEN
27 //                       Scuola Superiore S.Anna, ITALY
28 //                       Universidad de Cantabria, SPAIN
29 //                       University of York, UK
30 //
31 //   FSF API web pages: http://marte.unican.es/fsf/docs
32 //                      http://shark.sssup.it/contrib/first/docs/
33 //
34 //   This file is part of FOSA (Frsh Operating System Adaption)
35 //
36 //  FOSA is free software; you can redistribute it and/or modify it
37 //  under terms of the GNU General Public License as published by the
38 //  Free Software Foundation; either version 2, or (at your option) any
39 //  later version.  FOSA is distributed in the hope that it will be
40 //  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
41 //  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
42 //  General Public License for more details. You should have received a
43 //  copy of the GNU General Public License along with FOSA; see file
44 //  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
45 //  Cambridge, MA 02139, USA.
46 //
47 //  As a special exception, including FOSA header files in a file,
48 //  instantiating FOSA generics or templates, or linking other files
49 //  with FOSA objects to produce an executable application, does not
50 //  by itself cause the resulting executable application to be covered
51 //  by the GNU General Public License. This exception does not
52 //  however invalidate any other reasons why the executable file might be
53 //  covered by the GNU Public License.
54 // -----------------------------------------------------------------------
55 //fosa_long_jump.c
56 //==============================================
57 //  ********  ******    ********  **********
58 //  **///// /**    **  **//////  /**     /**
59 //  **      /**    ** /**        /**     /**
60 //  ******* /**    ** /********* /**********
61 //  **////  /**    ** ////////** /**//////**
62 //  **      /**    **        /** /**     /**
63 //  **      /**    **  ********  /**     /**
64 //  //       /******/  ////////   //      //
65 //
66 // FOSA(Frescor Operating System Adaptation layer)
67 //================================================
68
69
70 #include "fosa.h"
71
72 /**
73  *  fosa_long_jump_save_context
74  *
75  *  Save the context of the current thread for a future long jump
76  *
77  *  This function stores in context the information required to modify
78  *  the stack of the calling thread so that a later long jump may be 
79  *  executed in the future to restore this context
80  *
81  *  This function stores in 'context' the registers and the stack
82  *  frame of the calling thread. This information can be used by
83  *  'restorecontext' to change the stack of the task so that when it
84  *  is scheduled again it returns to the end of this function
85  *
86  *  Depending on the underlying implementation, the first invocation
87  *  of this function for a given thread may also install a signal
88  *  handler or a signal handler thread that is capable of executing
89  *  the actions required to restore the context of a thread from the
90  *  appropriate context. For instance, in POSIX it is necesaray that
91  *  the context is restored from the same thread being restored,
92  *  usually from a signal handler of that thread.
93  *
94  *  Returns 0 if successful; otherwise it returns an error code:
95  *     FOSA_EINVAL: the value of context is invalid
96  *
97  *  Alternatively, in case of error the implementation is allowed to
98  *  notify it to the system console and then terminate the FRSH
99  *  implementation and dependant applications
100  */
101 int fosa_long_jump_save_context(fosa_long_jump_context_t *context)
102 {
103         if (context == NULL)
104                 return FOSA_EINVAL;
105
106         context->setjmp_retvalue = sigsetjmp(context->setjmp_context, 1);
107
108         return 0;
109 }
110
111 /**
112  *  fosa_long_jump_was_performed
113  *
114  *  Check whether the current thread suffered a long jump or not
115  *
116  *  This function should be invoked after fosa_long_jump_save_context
117  *  to determine whether the current thread is executing normally, or
118  *  has suffered a long jump to the point where the context was
119  *  saved. If invoked after a direct invocation to
120  *  fosa_long_jump_save_context, the function shall return 0. If
121  *  invoked after returning from fosa_long_jump_save_context due to a
122  *  call to fosa_long_jump_restore_context, the function shall return
123  *  1.
124  *
125  *  Returns 0 if successful; otherwise it returns an error code:
126  *     FOSA_EINVAL: the value of context is invalid
127  *
128  *  Alternatively, in case of error the implementation is allowed to
129  *  notify it to the system console and then terminate the FRSH
130  *  implementation and dependant applications
131  */
132 int fosa_long_jump_was_performed(const fosa_long_jump_context_t *context,
133                                  int *jumped)
134 {
135         if (context == NULL)
136                 return FOSA_EINVAL;
137
138         *jumped = context->setjmp_retvalue != 0;
139
140         return 0;
141 }
142
143 /** 
144  * Body of the long-jump handler thread 
145  **/
146 void __long_jump_handler(int n, siginfo_t *info, void *c)
147 {
148         fosa_long_jump_context_t *context =
149                 (fosa_long_jump_context_t*) info->si_ptr;
150
151         siglongjmp(context->setjmp_context, -1);
152 }
153
154 /**
155  *  fosa_long_jump_install_handler
156  *
157  *  Install a long jump handler for the calling thread
158  *
159  *  This function shall install a handler that is capable of causing a
160  *  long jump operation that restores the context of a thread to a
161  *  previously saved value. If the handler has already been installed
162  *  for this thread the previously installed handler will be used and
163  *  the call shall succeed.
164  *
165  *  The long-jump handler is waiting for a signal to notify that a
166  *  thread context should be restored. This signal must carry attached
167  *  to it a pointer to the variable where the thread context was
168  *  saved. The thread referenced in that context will have its
169  *  internal context restored to the point where it was saved. For
170  *  this restore operation to work properly, the program frame where
171  *  the thread saved its context must still be valid.
172  *
173  *  Depending on the implementation a given thread may also install a signal
174  *  handler or a signal handler thread that is capable of executing
175  *  the actions required to restore the context of a thread from the
176  *  appropriate context. For instance, in POSIX it is necesaray that
177  *  the context is restored from the same thread being restored,
178  *  usually from a signal handler of that thread.
179  *
180  *  The function shall store in the variable pointed to by signal the
181  *  identifier of the signal that must be used to notify the request
182  *  for a long jump to be executed. In the variable pointed to by
183  *  handler, it shall store the thread id to which the signal must be
184  *  sent. The signal must be sent with its attached information set to
185  *  a pointer to the variable of type fosa_long_jump_context_t where
186  *  the context of the thread to be restored was saved.
187  *
188  *  Returns 0 if successful; otherwise it returns an error code:
189  *     FOSA_EINVAL: the value of context is invalid
190  *     FOSA_ENOMEM: there are no resources to satisfy the call at this time
191  *
192  *  Alternatively, in case of error the implementation is allowed to
193  *  notify it to the system console and then terminate the FRSH
194  *  implementation and dependant applications
195  */
196 int fosa_long_jump_install_handler(fosa_signal_t *signal,
197                                    fosa_thread_id_t *handler)
198 {
199         int ret;
200         struct sigaction sa_long_jump;
201
202         *signal = FOSA_LONG_JUMP_SIGNAL;
203         *handler = fosa_thread_self();
204
205         sa_long_jump.sa_handler = NULL;
206         sa_long_jump.sa_sigaction = __long_jump_handler;
207         sigemptyset(&sa_long_jump.sa_mask);
208         sa_long_jump.sa_flags = SA_SIGINFO;
209
210         ret = sigaction(*signal, &sa_long_jump, NULL);
211
212         return ret ? errno : 0;
213 }
214