include ../config.mk
include ../rules.mk
-FOSA_MODULES=fosa_clocks_and_timers fosa_threads_and_signals fosa_app_def_sched fosa_mutexes_and_condvars fosa_misc fosa_long_jump fosa_time
+FOSA_MODULES=fosa_clocks_and_timers fosa_threads_and_signals fosa_app_def_sched fosa_mutexes_and_condvars fosa_misc fosa_long_jump fosa_time fosa_setjmp
FOSA_OBJS=$(addsuffix .o,$(FOSA_MODULES))
check_gcc = $(shell \
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
&actions,
¤t_time);
break;
-
- case POSIX_APPSCHED_ERROR: // Implemented using the usual error handling mechanism
- fosa_scheduler_ops.appsched_error
- (fosa_scheduler_data,
- event.thread,
- 0,
- &actions);
- break;
-
*/
+ default:
+ printf ("BUG: Unknown ADS event\n");
+ exit (-20);
+ break;
}
}
}
/*************************
* Timing: Timers
*************************/
-void void_handler (int signo) {};
int fosa_timer_create
(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;
+ struct sigaction act, oact;
- // Assumption: the signal should accept queued values
- act.sa_handler = void_handler;
- sigfillset (&act.sa_mask);
+ sigaction (signal, NULL, &oact);
+ act = oact;
act.sa_flags = SA_SIGINFO; // accept signal queuing
sigaction (signal, &act, NULL);
#ifdef CONFIG_LONGJUMP
#include <fosa_long_jump.h>
+#include <stdio.h>
-enum {
- LONGJMP_MAGIC = 0x01234567,
-};
-
+#define LONGJMP_MAGIC 0x01234567
int jmp_used_signals [LONGJMP_NSIG] = {[0 ... (LONGJMP_NSIG - 1)] = 0};
pthread_mutex_t signal_pool_m = PTHREAD_MUTEX_INITIALIZER;
-
-int fosa_long_jump_save_context
- (fosa_long_jump_context_t * context)
-{
- if (!context)
- return FOSA_EINVAL;
-
- // Save the actual signal mask & mark the jump as still not performed
- pthread_sigmask (SIG_SETMASK, NULL, &(context -> jmp_sigmask));
- context -> jmp_hasexecuted = false;
-
- if (setjmp (context -> jmp_context) == LONGJMP_MAGIC) {
-#ifndef CONFIG_LONGJUMP_FREE_SIGNALS
- pthread_sigmask (SIG_SETMASK, &(context -> jmp_sigmask), NULL);
-#endif
- context -> jmp_hasexecuted = true;
- }
- return 0;
-}
-
+extern void fosa_longjmp (fosa_long_jump_context_t ctx, unsigned long magic);
int fosa_long_jump_was_performed
(const fosa_long_jump_context_t * context, int * jumped)
if (!context && !jumped)
return FOSA_EINVAL;
- *jumped = context -> jmp_hasexecuted? 1:0;
+// printf ("context [6]=%ld\n", (*(context))[6]);
+ *jumped = ((*(context))[6] == LONGJMP_MAGIC);
return 0;
}
{
fosa_long_jump_context_t *jmp_info = (fosa_long_jump_context_t *) info -> si_value.sival_ptr;
-#ifdef CONFIG_LONGJUMP_FREE_SIGNALS
+#ifdef CONFIG_LONGJUMP_FREE_SIGNAL
sigset_t set;
// Restore the signal mask
- pthread_sigmask (SIG_SETMASK, &(context -> jmp_sigmask), NULL);
+// pthread_sigmask (SIG_SETMASK, &(jmp_info -> jmp_sigmask), NULL);
// Free this signal
sigemptyset (&set);
pthread_mutex_unlock (&signal_pool_m);
#endif
+// printf ("\t\t\t\t>>> RESTORE CONTEXT <<<\n\n");
// Restore the saved context
- longjmp (jmp_info -> jmp_context, LONGJMP_MAGIC);
+ fosa_longjmp (*jmp_info, LONGJMP_MAGIC);
return;
}
--- /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.
+//
+//
+// 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
+//
+// This file is part of FOSA (Frsh Operating System Abstraction)
+//
+// 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(Frescor Operating System Adaptation layer)
+//================================================
+*/
+/*
+ * $FILE: fosa_setjmp.S
+ *
+ * Setjmp and Longjmp healper functions
+ */
+
+.text
+
+.global fosa_long_jump_save_context, fosa_longjmp
+.type fosa_long_jump_save_context,@function
+.type fosa_longjmp,@function
+
+fosa_long_jump_save_context:
+ movl 0(%esp), %ecx
+ leal 4(%esp), %edx
+ movl (%edx), %eax
+ movl %ebx, 0(%eax)
+ movl %esi, 4(%eax)
+ movl %edi, 8(%eax)
+ movl %ebp, 12(%eax)
+ movl %edx, 16(%eax)
+ movl %ecx, 20(%eax)
+ movl $0, 24(%eax)
+ movl $0, %eax
+ ret
+
+fosa_longjmp:
+ movl 4(%esp), %ecx
+ movl 8(%esp), %eax
+ movl %eax, 24(%ecx)
+ movl 20(%ecx), %edx
+ movl 0(%ecx), %ebx
+ movl 4(%ecx), %esi
+ movl 8(%ecx), %edi
+ movl 12(%ecx), %ebp
+ movl 16(%ecx), %esp
+ movl $0, %eax
+ jmp *%edx
act.sa_handler = SIG_DFL;
for (i = 0; i < size; i ++) {
- if (FOSA_SIGNAL_MIN > set [i] || set [i] > FOSA_SIGNAL_MAX)
+ if (FOSA_SIGNAL_MIN > set [i] || set [i] > FOSA_SIGNAL_MAX)
return EINVAL;
sigaction (set [i], &act, NULL);
--- /dev/null
+include ../../config.mk
+include ../../rules.mk
+
+SOURCES = $(wildcard *.c)
+NAMES = $(basename $(SOURCES))
+OBJECTS = $(addsuffix .o, $(NAMES))
+TARGETS = $(addsuffix .prtk, $(NAMES))
+
+LD=$(PRTK_PATH)/user/bin/ldkernel -f
+
+%.prtk: %.o libfosa
+ $(LD) -o $@ $< $(FOSA_PATH)/lib/libfosa_$(PLATFORM).a
+
+all: $(TARGETS)
+
--- /dev/null
+
+#include <fosa_long_jump.h>
+#include <fosa_threads_and_signals.h>
+#include <stdio.h>
+
+void f1 (void)
+{
+ fosa_long_jump_context_t ctx;
+ fosa_signal_t sig;
+ fosa_thread_id_t th;
+ int jmp;
+ fosa_signal_info_t ctx_info;
+
+
+ printf (">>> save context\n\n");
+ if (fosa_long_jump_save_context (&ctx))
+ perror ("fosa_long_jump_save_context");
+
+ printf (">>> check jump performed\n\n");
+ if (fosa_long_jump_was_performed ((const fosa_long_jump_context_t *) &ctx, &jmp))
+ perror ("fosa_long_jump_was_performed");
+
+ if (jmp) {
+ printf ("\t <<<< JUMPED\n\n");
+ exit (10);
+ }
+
+ printf (">>> install handler\n\n");
+ if (fosa_long_jump_install_handler (&sig, &th))
+ perror ("fosa_long_jump_install_handler()");
+
+ printf ("\t signal=%d, thread=0x%x (self=0x%x)\n", sig, (unsigned int) th, (unsigned int) fosa_thread_self());
+
+ printf (">>> trigger a long jump using a signal\n\n");
+ ctx_info.sival_ptr = &ctx;
+ if (fosa_signal_queue (sig, ctx_info, th))
+ perror ("fosa_signal_queue");
+
+}
+
+
+int main (void)
+{
+ f1 ();
+ return 0;
+}
+