Hi,
After last week's build debacle, I've decided to "do it right", or at
least what I think is right. I should know better than to resort to
conditionally including code.
Therefore, I would like to redefine the current suspension interface
from this mess:
#if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
&& !defined(GC_WIN32_THREADS) && !defined(GC_DARWIN_THREADS)
GC_API void GC_suspend_thread GC_PROTO((pthread_t));
GC_API void GC_resume_thread GC_PROTO((pthread_t));
#endif
to the more readable/maintainable:
GC_API void GC_suspend_thread GC_PROTO((GC_thread_t));
GC_API void GC_resume_thread GC_PROTO((GC_thread_t));
Where GC_thread_t is defined appropriately for every platform. On
platforms where the functions are unimplemented (anything but posix
threads right now), the functions will call ABORT with an appropriate
message.
There are lots of different ways to do this, but I find this the least
offensive of the solutions I've pondered. There seems little sense in
submitting this to the GC list since no decision has been officially
made on the existence of GC_suspend/resume_thread yet.
I have tested this on x86 linux, powerpc-darwin, and x86 cygwin.
Nonetheless, the giant ifdef in gc.h will, I'm sure, not be complete (or
necessarily correct). I would appreciate it if those-in-the-know would
pay special attention to this.
Keith
ChangeLog
2006-07-06 Keith Seitz <keiths@redhat.com>
* include/gc.h (GC_thread_t): Define.
(GC_suspend_thread): Define for all platforms.
(GC_resume_thread): Likewise.
* darwin_stop_world.c (GC_suspend_thread): New function.
(GC_resume_thread): New function.
* pthread_stop_world.c (GC_suspend_thread): New function.
(GC_resume_thread): New function.
* solaris_threads.c (GC_suspend_thread): New function.
(GC_resume_thread): New function.
* win32_threads.c (GC_suspend_thread): New function.
(GC_resume_thread): New function.
------------------------------------------------------------------------
Index: include/gc.h
===================================================================
--- include/gc.h (revision 115072)
+++ include/gc.h (working copy)
@@ -1036,18 +1036,35 @@
# include "gc_local_alloc.h"
#endif
+ /* External thread suspension support. These functions do not
+ * implement suspension counts or any other higher-level abstraction.
+ * Threads which have been suspended numerous times will resume with
+ * the very first call to GC_resume_thread.
+ */
+#if defined(GC_DARWIN_THREADS)
+ typedef thread_act_t GC_thread_t;
+#elif defined(GC_SOLARIS_PTHREADS)
+ typedef pthread_t GC_thread_t;
+#elif defined(GC_SOLARIS_THREADS)
+ typedef thread_t GC_thread_t;
+#elif defined(GC_WIN32_THREADS)
+# ifdef __CYGWIN32__
+ typedef pthread_t GC_thread_t;
+# else
+ typedef DWORD GC_thread_t;
+# endif
+#else
+# ifdef __CYGWIN32__
+# include <pthread.h>
+# endif
+ typedef pthread_t GC_thread_t;
+#endif
+
+ GC_API void GC_suspend_thread GC_PROTO((GC_thread_t));
+ GC_API void GC_resume_thread GC_PROTO((GC_thread_t));
+
#ifdef __cplusplus
} /* end of extern "C" */
#endif
-/* External thread suspension support. These functions do not implement
- * suspension counts or any other higher-level abstraction. Threads which
- * have been suspended numerous times will resume with the very first call
- * to GC_resume_thread.
- */
-#if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
- && !defined(GC_WIN32_THREADS) && !defined(GC_DARWIN_THREADS)
-GC_API void GC_suspend_thread GC_PROTO((pthread_t));
-GC_API void GC_resume_thread GC_PROTO((pthread_t));
-#endif
#endif /* _GC_H */
Index: darwin_stop_world.c
===================================================================
--- darwin_stop_world.c (revision 115072)
+++ darwin_stop_world.c (working copy)
@@ -503,4 +503,11 @@
GC_use_mach_handler_thread = 1;
}
+void GC_suspend_thread(GC_thread_t thread) {
+ ABORT("GC_suspend_thread not implemented");
+}
+
+void GC_resume_thread(GC_thread_t thread) {
+ ABORT("GC_resume_thread not implemented");
+}
#endif
Index: pthread_stop_world.c
===================================================================
--- pthread_stop_world.c (revision 115072)
+++ pthread_stop_world.c (working copy)
@@ -454,7 +454,8 @@
GC_end_blocking();
}
-void GC_suspend_thread(pthread_t thread) {
+void GC_suspend_thread(GC_thread_t thr) {
+ pthread_t thread = (pthread_t) thr;
if (thread == pthread_self())
suspend_self();
else {
@@ -475,8 +476,8 @@
}
}
-void GC_resume_thread(pthread_t thread) {
- GC_thread t = GC_lookup_thread(thread);
+void GC_resume_thread(GC_thread_t thread) {
+ GC_thread t = GC_lookup_thread((pthread_t) thread);
if (t == NULL)
ABORT("attempting to resume unknown thread");
Index: solaris_threads.c
===================================================================
--- solaris_threads.c (revision 115072)
+++ solaris_threads.c (working copy)
@@ -951,6 +951,14 @@
return(result);
}
+void GC_suspend_thread(GC_thread_t thread) {
+ ABORT("GC_suspend_thread not implemented");
+}
+
+void GC_resume_thread(GC_thread_t thread) {
+ ABORT("GC_resume_thread not implemented");
+}
+
# else /* !GC_SOLARIS_THREADS */
#ifndef LINT
Index: win32_threads.c
===================================================================
--- win32_threads.c (revision 115072)
+++ win32_threads.c (working copy)
@@ -522,6 +522,14 @@
#endif /* !CYGWIN32 */
+void GC_suspend_thread(GC_thread_t thread) {
+ ABORT("GC_suspend_thread not implemented");
+}
+
+void GC_resume_thread(GC_thread_t thread) {
+ ABORT("GC_resume_thread not implemented");
+}
+
#ifdef MSWINCE
typedef struct {