#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)
+{
+}
+
/*
* This may be called from DllMain, and hence operates under unusual
* constraints.
#ifdef __GNUC__
__inline__
#endif
-LONG GC_get_max_thread_index()
+static LONG GC_get_max_thread_index()
{
LONG my_max = GC_max_thread_index;
# 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;
}
# 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;
* 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: