This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFA: generic threads support


Mark Mitchell wrote:

You also need documentation for this feature, discussing both the new
configure switch, and what you have to do to replace the generic
functions, and what the semantics of those functions are, so that people
know how to replace them.



I've put the description of the functions as comments into gthr-generic.c and
gthr-objc-generic.c, with a pointer in install.texi.
I've followed the current gthread implementations on which functions
can only return 0 or -1, and which can return 0 or nonzero, although
I have to say it looks a bit idiosyncratic.

During the process of documenting the functions, I've found that
__gthread_key_dtor is obsolete, so I removed the definition.

Regression tested on i686-pc-linux-gnu X sh-elf, with and without
--enable-threads=gthreads.
nm on libgcc.a shows that the list of symbols is unchanged compared to
the baseline without --enable-threads=gthreads, but with this option, the
expected new symbols are present.

2006-04-06  Antony King <antony.king@st.com>
	    J"orn Rennecke <joern.rennecke@st.com>

	* configure.ac: Recognize 'generic' value for threads.
	Check for existance of a *.c and gthr-objc-*.c file for thread support.
	Substiture in extra_libgcc_srcs.
	* configure: Regenerate.
	* Makefile.in (LIB2ADD): Add @extra_libgcc_srcs@.
	* gthr-generic.h: New file.
	* gthr-generic.c: New file.
	* gthr-objc-generic.c: New file.
	* doc/install.texi: Document --enable-threads=generic

Index: doc/install.texi
===================================================================
/usr/bin/diff -p -d -F^( -u -L doc/install.texi	(revision 112638) -L doc/install.texi	(working copy) doc/.svn/text-base/install.texi.svn-base doc/install.texi
--- doc/install.texi	(revision 112638)
+++ doc/install.texi	(working copy)
@@ -935,6 +935,21 @@ like C++ and Java.  The possibilities fo
 AIX thread support.
 @item dce
 DCE thread support.
+@item generic
+Generic thread support.  All the thread interface primitives used by the
+libgcc/libobjc/libstdc++ will be provided as out-of-line weak stub functions
+with the same functionality as you get with @option{--enable-threads=single}.
+This is useful when you want to build a toolchain that has, and can be
+used to compile, thread-agnostic libraries, so that a single toolchain
+can support multiple OS environments for the same processor.
+Without adding further object files / libraries, this toolchain can
+compile and link objects that can run on a target without a threading
+system.
+You can also support a threaded environment by linking in an additional
+object / library which replaces some or all of the functions defined in
+@file{gthr-generic.c} / @file{gthr-objc-generic.c} with functions that
+match the intended target environment.  The data type definitions are
+at the start of @file{gthr-generic.h}.
 @item gnat
 Ada tasking support.  For non-Ada programs, this setting is equivalent
 to @samp{single}.  When used in conjunction with the Ada run time, it
Index: gthr-objc-generic.c
===================================================================
/usr/bin/diff -p -d -F^( -u -L gthr-objc-generic.c	(revision 0) -L gthr-objc-generic.c	(revision 0) .svn/empty-file gthr-objc-generic.c
--- gthr-objc-generic.c	(revision 0)
+++ gthr-objc-generic.c	(revision 0)
@@ -0,0 +1,220 @@
+/* Threads compatibility routines for libobjc.  */
+/* Compile this one with gcc.  */
+/* Copyright (C) 1997, 1999, 2000, 2006 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself cause the resulting executable
+   to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.  */
+
+#include "tconfig.h"
+
+#define __GTHR_WEAK __attribute__ ((weak))
+#define _LIBOBJC
+
+/* ??? The objc thread types are defined in ../libobjc/objc/thr.h,
+   but we don't want the gcc core to depend on libobjc.  */
+typedef void * objc_thread_t;
+typedef struct objc_mutex *objc_mutex_t;
+typedef struct objc_condition *objc_condition_t;
+#define OBJC_THREAD_INTERACTIVE_PRIORITY        2
+
+#include "gthr.h"
+
+#define UNUSED(x) x ATTRIBUTE_UNUSED
+
+/* Just provide compatibility for mutex handling.  */
+
+/* Thread local storage for a single thread */
+static void *thread_local_storage = 0;
+
+/* Backend initialization functions */
+
+/* Initialize the threads subsystem.  */
+int
+__generic_gxx_objc_init_thread_system (void)
+{
+  /* No thread support available */
+  return -1;
+}
+
+/* Close the threads subsystem.  */
+int
+__generic_gxx_objc_close_thread_system (void)
+{
+  /* No thread support available */
+  return -1;
+}
+
+/* Backend thread functions */
+
+/* Create a new thread of execution.  The thread starts executing by calling
+   FUNC with ARG as its only argument.
+   On success, a handle for the new thread is returned.
+   On failure, zero is returned.  */
+objc_thread_t
+__generic_gxx_objc_thread_detach (void UNUSED ((* func)(void *)),
+				  void * UNUSED(arg))
+{
+  /* No thread support available */
+  return 0;
+}
+
+/* Set the current thread's priority.  */
+int
+__generic_gxx_objc_thread_set_priority (int UNUSED(priority))
+{
+  /* No thread support available */
+  return -1;
+}
+
+/* Return the current thread's priority.  */
+int
+__generic_gxx_objc_thread_get_priority (void)
+{
+  return OBJC_THREAD_INTERACTIVE_PRIORITY;
+}
+
+/* Yield our process time to another thread.  */
+void
+__generic_gxx_objc_thread_yield (void)
+{
+  return;
+}
+
+/* Terminate the current thread.  */
+int
+__generic_gxx_objc_thread_exit (void)
+{
+  /* No thread support available */
+  /* Should we really exit the program */
+  /* exit (&__objc_thread_exit_status); */
+  return -1;
+}
+
+/* Returns an integer value which uniquely describes a thread.  */
+objc_thread_t
+__generic_gxx_objc_thread_id (void)
+{
+  /* No thread support, use 1.  */
+  return (objc_thread_t) 1;
+}
+
+/* Sets the thread's objc local storage pointer.  */
+int
+__generic_gxx_objc_thread_set_data (void *value)
+{
+  thread_local_storage = value;
+  return 0;
+}
+
+/* Returns the thread's objc local storage pointer.  */
+void *
+__generic_gxx_objc_thread_get_data (void)
+{
+  return thread_local_storage;
+}
+
+/* Backend mutex functions */
+
+/* Allocate a backend-specific mutex data in MUTEX->backend.  
+   Return 0 on success, -1 for failure.  */
+int
+__generic_gxx_objc_mutex_allocate (objc_mutex_t UNUSED(mutex))
+{
+  return 0;
+}
+
+/* Deallocate backend-specific mutex data in MUTEX->backend.
+   Return 0 on success, -1 for failure.  */
+int
+__generic_gxx_objc_mutex_deallocate (objc_mutex_t UNUSED(mutex))
+{
+  return 0;
+}
+
+/* Grab a lock on MUTEX.  Return 0 on success.  */
+int
+__generic_gxx_objc_mutex_lock (objc_mutex_t UNUSED(mutex))
+{
+  /* There can only be one thread, so we always get the lock */
+  return 0;
+}
+
+/* Try to grab a lock on MUTEX.  Return 0 on success.  */
+int
+__generic_gxx_objc_mutex_trylock (objc_mutex_t UNUSED(mutex))
+{
+  /* There can only be one thread, so we always get the lock */
+  return 0;
+}
+
+/* Unlock MUTEX.  Return 0 on success.  */
+int
+__generic_gxx_objc_mutex_unlock (objc_mutex_t UNUSED(mutex))
+{
+  return 0;
+}
+
+/* Backend condition mutex functions */
+
+/* Allocate backend-specific condition data in CONDITION->backend.
+   Return 0 on success, -1 for failure.  */
+int
+__generic_gxx_objc_condition_allocate (objc_condition_t UNUSED(condition))
+{
+  return 0;
+}
+
+/* Deallocate backend-specific condition data in CONDITION->backend.
+   Return 0 for success.  */
+int
+__generic_gxx_objc_condition_deallocate (objc_condition_t UNUSED(condition))
+{
+  return 0;
+}
+
+/* MUTEX is a locked mutex.  Atomically release MUTEX and wait on
+   CONDITION, i.e. so that no other thread can observe a state after
+   the release of MUTEX but before this thread has blocked.
+   Then re-acquire a lock on MUTEX.
+   Return 0 on success.  */
+int
+__generic_gxx_objc_condition_wait (objc_condition_t UNUSED(condition),
+				   objc_mutex_t UNUSED(mutex))
+{
+  return 0;
+}
+
+/* Wake up all threads waiting on CONDITION.  Return 0 on success.  */
+int
+__generic_gxx_objc_condition_broadcast (objc_condition_t UNUSED(condition))
+{
+  return 0;
+}
+
+/* Wake up one thread waiting on CONDITION.  Return 0 on success.  */
+int
+__generic_gxx_objc_condition_signal (objc_condition_t UNUSED(condition))
+{
+  return 0;
+}
Index: configure.ac
===================================================================
/usr/bin/diff -p -d -F^( -u -L configure.ac	(revision 112638) -L configure.ac	(working copy) .svn/text-base/configure.ac.svn-base configure.ac
--- configure.ac	(revision 112638)
+++ configure.ac	(working copy)
@@ -1352,7 +1352,7 @@ case ${enable_threads} in
     target_thread_file='single'
     ;;
   aix | dce | gnat | irix | posix | posix95 | rtems | \
-  single | solaris | vxworks | win32 )
+  single | solaris | vxworks | win32 | generic)
     target_thread_file=${enable_threads}
     ;;
   *)
@@ -1373,6 +1373,14 @@ if test $thread_file != single; then
   rm -f gthr-default.h
   echo "#include \"gthr-${thread_file}.h\"" > gthr-default.h
   gthread_flags=-DHAVE_GTHR_DEFAULT
+  if test $thread_file != posix; then
+    if test -f $srcdir/gthr-${thread_file}.c; then
+      extra_libgcc_srcs=$srcdir/gthr-${thread_file}.c
+    fi
+    if test -f $srcdir/gthr-objc-${thread_file}.c; then
+      extra_libgcc_srcs="${extra_libgcc_srcs} $srcdir/gthr-objc-${thread_file}.c"
+    fi
+  fi
 fi
 AC_SUBST(gthread_flags)
 
@@ -3514,6 +3522,7 @@ AC_SUBST(xmake_file)
 AC_SUBST(tmake_file)
 AC_SUBST(extra_gcc_objs)
 AC_SUBST(extra_headers_list)
+AC_SUBST(extra_libgcc_srcs)
 AC_SUBST(extra_objs)
 AC_SUBST(extra_parts)
 AC_SUBST(extra_passes)
Index: gthr-generic.c
===================================================================
/usr/bin/diff -p -d -F^( -u -L gthr-generic.c	(revision 0) -L gthr-generic.c	(revision 0) .svn/empty-file gthr-generic.c
--- gthr-generic.c	(revision 0)
+++ gthr-generic.c	(revision 0)
@@ -0,0 +1,169 @@
+/* Generic threads supplementary implementation. */
+/* Compile this one with gcc.  */
+/* Copyright (C) 1997, 1999, 2000, 2002, 2006 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself cause the resulting executable
+   to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.  */
+
+#define __GTHR_WEAK __attribute__ ((weak))
+
+#include "tconfig.h"
+#include "gthr.h"
+
+#ifndef __gthr_generic_h
+#error "Generic thread support package not supported"
+#endif
+
+/* These are stub functions.  When threading is available, a suitable set of definitions should be linked in.  */
+
+/* Return 1 if thread system is active, 0 if not.  */
+int
+__generic_gxx_active_p (void)
+{
+  return 0;
+}
+
+/* The following functions should return zero on success or the error
+   number.  If the operation is not supported, -1 is returned.
+
+   __generic_gxx_once
+   __generic_gxx_key_create
+   __generic_gxx_key_delete
+   __generic_gxx_setspecific
+   __generic_gxx_mutex_lock
+   __generic_gxx_mutex_trylock
+   __generic_gxx_mutex_unlock
+   __generic_gxx_recursive_mutex_lock
+   __generic_gxx_recursive_mutex_trylock
+   __generic_gxx_recursive_mutex_unlock  */
+
+/* FUNC is a function that should be called without parameters.
+   *ONCE has been initialized to __GTHREAD_ONCE_INIT and is otherwise only
+   used in calls to __generic_gxx_once with FUNC as the second parameter.
+   If __generic_gxx_once succeeds, FUNC will have been called exactly once
+   since the initialization of ONCE through any number of calls of
+   __generic_gxx_once with this pair of ONCE and FUNC values.  */
+int
+__generic_gxx_once (__gthread_once_t *once ATTRIBUTE_UNUSED,
+		    void (*func)(void) ATTRIBUTE_UNUSED)
+{
+  return -1;
+}
+
+/* Assign a key to *KEY that can be used in calls to
+   __generic_gxx_setspecific / __generic_gxx_getspecific.
+   If DTOR is nonzero, and at thread exit the value associated with the key
+   is nonzero, DTOR will be called at thread exit with the value associated
+   with the key as its only argument.  */
+int
+__generic_gxx_key_create (__gthread_key_t *key ATTRIBUTE_UNUSED,
+			  void (*dtor)(void *) ATTRIBUTE_UNUSED)
+{
+  return -1;
+}
+
+/* KEY is a key previously allocated by __generic_gxx_key_create.
+   Remove it from the set of keys known for this thread.  */
+int
+__generic_gxx_key_delete (__gthread_key_t key ATTRIBUTE_UNUSED)
+{
+  return -1;
+}
+
+/* Return thread-specific data associated with KEY.  */
+void *
+__generic_gxx_getspecific (__gthread_key_t key ATTRIBUTE_UNUSED)
+{
+  return 0;
+}
+
+/* Set thread-specific data associated with KEY to PTR.  */
+int
+__generic_gxx_setspecific (__gthread_key_t key ATTRIBUTE_UNUSED,
+		      const void *ptr ATTRIBUTE_UNUSED)
+{
+  return -1;
+}
+
+/* Initialize *MUTEX.  */
+void
+__generic_gxx_mutex_init_function (__gthread_mutex_t *mutex ATTRIBUTE_UNUSED)
+{
+}
+
+/* Acquire a lock on *MUTEX.  The behaviour is undefined if a lock on *MUTEX
+   has already been acquired by the same thread.  */
+int
+__generic_gxx_mutex_lock (__gthread_mutex_t *mutex ATTRIBUTE_UNUSED)
+{
+  return 0;
+}
+
+/* Try to acquire a lock on *MUTEX.  If a lock on *MUTEX already exists,
+   return an error code.  */
+int
+__generic_gxx_mutex_trylock (__gthread_mutex_t *mutex ATTRIBUTE_UNUSED)
+{
+  return 0;
+}
+
+/* A lock on *MUTEX has previously been acquired with __generic_gxx_mutex_lock
+   or __generic_gxx_mutex_trylock.  Release the lock.  */
+int
+__generic_gxx_mutex_unlock (__gthread_mutex_t *mutex ATTRIBUTE_UNUSED)
+{
+  return 0;
+}
+
+/* Initialize *MUTEX.  */
+void
+__generic_gxx_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex ATTRIBUTE_UNUSED)
+{
+}
+
+/* Acquire a lock on *MUTEX.  If a lock on *MUTEX has already been acquired by
+   the same thread, succeed.  */
+int
+__generic_gxx_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex ATTRIBUTE_UNUSED)
+{
+  return 0;
+}
+
+/* Try to acquire a lock on *MUTEX.  If a lock on *MUTEX has already been
+   acquired by the same thread, succeed.  If any other lock on *MUTEX
+   already exists, return an error code.  */
+int
+__generic_gxx_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex ATTRIBUTE_UNUSED)
+{
+  return 0;
+}
+
+/* A lock on *MUTEX has previously been acquired with
+   __generic_gxx_recursive_mutex_lock or
+   __generic_gxx_recursive_mutex_trylock.  Release the lock.  */
+int
+__generic_gxx_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex ATTRIBUTE_UNUSED)
+{
+  return 0;
+}
Index: gthr-generic.h
===================================================================
/usr/bin/diff -p -d -F^( -u -L gthr-generic.h	(revision 0) -L gthr-generic.h	(revision 0) .svn/empty-file gthr-generic.h
--- gthr-generic.h	(revision 0)
+++ gthr-generic.h	(revision 0)
@@ -0,0 +1,371 @@
+/* Generic threads compatibility routines for libgcc2 and libobjc. */
+/* Compile this one with gcc.  */
+/* Copyright (C) 1997, 1999, 2000, 2002, 2006 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+/* As a special exception, if you link this library with other files,
+   some of which are compiled with GCC, to produce an executable,
+   this library does not by itself cause the resulting executable
+   to be covered by the GNU General Public License.
+   This exception does not however invalidate any other reasons why
+   the executable file might be covered by the GNU General Public License.  */
+
+#ifndef __gthr_generic_h
+#define __gthr_generic_h
+
+#define __GTHREADS 1
+
+#define __GTHREAD_ONCE_INIT 0
+#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
+#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Avoid depedency on specific headers.
+   The general idea is that you dynamically allocate the required data
+   structures, and a void * is used to point to this dynamically allocated
+   data.  If your implementation can put all the required information in
+   the void * itself, that's fine, too, of course.
+   libstdc++ inherits from the mutex types, whcih is why they need to be
+   wrapped up as structs.  */
+typedef void *__gthread_key_t;
+typedef void *__gthread_once_t;
+typedef struct __gthread_mutex_s { void *p; } __gthread_mutex_t;
+typedef struct __gthread_recursive_mutex_s { void *p; } __gthread_recursive_mutex_t;
+
+/* We should always link with at least one definition, so we want strong
+   references.  The stub definitions are weak so that they can be overriden.  */
+#ifndef __GTHR_WEAK
+#define __GTHR_WEAK
+#endif
+
+extern int __generic_gxx_active_p (void) __GTHR_WEAK;
+
+extern int __generic_gxx_once (__gthread_once_t *, void (*)(void)) __GTHR_WEAK;
+
+extern int __generic_gxx_key_create (__gthread_key_t *,
+				     void (*)(void *)) __GTHR_WEAK;
+
+extern int __generic_gxx_key_delete (__gthread_key_t key) __GTHR_WEAK;
+
+extern void *__generic_gxx_getspecific (__gthread_key_t key) __GTHR_WEAK;
+
+extern int __generic_gxx_setspecific (__gthread_key_t, const void *) __GTHR_WEAK;
+
+extern void __generic_gxx_mutex_init_function (__gthread_mutex_t *) __GTHR_WEAK;
+
+extern int __generic_gxx_mutex_lock (__gthread_mutex_t *) __GTHR_WEAK;
+
+extern int __generic_gxx_mutex_trylock (__gthread_mutex_t *) __GTHR_WEAK;
+
+extern int __generic_gxx_mutex_unlock (__gthread_mutex_t *) __GTHR_WEAK;
+
+extern void __generic_gxx_recursive_mutex_init_function (__gthread_recursive_mutex_t *) __GTHR_WEAK;
+
+extern int __generic_gxx_recursive_mutex_lock (__gthread_recursive_mutex_t *) __GTHR_WEAK;
+
+extern int __generic_gxx_recursive_mutex_trylock (__gthread_recursive_mutex_t *) __GTHR_WEAK;
+
+extern int __generic_gxx_recursive_mutex_unlock (__gthread_recursive_mutex_t *) __GTHR_WEAK;
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef _LIBOBJC
+
+extern int __generic_gxx_objc_init_thread_system (void) __GTHR_WEAK;
+
+extern int __generic_gxx_objc_close_thread_system (void) __GTHR_WEAK;
+
+extern objc_thread_t __generic_gxx_objc_thread_detach (void (*)(void *), void *) __GTHR_WEAK;
+
+extern int __generic_gxx_objc_thread_set_priority (int priority) __GTHR_WEAK;
+
+extern int __generic_gxx_objc_thread_get_priority (void) __GTHR_WEAK;
+
+extern void __generic_gxx_objc_thread_yield (void) __GTHR_WEAK;
+
+extern int __generic_gxx_objc_thread_exit (void) __GTHR_WEAK;
+
+extern objc_thread_t __generic_gxx_objc_thread_id (void) __GTHR_WEAK;
+
+extern int __generic_gxx_objc_thread_set_data (void *value) __GTHR_WEAK;
+
+extern void *__generic_gxx_objc_thread_get_data (void) __GTHR_WEAK;
+
+extern int __generic_gxx_objc_mutex_allocate (objc_mutex_t) __GTHR_WEAK;
+
+extern int __generic_gxx_objc_mutex_deallocate (objc_mutex_t) __GTHR_WEAK;
+
+extern int __generic_gxx_objc_mutex_lock (objc_mutex_t) __GTHR_WEAK;
+
+extern int __generic_gxx_objc_mutex_trylock (objc_mutex_t) __GTHR_WEAK;
+
+extern int __generic_gxx_objc_mutex_unlock (objc_mutex_t) __GTHR_WEAK;
+
+extern int __generic_gxx_objc_condition_allocate (objc_condition_t) __GTHR_WEAK;
+
+extern int __generic_gxx_objc_condition_deallocate (objc_condition_t) __GTHR_WEAK;
+
+extern int __generic_gxx_objc_condition_wait (objc_condition_t, objc_mutex_t) __GTHR_WEAK;
+
+extern int __generic_gxx_objc_condition_broadcast (objc_condition_t) __GTHR_WEAK;
+
+extern int __generic_gxx_objc_condition_signal (objc_condition_t) __GTHR_WEAK;
+
+/* Backend initialization functions */
+
+/* Initialize the threads subsystem.  */
+static inline int
+__gthread_objc_init_thread_system (void)
+{
+  return __generic_gxx_objc_init_thread_system ();
+}
+
+/* Close the threads subsystem.  */
+static inline int
+__gthread_objc_close_thread_system (void)
+{
+  return __generic_gxx_objc_close_thread_system ();
+}
+
+/* Backend thread functions */
+
+/* Create a new thread of execution.  */
+static inline objc_thread_t
+__gthread_objc_thread_detach (void (* func)(void *), void * arg)
+{
+  return __generic_gxx_objc_thread_detach (func, arg);
+}
+
+/* Set the current thread's priority.  */
+static inline int
+__gthread_objc_thread_set_priority (int priority)
+{
+  return __generic_gxx_objc_thread_set_priority (priority);
+}
+
+/* Return the current thread's priority.  */
+static inline int
+__gthread_objc_thread_get_priority (void)
+{
+  return __generic_gxx_objc_thread_get_priority ();
+}
+
+/* Yield our process time to another thread.  */
+static inline void
+__gthread_objc_thread_yield (void)
+{
+  __generic_gxx_objc_thread_yield ();
+}
+
+/* Terminate the current thread.  */
+static inline int
+__gthread_objc_thread_exit (void)
+{
+  return __generic_gxx_objc_thread_exit ();
+}
+
+/* Returns an integer value which uniquely describes a thread.  */
+static inline objc_thread_t
+__gthread_objc_thread_id (void)
+{
+  return __generic_gxx_objc_thread_id ();
+}
+
+/* Sets the thread's local storage pointer.  */
+static inline int
+__gthread_objc_thread_set_data (void *value)
+{
+  return __generic_gxx_objc_thread_set_data (value);
+}
+
+/* Returns the thread's local storage pointer.  */
+static inline void *
+__gthread_objc_thread_get_data (void)
+{
+  return __generic_gxx_objc_thread_get_data ();
+}
+
+/* Backend mutex functions */
+
+/* Allocate a mutex.  */
+static inline int
+__gthread_objc_mutex_allocate (objc_mutex_t mutex)
+{
+  return __generic_gxx_objc_mutex_allocate (mutex);
+}
+
+/* Deallocate a mutex.  */
+static inline int
+__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
+{
+  return __generic_gxx_objc_mutex_deallocate (mutex);
+}
+
+/* Grab a lock on a mutex.  */
+static inline int
+__gthread_objc_mutex_lock (objc_mutex_t mutex)
+{
+  return __generic_gxx_objc_mutex_lock (mutex);
+}
+
+/* Try to grab a lock on a mutex.  */
+static inline int
+__gthread_objc_mutex_trylock (objc_mutex_t mutex)
+{
+  return __generic_gxx_objc_mutex_trylock (mutex);
+}
+
+/* Unlock the mutex */
+static inline int
+__gthread_objc_mutex_unlock (objc_mutex_t mutex)
+{
+  return __generic_gxx_objc_mutex_unlock (mutex);
+}
+
+/* Backend condition mutex functions */
+
+/* Allocate a condition.  */
+static inline int
+__gthread_objc_condition_allocate (objc_condition_t condition)
+{
+  return __generic_gxx_objc_condition_allocate (condition);
+}
+
+/* Deallocate a condition.  */
+static inline int
+__gthread_objc_condition_deallocate (objc_condition_t condition)
+{
+  return __generic_gxx_objc_condition_deallocate (condition);
+}
+
+/* Wait on the condition */
+static inline int
+__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
+{
+  return __generic_gxx_objc_condition_wait (condition, mutex);
+}
+
+/* Wake up all threads waiting on this condition.  */
+static inline int
+__gthread_objc_condition_broadcast (objc_condition_t condition)
+{
+  return __generic_gxx_objc_condition_broadcast ( condition);
+}
+
+/* Wake up one thread waiting on this condition.  */
+static inline int
+__gthread_objc_condition_signal (objc_condition_t condition)
+{
+  return __generic_gxx_objc_condition_signal (condition);
+}
+
+#else /* !_LIBOBJC */
+
+static inline int
+__gthread_active_p (void)
+{
+  return __generic_gxx_active_p ();
+}
+
+static inline int
+__gthread_once (__gthread_once_t *once, void (*func)(void))
+{
+  return __generic_gxx_once (once, func);
+}
+
+static inline int
+__gthread_key_create (__gthread_key_t *key, void (*dtor)(void *))
+{
+  return __generic_gxx_key_create (key, dtor);
+}
+
+static inline int
+__gthread_key_delete (__gthread_key_t key)
+{
+  return __generic_gxx_key_delete (key);
+}
+
+static inline void *
+__gthread_getspecific (__gthread_key_t key)
+{
+  return __generic_gxx_getspecific (key);
+}
+
+static inline int
+__gthread_setspecific (__gthread_key_t key, const void *ptr)
+{
+  return __generic_gxx_setspecific (key, ptr);
+}
+
+static inline void
+__gthread_mutex_init_function (__gthread_mutex_t *mutex)
+{
+  __generic_gxx_mutex_init_function (mutex);
+}
+
+static inline int
+__gthread_mutex_lock (__gthread_mutex_t * mutex)
+{
+  return __generic_gxx_mutex_lock (mutex);
+}
+
+static inline int
+__gthread_mutex_trylock (__gthread_mutex_t * mutex)
+{
+  return __generic_gxx_mutex_trylock (mutex);
+}
+
+static inline int
+__gthread_mutex_unlock (__gthread_mutex_t * mutex)
+{
+  return __generic_gxx_mutex_unlock (mutex);
+}
+
+static inline void
+__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
+{
+  __generic_gxx_recursive_mutex_init_function (mutex);
+}
+
+static inline int
+__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t * mutex)
+{
+  return __generic_gxx_recursive_mutex_lock (mutex);
+}
+
+static inline int
+__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t * mutex)
+{
+  return __generic_gxx_recursive_mutex_trylock (mutex);
+}
+
+static inline int
+__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t * mutex)
+{
+  return __generic_gxx_recursive_mutex_unlock (mutex);
+}
+
+#endif /* _LIBOBJC */
+
+#endif /* __gthr_generic_h */
Index: Makefile.in
===================================================================
/usr/bin/diff -p -d -F^( -u -L Makefile.in	(revision 112638) -L Makefile.in	(working copy) .svn/text-base/Makefile.in.svn-base Makefile.in
--- Makefile.in	(revision 112638)
+++ Makefile.in	(working copy)
@@ -1390,7 +1390,7 @@ xlimits.h: glimits.h limitx.h limity.h
 #
 # Build libgcc.a.
 
-LIB2ADD = $(LIB2FUNCS_EXTRA)
+LIB2ADD = $(LIB2FUNCS_EXTRA) @extra_libgcc_srcs@
 LIB2ADD_ST = $(LIB2FUNCS_STATIC_EXTRA)
 
 libgcc.mk: config.status Makefile mklibgcc $(LIB2ADD) $(LIB2ADD_ST) specs \

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]