diff -bNru rt_orig/doc/Configure.help rt_with_sig/doc/Configure.help --- rt_orig/doc/Configure.help Thu Jul 26 21:32:42 2001 +++ rt_with_sig/doc/Configure.help Mon Dec 23 13:27:07 2002 @@ -89,3 +89,78 @@ to dramatically reduce scheduling jitter. You need a 2.4.X kernel with CONFIG_SMP enabled for this option to work. +POSIX Signals +_RTL_POSIX_SIGNALS + A POSIX signal is the software equivalent of an interrupt or + exception occurrence. Say Y here if you want to make use of + the POSIX interface to signals. This allows you to send signals + (RTL_SIGUSR1,RTL_SIGUSR2 and from signal RTL_SIGRTMIN to RTL_SIGRTMAX) + to threads (pthread_kill), blocking signals (pthread_sigmask), + suspend a thread waiting for a signal to arrive (sigsuspend) and + install signal handlers, among other things. Signals are in + determinated cases a good interprocess communication mechanism. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -bNru rt_orig/examples/README rt_with_sig/examples/README --- rt_orig/examples/README Thu Jul 26 21:32:42 2001 +++ rt_with_sig/examples/README Mon Dec 23 13:27:07 2002 @@ -1,13 +1,19 @@ -To run the examples, you have to compile and install the main RTLinux modules. -See ../INSTALL. +This version of Open RTLinux is considered stable. It supports both Linux 2.2.x +and Linux 2.4.x kernel series. Please see the RELEASENOTE file to find out +what's new in this version. -examples: +RTLinux is a hard real-time extension to Linux. +More information can be found at http://www.rtlinux.org/ +and http://www.fsmlabs.com/ -hello -- the "Hello World" program -v1api -- RTLinux version 1 API examples -fp -- using floating point in RTLinux -frank -- using FIFOs and periodic scheduling -measurements -- measuring scheduling precision -mutex -- using mutex -sound -- handling interrupts in Real-Time +The installation instructions are in doc/html/Installation/Installation.html +file. The doc/html/GettingStarted document contains a brief intoduction to +RTLinux as well as sources of help and a quick API reference. +If you are upgrading from previous versions of RTL, please read the +file UPGRADING. + +Please send bug reports in to support@fsmlabs.com + +Finite State Machine Labs Inc. (FSMLabs) created and maintains +RTLinux. diff -bNru rt_orig/include/posix/signal.h rt_with_sig/include/posix/signal.h --- rt_orig/include/posix/signal.h Thu Jul 26 21:32:41 2001 +++ rt_with_sig/include/posix/signal.h Mon Dec 23 13:27:07 2002 @@ -7,6 +7,8 @@ * */ +#include + /* * RTLinux signal and the user-level RTLinux signals conflict. * This is ok since users should NOT be making RTLinux calls @@ -38,6 +40,10 @@ #include #endif +//#ifdef _RTL_POSIX_SIGNALS +#include +//#endif + struct rtl_sigaction { union { void (*_sa_handler)(int); @@ -45,6 +51,9 @@ } _u; int sa_flags; unsigned long sa_focus; +#ifdef _RTL_POSIX_SIGNALS + struct rtl_thread_struct *owner; +#endif rtl_sigset_t sa_mask; }; @@ -56,6 +65,13 @@ #define RTL_SIGLOCALIRQMIN 512 #define RTL_SIGIRQMAX 1024 +#ifdef _RTL_POSIX_SIGNALS +// Thread signals comes from 7 to 31. +#define RTL_THREAD_SIGNALS_MASK 0xFFFFFF80 +/* Array of sigactions. Thread signals from (7..31) */ +extern struct sigaction rtl_sigact[RTL_SIGIRQMAX]; +#endif + extern int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); extern int sigprocmask(int how, const rtl_sigset_t *set, rtl_sigset_t *oset); extern int pthread_sigmask(int how, const rtl_sigset_t *set, rtl_sigset_t *oset); @@ -65,4 +81,72 @@ #endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -bNru rt_orig/include/rtl_sched.h rt_with_sig/include/rtl_sched.h --- rt_orig/include/rtl_sched.h Thu Jul 26 21:32:41 2001 +++ rt_with_sig/include/rtl_sched.h Mon Dec 23 13:27:07 2002 @@ -96,7 +96,11 @@ #define RTL_PRIO(th) ((th)->sched_param.sched_priority) -enum {RTL_CANCELPENDING, RTL_CANCELTYPE, RTL_THREAD_JOINABLE, RTL_THREAD_FINISHED, RTL_THREAD_TIMERARMED, RTL_THREAD_WAIT_FOR_JOIN, RTL_THREAD_OK_TO_FINISH_JOIN}; +enum {RTL_CANCELPENDING, RTL_CANCELTYPE, RTL_THREAD_JOINABLE, RTL_THREAD_FINISHED, RTL_THREAD_TIMERARMED, RTL_THREAD_WAIT_FOR_JOIN, RTL_THREAD_OK_TO_FINISH_JOIN +#ifdef _RTL_POSIX_SIGNALS + , RTL_THREAD_SIGNAL_INTERRUMPIBLE +#endif +}; #define RTL_MAX_SIGNAL 31 /* this is max for internal RTLinux signals */ /* these are bit positions */ @@ -107,6 +111,14 @@ #define RTL_SIGNAL_TIMER 5 #define RTL_SIGNAL_READY 6 +#ifdef _RTL_POSIX_SIGNALS +#define RTL_SIGNAL_HANDLER_EXECUTION_INPROGRESS 4 +#define RTL_SIGUSR1 (RTL_SIGNAL_READY+1) +#define RTL_SIGUSR2 (RTL_SIGUSR1+1) +#define RTL_SIGRTMIN (RTL_SIGUSR2+1) +#define RTL_SIGRTMAX RTL_MAX_SIGNAL +#endif + /*TODO How will this work on PPC */ #define RTL_LINUX_MIN_SIGNAL 256 /* signals to Linux start here. global then local */ #define RTL_LINUX_MAX_SIGNAL 1024 @@ -355,6 +367,10 @@ int pthread_kill(pthread_t , int signo); +#ifdef _RTL_POSIX_SIGNALS +#define HIGHER_PRIORITY_THREAD(th1,th2) (RTL_PRIO(th1)>RTL_PRIO(th2)) +#endif + extern inline int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) { attr->detachstate = detachstate; @@ -404,3 +420,71 @@ #endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -bNru rt_orig/include/rtl_signal.h rt_with_sig/include/rtl_signal.h --- rt_orig/include/rtl_signal.h Thu Jul 26 21:32:41 2001 +++ rt_with_sig/include/rtl_signal.h Mon Dec 23 13:27:07 2002 @@ -9,6 +9,11 @@ #define RTL_SIGNAL_TIMER 5 #define RTL_SIGNAL_READY 6 +#define RTL_SIGUSR1 (RTL_SIGNAL_READY+1) +#define RTL_SIGUSR2 (RTL_SIGUSR1+1) +#define RTL_SIGRTMIN (RTL_SIGUSR2+1) +#define RTL_SIGRTMAX RTL_MAX_SIGNAL + /*TODO How will this work on PPC */ #define RTL_LINUX_MIN_SIGNAL 256 /* signals to Linux start here. global then local */ #define RTL_LINUX_MAX_SIGNAL 1024 @@ -20,3 +25,71 @@ #endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -bNru rt_orig/schedulers/rtl_sched.c rt_with_sig/schedulers/rtl_sched.c --- rt_orig/schedulers/rtl_sched.c Thu Jul 26 21:32:41 2001 +++ rt_with_sig/schedulers/rtl_sched.c Mon Dec 23 13:27:07 2002 @@ -13,12 +13,19 @@ * Copyright (C) Finite State Machine Labs Inc., 1998,1999 * Released under the terms of the GNU General Public License Version 2 * + * Added user signals support - Dec, 2002 Josep Vidal (OCERA) + * + * Fixed stack overflow when sending RTL_SIGNAL_SUSPEND signal. J. Vidal (OCERA) + * Fixed mutex bug when setting t->do_abort=0 on do_signal. J. Vidal (OCERA) + * Fixed long long casting in usleep P. Mendoza & J. Vidal (OCERA) + * See example/bug directory for more info. + * Thanks to I.Ripoll, P. Mendoza & P. Perez. */ #include #include #include -#include +#include #include #include #include @@ -148,6 +155,9 @@ return 0; } set_bit(signal, &thread->pending); +#ifdef _RTL_POSIX_SIGNALS + if ((signal >= RTL_SIGUSR1) && HIGHER_PRIORITY_THREAD(thread,pthread_self())) rtl_schedule(); +#endif return 0; } else if(thread != rtl_get_linux_thread(rtl_getcpuid())) { return EINVAL; @@ -267,6 +277,14 @@ rtl_irqstate_t flags; pthread_t self = pthread_self(); +#ifdef _RTL_POSIX_SIGNALS + /* Really necessary to block user signals?*/ + rtl_sigset_t mask; + + clear_bit(RTL_SIGNAL_HANDLER_EXECUTION_INPROGRESS,&self->pending); + rtl_sigfillset(&mask); + pthread_sigmask(SIG_SETMASK,&mask,NULL); +#endif rtl_no_interrupts(flags); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); @@ -275,7 +293,6 @@ set_bit (RTL_THREAD_FINISHED, &self->threadflags); delete_thread(pthread_self()); - rtl_schedule(); /* will never reach this line */ rtl_restore_interrupts(flags); @@ -359,7 +376,7 @@ return preemptor; } -#define do_abort(t) do { clear_bit(RTL_THREAD_TIMERARMED, &t->threadflags); if (t->abort) { t->abort(t->abortdata); }} while (0) +#define do_abort(t) do { clear_bit(RTL_THREAD_TIMERARMED, &t->threadflags); if (t->abort) { t->abort(t->abortdata);}} while (0) static void rtl_posix_cancel(int signal) @@ -375,12 +392,15 @@ static inline void do_signal(pthread_t t) { + rtl_irqstate_t flags; + rtl_no_interrupts(flags); + if (test_and_clear_bit(RTL_SIGNAL_SUSPEND, &t->pending)) { - t->abort = 0; + /* t->abort = 0; t->abortdata = 0; + */ do_abort(t); RTL_MARK_SUSPENDED(t); - rtl_schedule(); } if (test_and_clear_bit(RTL_SIGNAL_WAKEUP, &t->pending)) { @@ -396,10 +416,49 @@ if (!test_bit(RTL_SIGNAL_CANCEL, &t->blocked) && test_and_clear_bit(RTL_SIGNAL_CANCEL, &t->pending)) { RTL_MARK_READY(t); do_abort(t); + rtl_restore_interrupts(flags); (*rtl_sigcancel_handler)(RTL_SIGNAL_CANCEL); } + + rtl_restore_interrupts(flags); } +#ifdef _RTL_POSIX_SIGNALS +static inline void do_user_signal(pthread_t t){ + int sig; + unsigned long flags, initial_interrupt_state; + void (*fun)(int)=NULL; + + rtl_no_interrupts(initial_interrupt_state); + for (sig=RTL_MAX_SIGNAL;sig>=RTL_SIGUSR1;sig--){ + if (test_bit(sig,&t->pending) + && !test_bit(sig,&t->blocked)){ + + if (rtl_sigact[sig].owner==t){ + fun=rtl_sigact[sig].sa_handler; + if (fun) { + // Block signal being managed. + set_bit(sig,&t->blocked); + set_bit(RTL_SIGNAL_HANDLER_EXECUTION_INPROGRESS,&t->pending); + rtl_allow_interrupts(); + fun(sig); + rtl_no_interrupts(flags); + clear_bit(RTL_SIGNAL_HANDLER_EXECUTION_INPROGRESS,&t->pending); + clear_bit(sig,&t->blocked); + + if (test_and_clear_bit(RTL_THREAD_SIGNAL_INTERRUMPIBLE,&t->threadflags)){ + pthread_kill(t,RTL_SIGNAL_WAKEUP); + } + clear_bit (RTL_SCHED_TIMER_OK, &LOCAL_SCHED->sched_flags); + } + } + /* The bit should be pending until unblocked. */ + clear_bit(sig,&t->pending); + } + } + rtl_restore_interrupts(initial_interrupt_state); +} +#endif int rtl_schedule (void) { @@ -412,7 +471,7 @@ hrtime_t now; rtl_sigset_t mask; - rtl_no_interrupts(interrupt_state); +idle: rtl_no_interrupts(interrupt_state); rtl_trace2 (RTL_TRACE_SCHED_IN, (long) pthread_self()); /* new_task = &sched->rtl_linux_task;*/ @@ -454,6 +513,12 @@ } } + if (!new_task) { + rtl_allow_interrupts(); + /* rtl_cprintf ("idle"); */ + goto idle; + } + if (sched->clock->mode == RTL_CLOCK_MODE_ONESHOT && !test_bit (RTL_SCHED_TIMER_OK, &sched->sched_flags)) { if ( (preemptor = find_preemptor(sched,new_task))) { (sched->clock)->settimer(sched->clock, preemptor->resume_time - now); @@ -494,11 +559,20 @@ __restore_flags(flags); }*/ mask = pthread_self()->pending; - + rtl_restore_interrupts(interrupt_state); if (pthread_self()->pending & ~(1 << RTL_SIGNAL_READY)) do_signal(pthread_self()); - rtl_trace2 (RTL_TRACE_SCHED_OUT, (long) pthread_self()); - rtl_restore_interrupts(interrupt_state); +#ifdef _RTL_POSIX_SIGNALS + /* Signal handlers are non re-entrant, i.e. first finish current handler execution + and then manage the rest of pending signals. */ + if (test_bit(RTL_SIGNAL_HANDLER_EXECUTION_INPROGRESS,&pthread_self()->pending)) goto end; + if ((pthread_self()->pending & ~pthread_self()->blocked) & RTL_THREAD_SIGNALS_MASK) do_user_signal(pthread_self()); +#endif + if (!rtl_sigismember(&pthread_self()->pending, RTL_SIGNAL_READY)) { + goto idle; + } + +end: rtl_trace2 (RTL_TRACE_SCHED_OUT, (long) pthread_self()); return mask; } @@ -953,7 +1027,7 @@ save_resume_time = th->resume_time; RTL_MARK_SUSPENDED(th); - __rtl_setup_timeout (th, gethrtime() + interval * 1000); + __rtl_setup_timeout (th, gethrtime() + (long long) interval * 1000LL); rtl_schedule(); pthread_testcancel(); @@ -987,7 +1061,9 @@ } save_resume_time = self->resume_time; - +#ifdef _RTL_POSIX_SIGNALS + set_bit(RTL_THREAD_SIGNAL_INTERRUMPIBLE,&self->threadflags); +#endif RTL_MARK_SUSPENDED(self); __rtl_setup_timeout (self, timeout); ret = rtl_schedule(); @@ -995,6 +1071,9 @@ if (RTL_TIMED_OUT(&ret)) { self->resume_time = save_resume_time; +#ifdef _RTL_POSIX_SIGNALS + clear_bit(RTL_THREAD_SIGNAL_INTERRUMPIBLE,&self->threadflags); +#endif rtl_restore_interrupts (irqstate); return 0; } @@ -1018,3 +1097,71 @@ } return 0; } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -bNru rt_orig/schedulers/rtl_sema.c rt_with_sig/schedulers/rtl_sema.c --- rt_orig/schedulers/rtl_sema.c Thu Jul 26 21:32:42 2001 +++ rt_with_sig/schedulers/rtl_sema.c Mon Dec 23 13:27:07 2002 @@ -62,9 +62,28 @@ rtl_spin_unlock_irqrestore(&sem->lock, flags); return -1; } +#ifdef _RTL_POSIX_SIGNALS + set_bit(RTL_THREAD_SIGNAL_INTERRUMPIBLE,&(pthread_self()->threadflags)); +#endif ret = rtl_wait_sleep (&sem->wait, &sem->lock); pthread_testcancel(); rtl_spin_lock(&sem->lock); + +#ifdef _RTL_POSIX_SIGNALS + /* + Per POSIX standard sem_wait can be interrumped by a signal. + To check if sem_wait exits by a user signal or by sem_post, + what is done is to check the bit RTL_THREAD_SIGNAL_INTERRUMPIBLE. + If it is set implies that no signal has interrumped us. + So do_user_signal cleans it (if set) and puts the thread on ready state, + after executing the signal handler. + */ + if (!test_and_clear_bit(RTL_THREAD_SIGNAL_INTERRUMPIBLE,&(pthread_self()->threadflags))){ + errno=EINTR; + rtl_spin_unlock_irqrestore(&sem->lock, flags); + return -1; + } +#endif } rtl_spin_unlock_irqrestore(&sem->lock, flags); @@ -98,6 +117,9 @@ save_resume_time = self->resume_time; __rtl_setup_timeout(self, timeout); +#ifdef _RTL_POSIX_SIGNALS + set_bit(RTL_THREAD_SIGNAL_INTERRUMPIBLE,&self->threadflags); +#endif ret = rtl_wait_sleep (&sem->wait, &sem->lock); pthread_testcancel(); rtl_spin_lock(&sem->lock); @@ -109,7 +131,12 @@ rtl_spin_unlock_irqrestore(&sem->lock, flags); return -1; } + +#ifdef _RTL_POSIX_SIGNALS + if (!test_and_clear_bit(RTL_THREAD_SIGNAL_INTERRUMPIBLE,&self->threadflags)){ +#else if (RTL_SIGINTR(&ret)) { +#endif errno = EINTR; rtl_spin_unlock_irqrestore(&sem->lock, flags); return -1; @@ -135,4 +162,79 @@ rtl_schedule(); /* make it fast! */ return 0; } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -bNru rt_orig/schedulers/signal.c rt_with_sig/schedulers/signal.c --- rt_orig/schedulers/signal.c Thu Jul 26 21:32:42 2001 +++ rt_with_sig/schedulers/signal.c Mon Dec 23 13:27:07 2002 @@ -1,10 +1,12 @@ -/* + /* * RTLinux signal support * * Written by Michael Barabanov * Copyright (C) Finite State Machine Labs Inc., 2000 * Released under the terms of the GPL Version 2 * + * Added user signals support - Dec, 2002 Josep Vidal (OCERA) + * */ #include @@ -12,7 +14,11 @@ #include #include -static struct sigaction sigact [RTL_SIGIRQMAX]; +/* Thread signals */ /* F. González & J. Vidal */ +/* Array of sigactions. Thread signals from (7..31) */ +struct sigaction rtl_sigact [RTL_SIGIRQMAX]; +/* for compatibility issues */ +#define sigact rtl_sigact unsigned int rtl_sig_interrupt (unsigned int irq, struct pt_regs *regs) { @@ -24,14 +30,22 @@ return 0; } +/* Thread signals added. */ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { +#ifdef _RTL_POSIX_SIGNALS + int flags; +#endif + int irq = -1; if (act && (act->sa_flags & SA_IRQ)) { irq = sig; } else { - /* for now, only hard global interrupts */ - if (sig < RTL_SIGIRQMIN || sig >= RTL_SIGIRQMIN + NR_IRQS) { + /* for now, only hard global interrupts + & thread signals from RTL_SIGNAL_READY+1 to + RTL_MAX_SIGNAL + */ + if (sig <= RTL_SIGNAL_READY || (sig > RTL_MAX_SIGNAL && sig < RTL_SIGIRQMIN) || sig >= RTL_SIGIRQMIN + NR_IRQS) { errno = EINVAL; return -1; } @@ -39,35 +53,217 @@ } if (oact) { *oact = sigact[sig]; + /*hard global interrupts */ + if (sig > RTL_MAX_SIGNAL) rtl_irq_set_affinity(irq, NULL, &oact->sa_focus); } if (!act) { return 0; } + + /*hard global interrupts */ + if (sig > RTL_MAX_SIGNAL){ if (sigact[sig].sa_handler != act->sa_handler) { /* free old irq first if needed */ if (sigact[sig].sa_handler != SIG_IGN && sigact[sig].sa_handler != SIG_DFL) { -/* rtl_printf("freeing %d\n", sig - RTL_SIGIRQMIN); */ + /* rtl_printf("freeing %d\n", sig - RTL_SIGIRQMIN); */ rtl_free_global_irq (irq); } /* now request */ if (act->sa_handler != SIG_IGN && act->sa_handler != SIG_DFL) { sigact[sig] = *act; -/* rtl_printf("requesting %d\n", sig - RTL_SIGIRQMIN); */ + /* rtl_printf("requesting %d\n", sig - RTL_SIGIRQMIN); */ rtl_request_global_irq (irq, rtl_sig_interrupt); } } - if (act->sa_flags & SA_FOCUS) { + if ( act->sa_flags & SA_FOCUS) { rtl_irq_set_affinity (irq, &act->sa_focus, NULL); } + } /*End hard global interrupts */ +#ifdef _RTL_POSIX_SIGNALS + rtl_no_interrupts(flags); +#endif sigact[sig].sa_handler = act->sa_handler; + +#ifdef _RTL_POSIX_SIGNALS + if (sig > RTL_SIGNAL_READY && sig <= RTL_MAX_SIGNAL ){ + if (sigact[sig].sa_handler == SIG_IGN + || sigact[sig].sa_handler == SIG_DFL){ + sigact[sig].sa_handler = NULL; + } + } +#endif sigact[sig].sa_flags = act->sa_flags; sigact[sig].sa_focus = act->sa_focus; sigact[sig].sa_mask = act->sa_mask; +#ifdef _RTL_POSIX_SIGNALS + sigact[sig].owner = pthread_self(); + rtl_restore_interrupts(flags); +#endif + return 0; +} + +#ifdef _RTL_POSIX_SIGNALS +int pthread_sigmask(int how, const rtl_sigset_t *set, rtl_sigset_t *oset){ + pthread_t self=pthread_self(); + int err=0,flags; + + if (oset) *oset=self->blocked; + + if (!set) return EFAULT; + + /* + With pthread_sigmask RTLINUX scheduler signals can't be blocked + or unblocked. For this reason the RTL_THREAD_SIGNALS_MASK is + applied. + */ + + rtl_no_interrupts(flags); + + switch (how){ + case SIG_SETMASK: + self->blocked=( self->blocked & ~RTL_THREAD_SIGNALS_MASK) | + (RTL_THREAD_SIGNALS_MASK & *set); + break; + case SIG_BLOCK: + self->blocked=( self->blocked & ~RTL_THREAD_SIGNALS_MASK) | + (RTL_THREAD_SIGNALS_MASK & (self->blocked | *set)); + break; + case SIG_UNBLOCK: + self->blocked=( self->blocked & ~RTL_THREAD_SIGNALS_MASK) | + (RTL_THREAD_SIGNALS_MASK & (self->blocked & ~(*set))); + break; + default: + rtl_restore_interrupts(flags); + return EINVAL; + } + + rtl_restore_interrupts(flags); + return err; +} + + +int sigsuspend(const rtl_sigset_t *sigmask){ + rtl_sigset_t oset; + int flags; + pthread_t self=pthread_self(); + + if (!sigmask) { + errno=EFAULT; + return -1; + } + + rtl_no_interrupts(flags); + + // Backup old mask. + oset=self->blocked; + + /* + Instaure new. + With pthread_sigmask RTLINUX scheduler signals can't be blocked + or unblocked. + 0 .. 6 from oset, 7 .. 31 to 0 OR + 0 .. 6 to 0, 7 .. 31 from sigmask + */ + self->blocked= (oset & ~RTL_THREAD_SIGNALS_MASK) | (*sigmask & RTL_THREAD_SIGNALS_MASK) ; + // Mark as interrumpible by a signal. + set_bit(RTL_THREAD_SIGNAL_INTERRUMPIBLE,&self->threadflags); + // Suspend calling thread until a signal arrives. + pthread_suspend_np(self); + + // do_user_signal clears the bit RTL_THREAD_SIGNAL_INTERRUMPIBLE from threadflags. + if (!test_and_clear_bit(RTL_THREAD_SIGNAL_INTERRUMPIBLE,&self->threadflags)){ + errno=EINTR; + } + + // Restore thread blocked set. + self->blocked=oset; + rtl_restore_interrupts(flags); + + return -1; +} + +int sigpending(rtl_sigset_t *set){ + if (set){ + *set=pthread_self()->pending; return 0; + } else { + errno=EFAULT; + return -1; + } + } + +#endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -bNru rt_orig/scripts/config.in rt_with_sig/scripts/config.in --- rt_orig/scripts/config.in Thu Jul 26 21:32:41 2001 +++ rt_with_sig/scripts/config.in Mon Dec 23 13:27:07 2002 @@ -38,6 +38,7 @@ # bool 'POSIX Timeouts' _POSIX_TIMEOUTS bool 'Nolinux support (experimental)' CONFIG_RTL_SUSPEND_LINUX bool 'RTLinux tracer support (experimental)' CONFIG_RTL_TRACER +bool 'POSIX Signals' _RTL_POSIX_SIGNALS source main/arch/config.in endmenu @@ -52,3 +53,71 @@ bool 'Shared Memory Driver' CONFIG_MBUFF bool 'Serial Port Driver' CONFIG_RT_COMM endmenu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +