RFC: "Generic" gthread model

Jonathan Larmour jlarmour@redhat.com
Mon Aug 20 11:37:00 GMT 2001


Jonathan Larmour wrote:
> 
> Anyway, I will regenerate my patch with the new once_t tomorrow at a more
> sane hour of the day for me.

Attached... so I'd like it to be considered for application now.

Jifl

2001-08-15  Jonathan Larmour  <jlarmour@redhat.com>

        * Makefile.in (EXTRAEHOBJS): New. Set by configure.
	(LIB2ADDEH): Also build EXTRAEHOBJS.
        * config/ia64/t-ia64 (LIB2ADDEH): Likewise.
        * configure.in: Default to new "unknown" thread model if
        --enable-threads is used but no model is provided by the target.
	Include gthr-unknown.c in EXTRAEHOBJS if so.
        * doc/install.text: Document "unknown" thread model.
        * gthr.h: Document new __GTHREAD_MUTEX_DESTROY_FUNCTION
        interface.
        * gthr-unknown.h: New file.
        * gthr-unknown.c: New file.


-- 
Red Hat, Rustat House, Clifton Road, Cambridge, UK. Tel: +44 (1223) 271062
Maybe this world is another planet's Hell -Aldous Huxley || Opinions==mine
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.602.2.34
diff -u -5 -p -r1.602.2.34 Makefile.in
--- Makefile.in	2001/08/09 02:26:11	1.602.2.34
+++ Makefile.in	2001/08/20 18:23:58
@@ -375,13 +375,16 @@ LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES)
 LIBGCC2_INCLUDES =
 
 # Additional target-dependent options for compiling libgcc2.a.
 TARGET_LIBGCC2_CFLAGS =
 
+# Extra objects required for exception support
+EXTRAEHOBJS=@EXTRAEHOBJS@
+
 # Additional sources to handle exceptions; overridden on ia64.
 LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \
-  $(srcdir)/unwind-sjlj.c
+  $(srcdir)/unwind-sjlj.c $(EXTRAEHOBJS)
 LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h

 # nm flags to list global symbols in libgcc object files.
 SHLIB_NM_FLAGS = -pg

Index: configure.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/configure.in,v
retrieving revision 1.483.2.27
diff -u -5 -p -r1.483.2.27 configure.in
--- configure.in	2001/07/25 01:46:30	1.483.2.27
+++ configure.in	2001/08/20 18:23:58
@@ -284,14 +284,14 @@ case x${enable_threads_flag} in
 		# No threads
 		target_thread_file='single'
 		;;
 	xyes)
 		# default
-		target_thread_file=''
+		target_thread_file='unknown'
 		;;
 	xdecosf1 | xirix | xmach | xos2 | xposix | xpthreads | xsingle | \
-	xsolaris | xwin32 | xdce | xrtems| xvxworks | xaix)
+	xsolaris | xwin32 | xdce | xrtems| xvxworks | xaix | xunknown)
 		target_thread_file=$enable_threads_flag
 		;;
 	*)
 		echo "$enable_threads is an unknown thread package" 1>&2
 		exit 1
@@ -1764,16 +1764,21 @@ changequote([,])dnl
 	esac
 done
 
 # Make gthr-default.h if we have a thread file.
 gthread_flags=
+EXTRAEHOBJS=
 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 = unknown; then
+        EXTRAEHOBJS="\$(srcdir)/gthr-unknown.c"
+    fi
 fi
 AC_SUBST(gthread_flags)
