[w32file] Move MonoIO.Find{First,Next,Close} to managed
[mono.git] / libgc / win32_threads.c
index 681e1c2b82e85b8652403a21c41589176bef3089..5533b8f2e252bf750dba873d24aeecf78b79facd 100644 (file)
@@ -1,6 +1,7 @@
+#include "private/gc_priv.h"
+
 #if defined(GC_WIN32_THREADS) 
 
-#include "private/gc_priv.h"
 #include <windows.h>
 
 #ifdef CYGWIN32
@@ -10,6 +11,7 @@
 # undef pthread_create 
 # undef pthread_sigmask 
 # undef pthread_join 
+# undef pthread_detach
 # undef dlopen 
 
 # define DEBUG_CYGWIN_THREADS 0
@@ -74,7 +76,33 @@ extern LONG WINAPI GC_write_fault_handler(struct _EXCEPTION_POINTERS *exc_info);
 
 int GC_thread_is_registered (void)
 {
+#if defined(GC_DLL) || defined(GC_INSIDE_DLL)
+       /* Registered by DllMain */
        return 1;
+#else
+       /* FIXME: */
+       return 0;
+#endif
+}
+
+void GC_allow_register_threads (void)
+{
+    /* No-op for GC pre-v7. */
+}
+
+int GC_register_my_thread (struct GC_stack_base *sb)
+{
+#   if defined(GC_DLL) || defined(GC_INSIDE_DLL)
+       /* Registered by DllMain. */
+       return GC_DUPLICATE;
+#   else
+       /* TODO: Implement. */
+       return GC_UNIMPLEMENTED;
+#   endif
+}
+
+void GC_register_altstack (void *stack, int stack_size, void *altstack, int altstack_size)
+{
 }
 
 /*
@@ -156,7 +184,7 @@ static GC_thread GC_new_thread(void) {
 #ifdef __GNUC__
 __inline__
 #endif
-LONG GC_get_max_thread_index()
+static LONG GC_get_max_thread_index()
 {
   LONG my_max = GC_max_thread_index;
 
@@ -189,7 +217,7 @@ static void GC_delete_thread(DWORD thread_id) {
        /* Must still be in_use, since nobody else can store our thread_id. */
        i++) {}
   if (i > my_max) {
-    WARN("Removing nonexisiting thread %ld\n", (GC_word)thread_id);
+    WARN("Removing nonexistent thread %ld\n", (GC_word)thread_id);
   } else {
     GC_delete_gc_thread(thread_table+i);
   }
@@ -236,6 +264,9 @@ void GC_push_thread_structures GC_PROTO((void))
 # endif
 }
 
+/* Defined in misc.c */
+extern CRITICAL_SECTION GC_write_cs;
+
 void GC_stop_world()
 {
   DWORD thread_id = GetCurrentThreadId();
@@ -244,6 +275,9 @@ void GC_stop_world()
   if (!GC_thr_initialized) ABORT("GC_stop_world() called before GC_thr_init()");
 
   GC_please_stop = TRUE;
+# ifndef CYGWIN32
+    EnterCriticalSection(&GC_write_cs);
+# endif /* !CYGWIN32 */
   for (i = 0; i <= GC_get_max_thread_index(); i++)
     if (thread_table[i].stack_base != 0
        && thread_table[i].id != thread_id) {
@@ -269,11 +303,21 @@ void GC_stop_world()
 #         endif
          continue;
        }
-       if (SuspendThread(thread_table[i].handle) == (DWORD)-1)
-         ABORT("SuspendThread failed");
+       if (SuspendThread(thread_table[i].handle) == (DWORD)-1) {
+          thread_table[i].stack_base = 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);
+#         endif
+       }
 #     endif
       thread_table[i].suspended = TRUE;
     }
+# ifndef CYGWIN32
+    LeaveCriticalSection(&GC_write_cs);
+# endif /* !CYGWIN32 */
 }
 
 void GC_start_world()
@@ -362,6 +406,10 @@ void GC_push_all_stacks()
 #       if defined(I386)
           PUSH4(Edi,Esi,Ebx,Edx), PUSH2(Ecx,Eax), PUSH1(Ebp);
          sp = (ptr_t)context.Esp;
+#      elif defined(X86_64)
+         PUSH4(Rax,Rcx,Rdx,Rbx); PUSH2(Rbp, Rsi); PUSH1(Rdi);
+         PUSH4(R8, R9, R10, R11); PUSH4(R12, R13, R14, R15);
+         sp = (ptr_t)context.Rsp;
 #       elif defined(ARM32)
          PUSH4(R0,R1,R2,R3),PUSH4(R4,R5,R6,R7),PUSH4(R8,R9,R10,R11),PUSH1(R12);
          sp = (ptr_t)context.Sp;
@@ -753,8 +801,8 @@ int GC_pthread_detach(pthread_t thread)
  * 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)
+#if defined(GC_DLL) || defined(GC_INSIDE_DLL)
+BOOL WINAPI GC_DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved)
 {
   switch (reason) {
   case DLL_PROCESS_ATTACH: