[git commit master] uClibc_main: add the needed support for nptl

Austin Foxley austinf at cetoncorp.com
Fri Apr 23 14:31:55 UTC 2010


commit: http://git.uclibc.org/uClibc/commit/?id=d2b282faa6fef368680cf1cb96bad562f082ce03
branch: http://git.uclibc.org/uClibc/commit/?id=refs/heads/master

 * setup memory for the cancellation buffer
 * remove unneeded weak's
 * deallocation of tsd on main thread exit

Signed-off-by: Austin Foxley <austinf at cetoncorp.com>
---
 libc/misc/internals/__uClibc_main.c |  109 ++++++++++++++++++++++++-----------
 1 files changed, 75 insertions(+), 34 deletions(-)

diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c
index b166aaa..be63fe4 100644
--- a/libc/misc/internals/__uClibc_main.c
+++ b/libc/misc/internals/__uClibc_main.c
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) Feb 2001 Manuel Novoa III
+ * Copyright (C) 2006 by Steven J. Hill <sjhill at realitydiluted.com>
+ * Copyright (C) 2001 by Manuel Novoa III <mjn3 at uclibc.org>
  * Copyright (C) 2000-2005 Erik Andersen <andersen at uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
@@ -13,8 +14,10 @@
  * avoided in the static library case.
  */
 
-#define	_ERRNO_H
 #include <features.h>
+#ifndef __UCLIBC_HAS_THREADS_NATIVE__
+#define	_ERRNO_H
+#endif
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
@@ -22,10 +25,17 @@
 #include <link.h>
 #include <bits/uClibc_page.h>
 #include <paths.h>
+#include <unistd.h>
 #include <asm/errno.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/sysmacros.h>
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+#include <errno.h>
+#include <pthread-functions.h>
+#include <not-cancel.h>
+#include <atomic.h>
+#endif
 
 
 #ifndef SHARED
@@ -56,7 +66,7 @@ uintptr_t __guard attribute_relro;
 /*
  * Needed to initialize _dl_phdr when statically linked
  */
-
+ 
 void internal_function _dl_aux_init (ElfW(auxv_t) *av);
 #endif /* !SHARED */
 
@@ -64,16 +74,17 @@ void internal_function _dl_aux_init (ElfW(auxv_t) *av);
  * Prototypes.
  */
 extern int *weak_const_function __errno_location(void);
-libc_hidden_proto(__errno_location)
 extern int *weak_const_function __h_errno_location(void);
-libc_hidden_proto(__h_errno_location)
-
 extern void weak_function _stdio_init(void) attribute_hidden;
 #ifdef __UCLIBC_HAS_LOCALE__
 extern void weak_function _locale_init(void) attribute_hidden;
 #endif
 #ifdef __UCLIBC_HAS_THREADS__
+#if !defined (__UCLIBC_HAS_THREADS_NATIVE__) || defined (SHARED)
 extern void weak_function __pthread_initialize_minimal(void);
+#else
+extern void __pthread_initialize_minimal(void);
+#endif
 #endif
 
 /* If __UCLIBC_FORMAT_SHARED_FLAT__, all array initialisation and finalisation
@@ -126,7 +137,7 @@ static void __check_one_fd(int fd, int mode)
 	int nullfd = open(_PATH_DEVNULL, mode);
 	/* /dev/null is major=1 minor=3.  Make absolutely certain
 	 * that is in fact the device that we have opened and not
-	 * some other weird file... [removed in uclibc] */
+	 * some other wierd file... [removed in uclibc] */
 	if (nullfd!=fd)
 	{
 		abort();
@@ -183,7 +194,9 @@ void __uClibc_init(void)
      * __pthread_initialize_minimal so we can use pthread_locks
      * whenever they are needed.
      */
+#if !defined (__UCLIBC_HAS_THREADS_NATIVE__) || defined (SHARED)
     if (likely(__pthread_initialize_minimal!=NULL))
+#endif
 	__pthread_initialize_minimal();
 #endif
 
@@ -267,6 +280,11 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
     ElfW(auxv_t) auxvt[AT_EGID + 1];
 #endif
 
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+	/* Result of the 'main' function.  */
+	int result;
+#endif
+
 #ifndef SHARED
     __libc_stack_end = stack_end;
 #endif
@@ -386,34 +404,57 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
     if (likely(__h_errno_location!=NULL))
 	*(__h_errno_location()) = 0;
 
-    /*
-     * Finally, invoke application's main and then exit.
-     */
-    exit(main(argc, argv, __environ));
-}
+#if defined HAVE_CLEANUP_JMP_BUF && defined __UCLIBC_HAS_THREADS_NATIVE__
+	/* Memory for the cancellation buffer.  */
+	struct pthread_unwind_buf unwind_buf;
 
-#if defined(__UCLIBC_HAS_THREADS__) && !defined(SHARED)
-/* Weaks for internal library use only.
- *
- * We need to define weaks here to cover all the pthread functions that
- * libc itself will use so that we aren't forced to link libc against
- * libpthread.  This file is only used in libc.a and since we have
- * weaks here, they will be automatically overridden by libpthread.a
- * if it gets linked in.
- */
+	int not_first_call;
+	not_first_call =
+		setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf);
+	if (__builtin_expect (! not_first_call, 1))
+	{
+		struct pthread *self = THREAD_SELF;
+
+		/* Store old info.  */
+		unwind_buf.priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf);
+		unwind_buf.priv.data.cleanup = THREAD_GETMEM (self, cleanup);
+
+		/* Store the new cleanup handler info.  */
+		THREAD_SETMEM (self, cleanup_jmp_buf, &unwind_buf);
 
-static int __pthread_return_0 (void) { return 0; }
-static void __pthread_return_void (void) { return; }
-
-weak_alias (__pthread_return_0, __pthread_mutex_init)
-weak_alias (__pthread_return_0, __pthread_mutex_lock)
-weak_alias (__pthread_return_0, __pthread_mutex_trylock)
-weak_alias (__pthread_return_0, __pthread_mutex_unlock)
-weak_alias (__pthread_return_void, _pthread_cleanup_push_defer)
-weak_alias (__pthread_return_void, _pthread_cleanup_pop_restore)
-# ifdef __UCLIBC_HAS_THREADS_NATIVE__
-weak_alias (__pthread_return_0, __pthread_mutexattr_init)
-weak_alias (__pthread_return_0, __pthread_mutexattr_destroy)
-weak_alias (__pthread_return_0, __pthread_mutexattr_settype)
+		/* Run the program.  */
+		result = main (argc, argv, __environ);
+	}
+	else
+	{
+		/* Remove the thread-local data.  */
+# ifdef SHARED
+		__libc_pthread_functions.ptr__nptl_deallocate_tsd ();
+# else
+		extern void __nptl_deallocate_tsd (void) __attribute ((weak));
+		__nptl_deallocate_tsd ();
 # endif
+
+		/* One less thread.  Decrement the counter.  If it is zero we
+		   terminate the entire process.  */
+		result = 0;
+# ifdef SHARED
+		unsigned int *const ptr = __libc_pthread_functions.ptr_nthreads;
+# else
+		extern unsigned int __nptl_nthreads __attribute ((weak));
+		unsigned int *const ptr = &__nptl_nthreads;
+# endif
+
+		if (! atomic_decrement_and_test (ptr))
+			/* Not much left to do but to exit the thread, not the process.  */
+			__exit_thread_inline (0);
+	}
+
+	exit (result);
+#else
+	/*
+	 * Finally, invoke application's main and then exit.
+	 */
+	exit (main (argc, argv, __environ));
 #endif
+}
-- 
1.6.3.3



More information about the uClibc-cvs mailing list