diff options
Diffstat (limited to 'libpthread')
-rw-r--r-- | libpthread/linuxthreads/pthread.c | 138 |
1 files changed, 30 insertions, 108 deletions
diff --git a/libpthread/linuxthreads/pthread.c b/libpthread/linuxthreads/pthread.c index 51d600a18..90c770879 100644 --- a/libpthread/linuxthreads/pthread.c +++ b/libpthread/linuxthreads/pthread.c @@ -32,11 +32,16 @@ #include "restart.h" #include "debug.h" /* added to linuxthreads -StS */ + +/* Mods for uClibc: Some includes */ +#include <signal.h> +#include <sys/types.h> +#include <sys/syscall.h> + /* mods for uClibc: getpwd and getpagesize are the syscalls */ #define __getpid getpid #define __getpagesize getpagesize /* mods for uClibc: __libc_sigaction is not in any standard headers */ -#include <signal.h> extern int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact); @@ -180,12 +185,6 @@ char *__pthread_manager_thread_tos = NULL; int __pthread_exit_requested = 0; int __pthread_exit_code = 0; -/* Pointers that select new or old suspend/resume functions - based on availability of rt signals. */ - -void (*__pthread_restart)(pthread_descr) = __pthread_restart_old; -void (*__pthread_suspend)(pthread_descr) = __pthread_suspend_old; - /* Communicate relevant LinuxThreads constants to gdb */ const int __pthread_threads_max = PTHREAD_THREADS_MAX; @@ -212,106 +211,22 @@ static void pthread_handle_sigdebug(int sig); platform does not support any real-time signals we will define the values to some unreasonable value which will signal failing of all the functions below. */ -#ifndef __SIGRTMIN -static int current_rtmin = -1; -static int current_rtmax = -1; -int __pthread_sig_restart = SIGUSR1; -int __pthread_sig_cancel = SIGUSR2; -int __pthread_sig_debug = 0; -#else -static int current_rtmin; -static int current_rtmax; - -#if __SIGRTMAX - __SIGRTMIN >= 3 +#ifdef __NR_rt_sigaction int __pthread_sig_restart = __SIGRTMIN; int __pthread_sig_cancel = __SIGRTMIN + 1; int __pthread_sig_debug = __SIGRTMIN + 2; +void (*__pthread_restart)(pthread_descr) = __pthread_restart_new; +void (*__pthread_suspend)(pthread_descr) = __pthread_wait_for_restart_signal; #else int __pthread_sig_restart = SIGUSR1; int __pthread_sig_cancel = SIGUSR2; int __pthread_sig_debug = 0; +/* Pointers that select new or old suspend/resume functions + based on availability of rt signals. */ +void (*__pthread_restart)(pthread_descr) = __pthread_restart_old; +void (*__pthread_suspend)(pthread_descr) = __pthread_suspend_old; #endif -static int rtsigs_initialized; - -#include "testrtsig.h" - -static void -init_rtsigs (void) -{ - if (!kernel_has_rtsig ()) - { - current_rtmin = -1; - current_rtmax = -1; -#if __SIGRTMAX - __SIGRTMIN >= 3 - __pthread_sig_restart = SIGUSR1; - __pthread_sig_cancel = SIGUSR2; - __pthread_sig_debug = 0; -#endif -PDEBUG("no rt-sigs, sig_restart=%d, sig_cancel=%d.\n", __pthread_sig_restart, __pthread_sig_cancel ); - __pthread_init_condvar(0); - } - else - { -#if __SIGRTMAX - __SIGRTMIN >= 3 - current_rtmin = __SIGRTMIN + 3; - __pthread_restart = __pthread_restart_new; - __pthread_suspend = __pthread_wait_for_restart_signal; - __pthread_init_condvar(1); -#else - current_rtmin = __SIGRTMIN; - __pthread_init_condvar(0); -#endif - - current_rtmax = __SIGRTMAX; -PDEBUG("have rt-sigs, rtmin = %d, rtmax = %d.\n", current_rtmin, current_rtmax); - } - - rtsigs_initialized = 1; -} -#endif - -/* Return number of available real-time signal with highest priority. */ -int -__libc_current_sigrtmin (void) -{ -#ifdef __SIGRTMIN - if (!rtsigs_initialized) - init_rtsigs (); -#endif - return current_rtmin; -} - -/* Return number of available real-time signal with lowest priority. */ -int -__libc_current_sigrtmax (void) -{ -#ifdef __SIGRTMIN - if (!rtsigs_initialized) - init_rtsigs (); -#endif - return current_rtmax; -} - -/* Allocate real-time signal with highest/lowest available - priority. Please note that we don't use a lock since we assume - this function to be called at program start. */ -int -__libc_allocate_rtsig (int high) -{ -#ifndef __SIGRTMIN - return -1; -#else - if (!rtsigs_initialized) - init_rtsigs (); - if (current_rtmin == -1 || current_rtmin > current_rtmax) - /* We don't have anymore signal available. */ - return -1; - - return high ? current_rtmin++ : current_rtmax--; -#endif -} - /* Initialize the pthread library. Initialization is split in two functions: - a constructor function that blocks the __pthread_sig_restart signal @@ -374,10 +289,6 @@ static void pthread_initialize(void) __pthread_initial_thread_bos, __pthread_initial_thread_tos); #endif /* __UCLIBC_HAS_MMU__ */ -#ifdef __SIGRTMIN - /* Initialize real-time signals. */ - init_rtsigs (); -#endif /* Setup signal handlers for the initial thread. Since signal handlers are shared between threads, these settings will be inherited by all other threads. */ @@ -822,12 +733,27 @@ void __pthread_wait_for_restart_signal(pthread_descr self) } while (self->p_signal !=__pthread_sig_restart ); } +#ifdef __NR_rt_sigaction +void __pthread_restart_new(pthread_descr th) +{ + kill(th->p_pid, __pthread_sig_restart); +} + +/* There is no __pthread_suspend_new because it would just + be a wasteful wrapper for __pthread_wait_for_restart_signal */ +#if 0 +void __pthread_suspend_new(pthread_descr th) +{ + __pthread_wait_for_restart_signal(th); +} +#endif + +#else /* The _old variants are for 2.0 and early 2.1 kernels which don't have RT signals. On these kernels, we use SIGUSR1 and SIGUSR2 for restart and cancellation. Since the restart signal does not queue, we use an atomic counter to create queuing semantics. This is needed to resolve a rare race condition in pthread_cond_timedwait_relative. */ - void __pthread_restart_old(pthread_descr th) { if (atomic_increment(&th->p_resume_count) == -1) @@ -839,11 +765,7 @@ void __pthread_suspend_old(pthread_descr self) if (atomic_decrement(&self->p_resume_count) <= 0) __pthread_wait_for_restart_signal(self); } - -void __pthread_restart_new(pthread_descr th) -{ - kill(th->p_pid, __pthread_sig_restart); -} +#endif /* There is no __pthread_suspend_new because it would just be a wasteful wrapper for __pthread_wait_for_restart_signal */ |