+AC_SUBST(EXTRAEHOBJS)
 
 # Find out what GC implementation we want, or may, use.
 AC_ARG_WITH(gc,
 [  --with-gc={simple,page} choose the garbage collection mechanism to use
                           with the compiler],
Index: gthr.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gthr.h,v
retrieving revision 1.7
diff -u -5 -p -r1.7 gthr.h
--- gthr.h	2000/01/27 18:49:12	1.7
+++ gthr.h	2001/08/20 18:23:58
@@ -52,10 +52,15 @@ Boston, MA 02111-1307, USA.  */
      		some systems can't initalize a mutex without a
 		function call.  On such systems, define this to a
 		function which looks like this:
 		  void __GTHREAD_MUTEX_INIT_FUNCTION (__gthread_mutex_t *)
 		Don't define __GTHREAD_MUTEX_INIT in this case
+     __GTHREAD_MUTEX_DESTROY_FUNCTION
+     		some systems can't clean up an unused mutex without a
+		function call.  On such systems, define this to a
+		function which looks like this:
+		  void __GTHREAD_MUTEX_DESTROY_FUNCTION (__gthread_mutex_t *)
 
    The threads interface must define the following static functions:
 
      int __gthread_once (__gthread_once_t *once, void (*func) ())
 
Index: config/ia64/t-ia64
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/t-ia64,v
retrieving revision 1.6.4.1
diff -u -5 -p -r1.6.4.1 t-ia64
--- config/ia64/t-ia64	2001/05/13 07:10:10	1.6.4.1
+++ config/ia64/t-ia64	2001/08/20 18:23:58
@@ -38,6 +38,6 @@ crtbeginS.o: $(srcdir)/config/ia64/crtbe
 	$(GCC_FOR_TARGET) -DSHARED -c -o crtendS.o -x assembler-with-cpp $(srcdir)/config/ia64/crtend.asm
 crtfastmath.o: $(srcdir)/config/ia64/crtfastmath.c $(GCC_PASSES)
 	$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -c -o crtfastmath.o $(srcdir)/config/ia64/crtfastmath.c
 
 EXTRA_HEADERS = $(srcdir)/config/ia64/ia64intrin.h
-LIB2ADDEH = $(srcdir)/config/ia64/unwind-ia64.c $(srcdir)/unwind-sjlj.c
+LIB2ADDEH = $(srcdir)/config/ia64/unwind-ia64.c $(srcdir)/unwind-sjlj.c $(EXTRAEHOBJS)
Index: doc/install.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/install.texi,v
retrieving revision 1.1.2.54
diff -u -5 -p -r1.1.2.54 install.texi
--- doc/install.texi	2001/08/17 23:32:52	1.1.2.54
+++ doc/install.texi	2001/08/20 18:23:59
@@ -532,11 +532,11 @@ On some systems, this is the default.
 
 In general, the best (and, in many cases, the only known) threading
 model available will be configured for use.  Beware that on some
 systems, gcc has not been taught what threading models are generally
 available for the system.  In this case, @option{--enable-threads} is an
-alias for @option{--enable-threads=single}.
+alias for @option{--enable-threads=unknown}.
 
 @item --disable-threads
 Specify that threading support should be disabled for the system.
 This is an alias for @option{--enable-threads=single}.
 
@@ -567,10 +567,14 @@ to all platforms.
 RTEMS thread support.
 @item single
 Disable thread support, should work for all platforms.
 @item solaris
 Sun Solaris 2 thread support.
+@item unknown
+A platform with unknown thread support. GCC will instead provide a layer
+that allows the runtime system to provide an implementation of the
+thread model.
 @item vxworks
 VxWorks thread support.
 @item win32
 Microsoft Win32 API thread support.
 @end table
--- /dev/null	Thu Aug 24 10:00:32 2000
+++ gthr-unknown.h	Mon Aug 20 03:32:54 2001
@@ -0,0 +1,194 @@
+/* Threads compatibility routines for libgcc2 and libobjc.  */
+/* Compile this one with gcc.  */
+/* Copyright (C) 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, 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_unknown_h
+#define __gthr_unknown_h
+
+/* Provide a non-inlined API to allow unknown runtimes to plug in to the
+   GCC thread system without recompiling GCC. */
+
+#define __GTHREADS 1
+
+/* We assign opaque types that allow the runtime to map the objects to real
+   values, either by casting it directly, or by pointing at the real object. */
+typedef void    *__gthread_key_t;
+typedef void    *__gthread_mutex_t;
+typedef union
+{
+  struct __gthread_once_info_def {
+    char __gthread_once_imp_data[16];  /* the real implementation's once_t */
+    char __gthread_once_t_init_state;  /* boolean flag for whether init'd */
+  } __gthread_once_info;
+  double __gthread_once_unused_double; /* for alignment only */
+} __gthread_once_t;
+
+
+#define __GTHREAD_MUTEX_INIT_FUNCTION    __gthread_mutex_init_function
+#define __GTHREAD_MUTEX_DESTROY_FUNCTION __gthread_mutex_destroy_function
+#define __GTHREAD_ONCE_INIT { { { 0 }, 0 } }
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _LIBOBJC
+
+/* Backend initialization functions */
+
+/* Initialize the threads subsystem. */
+extern int
+__gthread_objc_init_thread_system(void);
+
+/* Close the threads subsystem. */
+extern int
+__gthread_objc_close_thread_system(void);
+
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
+extern objc_thread_t
+__gthread_objc_thread_detach(void (* func)(void *), void *arg);
+
+/* Set the current thread's priority. */
+extern int
+__gthread_objc_thread_set_priority(int priority);
+
+/* Return the current thread's priority. */
+extern int
+__gthread_objc_thread_get_priority(void);
+
+/* Yield our process time to another thread. */
+extern void
+__gthread_objc_thread_yield(void);
+
+/* Terminate the current thread. */
+extern int
+__gthread_objc_thread_exit(void);
+
+/* Returns an integer value which uniquely describes a thread. */
+extern objc_thread_t
+__gthread_objc_thread_id(void);
+
+/* Sets the thread's local storage pointer. */
+extern int
+__gthread_objc_thread_set_data(void *value);
+
+/* Returns the thread's local storage pointer. */
+extern void *
+__gthread_objc_thread_get_data(void);
+
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+extern int
+__gthread_objc_mutex_allocate(objc_mutex_t mutex);
+
+/* Deallocate a mutex. */
+extern int
+__gthread_objc_mutex_deallocate(objc_mutex_t mutex);
+
+/* Grab a lock on a mutex. */
+extern int
+__gthread_objc_mutex_lock(objc_mutex_t mutex);
+
+/* Try to grab a lock on a mutex. */
+extern int
+__gthread_objc_mutex_trylock(objc_mutex_t mutex);
+
+/* Unlock the mutex */
+extern int
+__gthread_objc_mutex_unlock(objc_mutex_t mutex);
+
+/* Backend condition mutex functions */
+
+/* Allocate a condition. */
+extern int
+__gthread_objc_condition_allocate(objc_condition_t condition);
+
+/* Deallocate a condition. */
+extern int
+__gthread_objc_condition_deallocate(objc_condition_t condition);
+
+/* Wait on the condition */
+extern int
+__gthread_objc_condition_wait(objc_condition_t condition,
+			      objc_mutex_t mutex);
+
+/* Wake up all threads waiting on this condition. */
+extern int
+__gthread_objc_condition_broadcast(objc_condition_t condition);
+
+/* Wake up one thread waiting on this condition. */
+extern int
+__gthread_objc_condition_signal(objc_condition_t condition);
+
+#else /* _LIBOBJC */
+
+extern int
+__gthread_active_p (void);
+
+extern int
+__gthread_once (__gthread_once_t *once, void (*func) (void));
+
+extern int
+__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *));
+
+extern int
+__gthread_key_dtor (__gthread_key_t key, void *ptr);
+
+extern int
+__gthread_key_delete (__gthread_key_t key);
+
+extern void *
+__gthread_getspecific (__gthread_key_t key);
+
+extern int
+__gthread_setspecific (__gthread_key_t key, const void *ptr);
+
+extern void
+__gthread_mutex_init_function(__gthread_mutex_t *mutex);
+
+extern void
+__gthread_mutex_destroy_function(__gthread_mutex_t *mutex);
+
+extern int
+__gthread_mutex_lock (__gthread_mutex_t *mutex);
+
+extern int
+__gthread_mutex_trylock (__gthread_mutex_t *mutex);
+
+extern int
+__gthread_mutex_unlock (__gthread_mutex_t *mutex);
+
+#endif /* _LIBOBJC */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not __gthr_unknown_h */
--- /dev/null	Thu Aug 24 10:00:32 2000
+++ gthr-unknown.c	Mon Aug 20 03:31:09 2001
@@ -0,0 +1,289 @@
+/* Threads compatibility routines for libgcc2 and libobjc.  */
+/* Compile this one with gcc.  */
+/* Copyright (C) 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, 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.  */
+
+/* Implement a non-inlined API to allow unknown runtimes to plug in to the
+   GCC thread system without recompiling GCC. */
+
+#include "gthr-unknown.h"
+
+#ifdef __cplusplus
+#define UNUSED(x)
+#else
+#define UNUSED(x) x __attribute__((unused))
+#endif
+
+#ifdef _LIBOBJC
+
+/* Thread local storage for a single thread */
+static void *thread_local_storage = NULL;
+
+/* Backend initialization functions */
+
+/* Initialize the threads subsystem. */
+int
+__gthread_objc_init_thread_system(void)
+{
+  /* No thread support available */
+  return -1;
+}
+
+/* Close the threads subsystem. */
+int
+__gthread_objc_close_thread_system(void)
+{
+  /* No thread support available */
+  return -1;
+}
+
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
+objc_thread_t
+__gthread_objc_thread_detach(void (* func)(void *), void * UNUSED(arg))
+{
+  /* No thread support available */
+  return NULL;
+}
+
+/* Set the current thread's priority. */
+int
+__gthread_objc_thread_set_priority(int UNUSED(priority))
+{
+  /* No thread support available */
+  return -1;
+}
+
+/* Return the current thread's priority. */
+int
+__gthread_objc_thread_get_priority(void)
+{
+  return OBJC_THREAD_INTERACTIVE_PRIORITY;
+}
+
+/* Yield our process time to another thread. */
+void
+__gthread_objc_thread_yield(void)
+{
+  return;
+}
+
+/* Terminate the current thread. */
+int
+__gthread_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
+__gthread_objc_thread_id(void)
+{
+  /* No thread support, use 1. */
+  return (objc_thread_t)1;
+}
+
+/* Sets the thread's local storage pointer. */
+int
+__gthread_objc_thread_set_data(void *value)
+{
+  thread_local_storage = value;
+  return 0;
+}
+
+/* Returns the thread's local storage pointer. */
+void *
+__gthread_objc_thread_get_data(void)
+{
+  return thread_local_storage;
+}
+
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+int
+__gthread_objc_mutex_allocate(objc_mutex_t UNUSED(mutex))
+{
+  return 0;
+}
+
+/* Deallocate a mutex. */
+int
+__gthread_objc_mutex_deallocate(objc_mutex_t UNUSED(mutex))
+{
+  return 0;
+}
+
+/* Grab a lock on a mutex. */
+int
+__gthread_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 a mutex. */
+int
+__gthread_objc_mutex_trylock(objc_mutex_t UNUSED(mutex))
+{
+  /* There can only be one thread, so we always get the lock */
+  return 0;
+}
+
+/* Unlock the mutex */
+int
+__gthread_objc_mutex_unlock(objc_mutex_t UNUSED(mutex))
+{
+  return 0;
+}
+
+/* Backend condition mutex functions */
+
+/* Allocate a condition. */
+int
+__gthread_objc_condition_allocate(objc_condition_t UNUSED(condition))
+{
+  return 0;
+}
+
+/* Deallocate a condition. */
+int
+__gthread_objc_condition_deallocate(objc_condition_t UNUSED(condition))
+{
+  return 0;
+}
+
+/* Wait on the condition */
+int
+__gthread_objc_condition_wait(objc_condition_t UNUSED(condition),
+			      objc_mutex_t UNUSED(mutex))
+{
+  return 0;
+}
+
+/* Wake up all threads waiting on this condition. */
+int
+__gthread_objc_condition_broadcast(objc_condition_t UNUSED(condition))
+{
+  return 0;
+}
+
+/* Wake up one thread waiting on this condition. */
+int
+__gthread_objc_condition_signal(objc_condition_t UNUSED(condition))
+{
+  return 0;
+}
+
+#else /* _LIBOBJC */
+
+int
+__gthread_active_p (void)
+{
+  return 0;
+}
+
+int
+__gthread_once (__gthread_once_t *once, void (*func) (void))
+{
+  if (0 == once->__gthread_once_info.__gthread_once_t_init_state)
+    {
+      (once->__gthread_once_info.__gthread_once_t_init_state)++;
+      (*func)();
+    }
+  return 0;
+}
+
+int
+__gthread_key_create (__gthread_key_t *UNUSED(key),
+                      UNUSED(void (*dtor) (void *)))
+{
+  return -1;
+}
+
+int
+__gthread_key_dtor (__gthread_key_t UNUSED(key), void * UNUSED(ptr))
+{
+  return -1;
+}
+
+int
+__gthread_key_delete (__gthread_key_t UNUSED(key))
+{
+  return -1;
+}
+
+void *
+__gthread_getspecific (__gthread_key_t UNUSED(key))
+{
+  return (void *)0L;
+}
+
+int
+__gthread_setspecific (__gthread_key_t UNUSED(key), const void * UNUSED(ptr))
+{
+  return -1;
+}
+
+void
+__gthread_mutex_init_function(__gthread_mutex_t * UNUSED(mutex))
+{
+  return;
+}
+
+
+void
+__gthread_mutex_destroy_function(__gthread_mutex_t * UNUSED(mutex))
+{
+  return;
+}
+
+
+int
+__gthread_mutex_lock (__gthread_mutex_t * UNUSED(mutex))
+{
+  return 0;
+}
+
+int
+__gthread_mutex_trylock (__gthread_mutex_t * UNUSED(mutex))
+{
+  return 0;
+}
+
+int
+__gthread_mutex_unlock (__gthread_mutex_t * UNUSED(mutex))
+{
+  return 0;
+}
+
+#endif /* _LIBOBJC */
+
+#undef UNUSED


More information about the Gcc-patches mailing list