X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=libgc%2Fwin32_threads.c;h=a2cd0fda43ee3dbd88bf8d15884bc76c1f35c750;hb=d5c8747c5a0fc194a9d32ccc066e8813c3cd2bb9;hp=3195094cc117ec39fcf0a84af0053c443dba8d7f;hpb=fefd6f1d0578964f8ec15e061c5b2db1f9ef4fbc;p=mono.git diff --git a/libgc/win32_threads.c b/libgc/win32_threads.c index 3195094cc11..a2cd0fda43e 100644 --- a/libgc/win32_threads.c +++ b/libgc/win32_threads.c @@ -1,6 +1,7 @@ +#include "private/gc_priv.h" + #if defined(GC_WIN32_THREADS) -#include "private/gc_priv.h" #include #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 @@ -195,7 +197,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); } @@ -242,6 +244,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(); @@ -250,6 +255,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) { @@ -275,11 +283,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() @@ -367,7 +385,11 @@ void GC_push_all_stacks() # define PUSH4(r1,r2,r3,r4) PUSH2(r1,r2), PUSH2(r3,r4) # if defined(I386) PUSH4(Edi,Esi,Ebx,Edx), PUSH2(Ecx,Eax), PUSH1(Ebp); - sp = (ptr_t)context.Esp; + 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; @@ -760,7 +782,7 @@ int GC_pthread_detach(pthread_t thread) * Pontus Rydin suggests wrapping the thread start routine instead. */ #if defined(GC_DLL) || defined(GC_INSIDE_DLL) -BOOL WINAPI DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved) +BOOL WINAPI GC_DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved) { switch (reason) { case DLL_PROCESS_ATTACH: