Browse Source

Fix pthreads to use the rt signals if present
-Erik

Eric Andersen 23 years ago
parent
commit
bdcefd6212
2 changed files with 51 additions and 151 deletions
  1. 21 43
      libc/signal/allocrtsig.c
  2. 30 108
      libpthread/linuxthreads/pthread.c

+ 21 - 43
libc/signal/allocrtsig.c

@@ -4,80 +4,58 @@
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
 
    The GNU C Library is free software; you can redistribute it and/or
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
+   modify it under the terms of the GNU Lesser General Public
-   published by the Free Software Foundation; either version 2 of the
+   License as published by the Free Software Foundation; either
-   License, or (at your option) any later version.
+   version 2.1 of the License, or (at your option) any later version.
 
 
    The GNU C Library is distributed in the hope that it will be useful,
    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
+   Lesser General Public License for more details.
 
 
-   You should have received a copy of the GNU Library General Public
+   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   License along with the GNU C Library; if not, write to the Free
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   Boston, MA 02111-1307, USA.  */
+   02111-1307 USA.  */
 
 
 #include <features.h>
 #include <features.h>
 #include <signal.h>
 #include <signal.h>
 #include <sys/types.h>
 #include <sys/types.h>
 #include <sys/syscall.h>
 #include <sys/syscall.h>
-
+ 
-
 /* Only enable rt signals when it is supported at compile time */
 /* Only enable rt signals when it is supported at compile time */
-#ifdef __NR_rt_sigaction
+#ifndef __NR_rt_sigaction
 /* In these variables we keep track of the used variables.  If the
 /* In these variables we keep track of the used variables.  If the
    platform does not support any real-time signals we will define the
    platform does not support any real-time signals we will define the
    values to some unreasonable value which will signal failing of all
    values to some unreasonable value which will signal failing of all
    the functions below.  */
    the functions below.  */
-
+static int current_rtmin = -1;
+static int current_rtmax = -1;
+#else
 static int current_rtmin = __SIGRTMIN;
 static int current_rtmin = __SIGRTMIN;
 static int current_rtmax = __SIGRTMAX;
 static int current_rtmax = __SIGRTMAX;
-
-
-
-#ifdef __UCLIBC_HAS_THREADS__
-/* 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)
-{
-    if (current_rtmin > current_rtmax)
-	/* We don't have anymore signals available.  */
-	return -1;
-
-    return high ? current_rtmin++ : current_rtmax--;
-}
 #endif
 #endif
 
 
 /* Return number of available real-time signal with highest priority.  */
 /* Return number of available real-time signal with highest priority.  */
 int __libc_current_sigrtmin (void)
 int __libc_current_sigrtmin (void)
 {
 {
-    return current_rtmin;
+  return current_rtmin;
 }
 }
 
 
 /* Return number of available real-time signal with lowest priority.  */
 /* Return number of available real-time signal with lowest priority.  */
 int __libc_current_sigrtmax (void)
 int __libc_current_sigrtmax (void)
 {
 {
-    return current_rtmax;
+  return current_rtmax;
 }
 }
 
 
-#else
+/* Allocate real-time signal with highest/lowest available
-
+   priority.  Please note that we don't use a lock since we assume
-#ifdef __UCLIBC_HAS_THREADS__
+   this function to be called at program start.  */
 int __libc_allocate_rtsig (int high)
 int __libc_allocate_rtsig (int high)
 {
 {
+  if (current_rtmin == -1 || current_rtmin > current_rtmax)
+    /* We don't have anymore signal available.  */
     return -1;
     return -1;
-}
-#endif
 
 
-int __libc_current_sigrtmin (void)
+  return high ? current_rtmin++ : current_rtmax--;
-{
-  return -1;
 }
 }
-
-int __libc_current_sigrtmax (void)
-{
-  return -1;
-}
-#endif

+ 30 - 108
libpthread/linuxthreads/pthread.c

@@ -32,11 +32,16 @@
 #include "restart.h"
 #include "restart.h"
 #include "debug.h"      /* added to linuxthreads -StS */
 #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 */
 /* mods for uClibc: getpwd and getpagesize are the syscalls */
 #define __getpid getpid
 #define __getpid getpid
 #define __getpagesize getpagesize
 #define __getpagesize getpagesize
 /* mods for uClibc: __libc_sigaction is not in any standard headers */
 /* 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);
 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_requested = 0;
 int __pthread_exit_code = 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 */
 /* Communicate relevant LinuxThreads constants to gdb */
 
 
 const int __pthread_threads_max = PTHREAD_THREADS_MAX;
 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
    platform does not support any real-time signals we will define the
    values to some unreasonable value which will signal failing of all
    values to some unreasonable value which will signal failing of all
    the functions below.  */
    the functions below.  */
-#ifndef __SIGRTMIN
+#ifdef __NR_rt_sigaction
-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
 int __pthread_sig_restart = __SIGRTMIN;
 int __pthread_sig_restart = __SIGRTMIN;
 int __pthread_sig_cancel = __SIGRTMIN + 1;
 int __pthread_sig_cancel = __SIGRTMIN + 1;
 int __pthread_sig_debug = __SIGRTMIN + 2;
 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
 #else
 int __pthread_sig_restart = SIGUSR1;
 int __pthread_sig_restart = SIGUSR1;
 int __pthread_sig_cancel = SIGUSR2;
 int __pthread_sig_cancel = SIGUSR2;
 int __pthread_sig_debug = 0;
 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
 #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.
 /* Initialize the pthread library.
    Initialization is split in two functions:
    Initialization is split in two functions:
    - a constructor function that blocks the __pthread_sig_restart signal
    - 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);
 	 __pthread_initial_thread_bos, __pthread_initial_thread_tos);
 #endif /* __UCLIBC_HAS_MMU__ */
 #endif /* __UCLIBC_HAS_MMU__ */
 
 
-#ifdef __SIGRTMIN
-  /* Initialize real-time signals. */
-  init_rtsigs ();
-#endif
   /* Setup signal handlers for the initial thread.
   /* Setup signal handlers for the initial thread.
      Since signal handlers are shared between threads, these settings
      Since signal handlers are shared between threads, these settings
      will be inherited by all other threads. */
      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 );
   } 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.
 /* 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.
    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
    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
    queuing semantics. This is needed to resolve a rare race condition in
    pthread_cond_timedwait_relative. */
    pthread_cond_timedwait_relative. */
-
 void __pthread_restart_old(pthread_descr th)
 void __pthread_restart_old(pthread_descr th)
 {
 {
   if (atomic_increment(&th->p_resume_count) == -1)
   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)
   if (atomic_decrement(&self->p_resume_count) <= 0)
     __pthread_wait_for_restart_signal(self);
     __pthread_wait_for_restart_signal(self);
 }
 }
-
+#endif
-void __pthread_restart_new(pthread_descr th)
-{
-    kill(th->p_pid, __pthread_sig_restart);
-}
 
 
 /* There is no __pthread_suspend_new because it would just
 /* There is no __pthread_suspend_new because it would just
    be a wasteful wrapper for __pthread_wait_for_restart_signal */
    be a wasteful wrapper for __pthread_wait_for_restart_signal */