thread safe longjmp functions.
[kopensolaris-gnu/glibc.git] / linuxthreads / pthread.c
index 994233e..9699b4d 100644 (file)
@@ -166,6 +166,7 @@ static void pthread_initialize(void)
   /* The errno/h_errno variable of the main thread are the global ones.  */
   __pthread_initial_thread.p_errnop = &_errno;
   __pthread_initial_thread.p_h_errnop = &_h_errno;
+#ifdef SIGRTMIN
   /* Allocate the signals used.  */
   __pthread_sig_restart = __libc_allocate_rtsig (1);
   __pthread_sig_cancel = __libc_allocate_rtsig (1);
@@ -176,6 +177,7 @@ static void pthread_initialize(void)
       __pthread_sig_restart = SIGUSR1;
       __pthread_sig_cancel = SIGUSR2;
     }
+#endif
   /* Setup signal handlers for the initial thread.
      Since signal handlers are shared between threads, these settings
      will be inherited by all other threads. */
@@ -234,8 +236,8 @@ static int pthread_initialize_manager(void)
 
 /* Thread creation */
 
-int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
-                   void * (*start_routine)(void *), void *arg)
+int __pthread_create_2_1(pthread_t *thread, const pthread_attr_t *attr,
+                        void * (*start_routine)(void *), void *arg)
 {
   pthread_descr self = thread_self();
   struct pthread_request request;
@@ -255,6 +257,35 @@ int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
   return self->p_retcode;
 }
 
+#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
+default_symbol_version (__pthread_create_2_1, pthread_create, GLIBC_2.1);
+
+int __pthread_create_2_0(pthread_t *thread, const pthread_attr_t *attr,
+                        void * (*start_routine)(void *), void *arg)
+{
+  /* The ATTR attribute is not really of type `pthread_attr_t *'.  It has
+     the old size and access to the new members might crash the program.
+     We convert the struct now.  */
+  pthread_attr_t new_attr;
+
+  if (attr != NULL)
+    {
+      size_t ps = __getpagesize ();
+
+      memcpy (&new_attr, attr, (size_t) &(((pthread_attr_t*)NULL)->guardsize));
+      new_attr.guardsize = ps;
+      new_attr.stackaddr_set = 0;
+      new_attr.stackaddr = NULL;
+      new_attr.stacksize = STACK_SIZE - ps;
+      attr = &new_attr;
+    }
+  return __pthread_create_2_1 (thread, attr, start_routine, arg);
+}
+symbol_version (__pthread_create_2_0, pthread_create, GLIBC_2.0);
+#else
+strong_alias (__pthread_create_2_1, pthread_create)
+#endif
+
 /* Simple operations on thread identifiers */
 
 pthread_t pthread_self(void)
@@ -417,6 +448,23 @@ void __pthread_kill_other_threads_np(void)
 }
 weak_alias (__pthread_kill_other_threads_np, pthread_kill_other_threads_np)
 
+/* Concurrency symbol level.  */
+static int current_level;
+
+int __pthread_setconcurrency(int level)
+{
+  /* We don't do anything unless we have found a useful interpretation.  */
+  current_level = level;
+  return 0;
+}
+weak_alias (__pthread_setconcurrency, pthread_setconcurrency)
+
+int __pthread_getconcurrency(void)
+{
+  return current_level;
+}
+weak_alias (__pthread_getconcurrency, pthread_getconcurrency)
+
 /* Debugging aid */
 
 #ifdef DEBUG