2003/09/26 06:41:51
authormegacz <megacz@xwt.org>
Fri, 30 Jan 2004 07:37:25 +0000 (07:37 +0000)
committermegacz <megacz@xwt.org>
Fri, 30 Jan 2004 07:37:25 +0000 (07:37 +0000)
darcs-hash:20040130073725-2ba56-b105af6100888ba5126b86a817ab42ddc49c90a0.gz

upstream/gcc-3.3/patches/darwin-gc.patch

index 26f0942..c462e70 100644 (file)
@@ -1368,7 +1368,7 @@ diff -buNr boehm-gc/alpha_mach_dep.s boehm-gc/alpha_mach_dep.s
 --- boehm-gc/alpha_mach_dep.s  Fri Aug 17 11:30:45 2001
 +++ boehm-gc/alpha_mach_dep.s  Sat Sep 13 02:10:15 2003
 @@ -1,3 +1,4 @@
-+ # $Id: darwin-gc.patch,v 1.4 2003/09/26 01:54:05 megacz Exp $
++ # $Id: darwin-gc.patch,v 1.5 2003/09/26 05:41:51 megacz Exp $
        .arch ev6
  
          .text
@@ -27265,430 +27265,22 @@ diff -buNr boehm-gc/version.h boehm-gc/version.h
  
  
 --- /tmp/gcc-3.3/boehm-gc/win32_threads.c      Mon Apr 28 13:55:07 2003
-+++ upstream/gcc-3.3/src/boehm-gc/win32_threads.c      Thu Sep 25 05:31:33 2003
-@@ -2,12 +2,26 @@
++++ upstream/gcc-3.3/src/boehm-gc/win32_threads.c      Thu Sep 25 22:38:28 2003
+@@ -337,7 +337,7 @@
  
- #include "private/gc_priv.h"
--#if 0
--#define STRICT
--#include <windows.h>
-+#ifdef CYGWIN32
-+# include <errno.h>
-+
-+ /* Cygwin-specific forward decls */
-+# undef pthread_create 
-+# undef pthread_sigmask 
-+# undef pthread_join 
-+# undef dlopen 
-+
-+# define DEBUG_CYGWIN_THREADS 0
-+
-+  GC_bool GC_thr_initialized = FALSE;
-+  void * GC_start_routine(void * arg);
-+  void GC_thread_exit_proc(void *arg);
-+
- #endif
--#define MAX_THREADS 64
-+#ifndef MAX_THREADS
-+# define MAX_THREADS 64
-+#endif
- struct thread_entry {
-   LONG in_use;
-@@ -18,6 +32,12 @@
-                       /* !in_use ==> stack == 0       */
-   CONTEXT context;
-   GC_bool suspended;
-+
-+# ifdef CYGWIN32
-+    void *status; /* hold exit value until join in case it's a pointer */
-+    pthread_t pthread_id;
-+# endif
-+
- };
- volatile GC_bool GC_please_stop = FALSE;
-@@ -29,6 +49,12 @@
-     /* Unlike the other threads implementations, the thread table here        */
-     /* contains no pointers to the collectable heap.  Thus we have    */
-     /* no private structures we need to preserve.                     */
-+# ifdef CYGWIN32
-+  { int i; /* pthreads may keep a pointer in the thread exit value */
-+    for (i = 0; i < MAX_THREADS; i++)
-+      if (thread_table[i].in_use) GC_push_all((ptr_t)&(thread_table[i].status),(ptr_t)(&(thread_table[i].status)+1));
-+  }
-+# endif
- }
- void GC_stop_world()
-@@ -36,6 +62,10 @@
-   DWORD thread_id = GetCurrentThreadId();
-   int i;
-+#ifdef CYGWIN32
-+  if (!GC_thr_initialized) ABORT("GC_stop_world() called before GC_thr_init()");
-+#endif
-+
-   GC_please_stop = TRUE;
-   for (i = 0; i < MAX_THREADS; i++)
-     if (thread_table[i].stack != 0
-@@ -53,10 +83,14 @@
-       DWORD exitCode; 
-       if (GetExitCodeThread(thread_table[i].handle,&exitCode) &&
-             exitCode != STILL_ACTIVE) {
--            thread_table[i].stack = 0;
-+          thread_table[i].stack = 0; /* prevent stack from being pushed */
-+#         ifndef CYGWIN32
-+            /* this breaks pthread_join on Cygwin, which is guaranteed to  */
-+          /* only see user pthreads                                      */
-           thread_table[i].in_use = FALSE;
-           CloseHandle(thread_table[i].handle);
-           BZERO((void *)(&thread_table[i].context), sizeof(CONTEXT));
-+#         endif
-           continue;
-       }
-       if (SuspendThread(thread_table[i].handle) == (DWORD)-1)
-@@ -335,9 +369,11 @@
-     if (*lo < start) *lo = start;
- }
--#if !defined(MSWINCE) && !(defined(__MINGW32__) && !defined(_DLL))
-+#if !defined(MSWINCE) && defined(GC_DLL)
+ #if !defined(MSWINCE) && !(defined(__MINGW32__) && !defined(_DLL))
  
 -HANDLE WINAPI GC_CreateThread(
-+/* We register threads from DllMain */
-+
 +GC_API HANDLE GC_CreateThread(
      LPSECURITY_ATTRIBUTES lpThreadAttributes, 
      DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, 
      LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId )
-@@ -346,7 +382,10 @@
-                         lpParameter, dwCreationFlags, lpThreadId);
- }
--#else /* !defined(MSWINCE) && !(defined(__MINGW32__) && !defined(_DLL)) */
-+#else /* defined(MSWINCE) || !defined(GC_DLL))  */
-+
-+/* We have no DllMain to take care of new threads.  Thus we   */
-+/* must properly intercept thread creation.                   */
- typedef struct {
-     HANDLE child_ready_h, parent_ready_h;
-@@ -357,7 +396,7 @@
+@@ -357,7 +357,7 @@
  
  DWORD WINAPI thread_start(LPVOID arg);
  
 -HANDLE WINAPI GC_CreateThread(
-+HANDLE GC_CreateThread(
++GC_API HANDLE GC_CreateThread(
      LPSECURITY_ATTRIBUTES lpThreadAttributes, 
      DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, 
      LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId )
-@@ -527,22 +566,11 @@
- LONG WINAPI GC_write_fault_handler(struct _EXCEPTION_POINTERS *exc_info);
--#ifdef GC_DLL
--
--/*
-- * This isn't generally safe, since DllMain is not premptible.
-- * If another thread holds the lock while this runs we're in trouble.
-- * Pontus Rydin suggests wrapping the thread start routine instead.
-+/* threadAttach/threadDetach routines used by both CYGWIN and DLL
-+ * implementation, since both recieve explicit notification on thread
-+ * creation/destruction.
-  */
--BOOL WINAPI DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved)
--{
--  switch (reason) {
--  case DLL_PROCESS_ATTACH:
--    InitializeCriticalSection(&GC_allocate_ml);
--    GC_init();        /* Force initialization before thread attach.   */
--    /* fall through */
--  case DLL_THREAD_ATTACH:
--    {
-+static void threadAttach() {
-       int i;
-       /* It appears to be unsafe to acquire a lock here, since this   */
-       /* code is apparently not preeemptible on some systems.         */
-@@ -554,14 +582,11 @@
-       /* The following should be a noop according to the win32        */
-       /* documentation.  There is empirical evidence that it  */
-       /* isn't.               - HB                                    */
--#     ifdef MPROTECT_VDB
-+# if defined(MPROTECT_VDB)
-        if (GC_incremental) SetUnhandledExceptionFilter(GC_write_fault_handler);
- #     endif
--
--      for (i = 0;
-                              /* cast away volatile qualifier */
--         InterlockedExchange((LPLONG) &thread_table[i].in_use, 1) != 0;
--         i++) {
-+  for (i = 0; InterlockedExchange((LONG*)&thread_table[i].in_use,1) != 0; i++) {
-       /* Compare-and-swap would make this cleaner, but that's not     */
-       /* supported before Windows 98 and NT 4.0.  In Windows 2000,    */
-       /* InterlockedExchange is supposed to be replaced by            */
-@@ -571,11 +596,13 @@
-         ABORT("too many threads");
-       }
-       thread_table[i].id = GetCurrentThreadId();
-+# ifdef CYGWIN32
-+    thread_table[i].pthread_id = pthread_self();
-+# endif
-       if (!DuplicateHandle(GetCurrentProcess(),
-                          GetCurrentThread(),
-                          GetCurrentProcess(),
--                         /* cast away volatile qualifier */
--                         (HANDLE *) &thread_table[i].handle,
-+                     (HANDLE*)&thread_table[i].handle,
-                          0,
-                          0,
-                          DUPLICATE_SAME_ACCESS)) {
-@@ -584,33 +611,226 @@
-       ABORT("DuplicateHandle failed");
-       }
-       thread_table[i].stack = GC_get_stack_base();
-+  if (thread_table[i].stack == NULL) 
-+    ABORT("Failed to find stack base in threadAttach");
-       /* If this thread is being created while we are trying to stop  */
-       /* the world, wait here.  Hopefully this can't happen on any    */
-       /* systems that don't allow us to block here.                   */
-       while (GC_please_stop) Sleep(20);
--    }
--    break;
--  case DLL_THREAD_DETACH:
--    {
-+}
-+
-+static void threadDetach(DWORD thread_id) {
-       int i;
--      DWORD thread_id = GetCurrentThreadId();
-+
-       LOCK();
-       for (i = 0;
-            i < MAX_THREADS &&
--         (thread_table[i].stack == 0 || thread_table[i].id != thread_id);
-+       !thread_table[i].in_use || thread_table[i].id != thread_id;
-          i++) {}
--      if (i >= MAX_THREADS) {
-+  if (i >= MAX_THREADS ) {
-         WARN("thread %ld not found on detach", (GC_word)thread_id);
--      } else {
-+  }
-+  else {
-           thread_table[i].stack = 0;
-           thread_table[i].in_use = FALSE;
-           CloseHandle(thread_table[i].handle);
-           /* cast away volatile qualifier */
--          BZERO((void *) &thread_table[i].context, sizeof(CONTEXT));
-+    BZERO((void *)&thread_table[i].context, sizeof(CONTEXT));
-+  }
-+  UNLOCK();
-+}
-+
-+#ifdef CYGWIN32
-+
-+/* Called by GC_init() - we hold the allocation lock. */
-+void GC_thr_init() {
-+    if (GC_thr_initialized) return;
-+    GC_thr_initialized = TRUE;
-+
-+#if 0
-+    /* this might already be handled in GC_init... */
-+    InitializeCriticalSection(&GC_allocate_ml);
-+#endif
-+
-+    /* Add the initial thread, so we can stop it.     */
-+    threadAttach();
-+}
-+
-+struct start_info {
-+    void *(*start_routine)(void *);
-+    void *arg;
-+};
-+
-+int GC_pthread_join(pthread_t pthread_id, void **retval) {
-+    int result;
-+    int i;
-+
-+#   if DEBUG_CYGWIN_THREADS
-+      GC_printf3("thread 0x%x(0x%x) is joining thread 0x%x.\n",(int)pthread_self(),
-+               GetCurrentThreadId(), (int)pthread_id);
-+#   endif
-+
-+    /* Can't do any table lookups here, because thread being joined 
-+       might not have registered itself yet */
-+
-+    result = pthread_join(pthread_id, retval);
-+
-+    LOCK();
-+    for (i = 0; !thread_table[i].in_use || thread_table[i].pthread_id != pthread_id;
-+         i++) {
-+      if (i == MAX_THREADS - 1) {
-+        GC_printf1("Failed to find thread 0x%x in pthread_join()\n", pthread_id);
-+        ABORT("thread not found on detach");
-+      }
-       }
-       UNLOCK();
-+    threadDetach(thread_table[i].id);
-+
-+#   if DEBUG_CYGWIN_THREADS
-+      GC_printf3("thread 0x%x(0x%x) completed join with thread 0x%x.\n",
-+               (int)pthread_self(), GetCurrentThreadId(), (int)pthread_id);
-+#   endif
-+
-+    return result;
-+}
-+
-+/* Cygwin-pthreads calls CreateThread internally, but it's not
-+ * easily interceptible by us..
-+ *   so intercept pthread_create instead
-+ */
-+int
-+GC_pthread_create(pthread_t *new_thread,
-+                const pthread_attr_t *attr,
-+                  void *(*start_routine)(void *), void *arg) {
-+    int result;
-+    struct start_info * si;
-+
-+    if (!GC_is_initialized) GC_init();
-+              /* make sure GC is initialized (i.e. main thread is attached) */
-+    
-+    /* This is otherwise saved only in an area mmapped by the thread */
-+    /* library, which isn't visible to the collector.          */
-+    si = GC_malloc_uncollectable(sizeof(struct start_info)); 
-+    if (0 == si) return(EAGAIN);
-+
-+    si -> start_routine = start_routine;
-+    si -> arg = arg;
-+
-+#   if DEBUG_CYGWIN_THREADS
-+      GC_printf2("About to create a thread from 0x%x(0x%x)\n",(int)pthread_self(),
-+                                                            GetCurrentThreadId);
-+#   endif
-+    result = pthread_create(new_thread, attr, GC_start_routine, si); 
-+
-+    if (result) { /* failure */
-+              GC_free(si);
-+    } 
-+
-+    return(result);
-+}
-+
-+void * GC_start_routine(void * arg)
-+{
-+    struct start_info * si = arg;
-+    void * result;
-+    void *(*start)(void *);
-+    void *start_arg;
-+    pthread_t pthread_id;
-+    int i;
-+
-+#   if DEBUG_CYGWIN_THREADS
-+      GC_printf2("thread 0x%x(0x%x) starting...\n",(int)pthread_self(),
-+                                                 GetCurrentThreadId());
-+#   endif
-+
-+    /* If a GC occurs before the thread is registered, that GC will   */
-+    /* ignore this thread.  That's fine, since it will block trying to  */
-+    /* acquire the allocation lock, and won't yet hold interesting    */
-+    /* pointers.                                                      */
-+    LOCK();
-+    /* We register the thread here instead of in the parent, so that  */
-+    /* we don't need to hold the allocation lock during pthread_create. */
-+    threadAttach();
-+    UNLOCK();
-+
-+    start = si -> start_routine;
-+    start_arg = si -> arg;
-+    pthread_id = pthread_self();
-+
-+    GC_free(si); /* was allocated uncollectable */
-+
-+    pthread_cleanup_push(GC_thread_exit_proc, pthread_id);
-+    result = (*start)(start_arg);
-+    pthread_cleanup_pop(0);
-+
-+#   if DEBUG_CYGWIN_THREADS
-+      GC_printf2("thread 0x%x(0x%x) returned from start routine.\n",
-+               (int)pthread_self(),GetCurrentThreadId());
-+#   endif
-+
-+    LOCK();
-+    for (i = 0; thread_table[i].pthread_id != pthread_id; i++) {
-+      if (i == MAX_THREADS - 1)
-+        ABORT("thread not found on exit");
-+    }
-+    thread_table[i].status = result;
-+    UNLOCK();
-+
-+    return(result);
-+}
-+
-+void GC_thread_exit_proc(void *arg)
-+{
-+    pthread_t pthread_id = (pthread_t)arg;
-+    int i;
-+
-+#   if DEBUG_CYGWIN_THREADS
-+      GC_printf2("thread 0x%x(0x%x) called pthread_exit().\n",
-+               (int)pthread_self(),GetCurrentThreadId());
-+#   endif
-+
-+    LOCK();
-+    for (i = 0; thread_table[i].pthread_id != pthread_id; i++) {
-+      if (i == MAX_THREADS - 1)
-+        ABORT("thread not found on exit");
-     }
-+    UNLOCK();
-+
-+#if 0
-+    /* TODO: we need a way to get the exit value after a pthread_exit so we can stash it safely away */
-+    thread_table[i].status = ???
-+#endif
-+}
-+
-+/* nothing required here... */
-+int GC_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) {
-+  return pthread_sigmask(how, set, oset);
-+}
-+int GC_pthread_detach(pthread_t thread) {
-+  return pthread_detach(thread);
-+}
-+#else /* !CYGWIN32 */
-+
-+/*
-+ * We avoid acquiring locks here, since this doesn't seem to be preemptable.
-+ * Pontus Rydin suggests wrapping the thread start routine instead.
-+ */
-+#ifdef GC_DLL
-+BOOL WINAPI DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved)
-+{
-+  switch (reason) {
-+  case DLL_PROCESS_ATTACH:
-+    InitializeCriticalSection(&GC_allocate_ml);
-+    GC_init();        /* Force initialization before thread attach.   */
-+    /* fall through */
-+  case DLL_THREAD_ATTACH:
-+    threadAttach();
-+    break;
-+
-+  case DLL_THREAD_DETACH:
-+    threadDetach(GetCurrentThreadId());
-     break;
-+
-   case DLL_PROCESS_DETACH:
-     {
-       int i;
-@@ -636,8 +856,8 @@
-   }
-   return TRUE;
- }
--
--#   endif /* GC_DLL */
-+#endif /* GC_DLL */
-+#endif /* !CYGWIN32 */
- # endif /* !MSWINCE */