STATIC GC_thread GC_threads[THREAD_TABLE_SZ];
/* It may not be safe to allocate when we register the first thread. */
-/* Thus we allocated one statically. */
+/* Thus we allocated one statically. It does not contain any field we */
+/* need to push ("next" and "status" fields are unused). */
static struct GC_Thread_Rep first_thread;
static GC_bool first_thread_used = FALSE;
/* see GC_stop_world() for the information. */
t -> stack_base = 0;
t -> id = 0;
-# ifdef GC_PTHREADS
- GC_PTHREAD_PTRVAL(t->pthread_id) = 0;
-# endif
AO_store_release(&t->tm.in_use, FALSE);
} else
# endif
GC_ASSERT(I_HOLD_LOCK());
# ifndef GC_NO_THREADS_DISCOVERY
if (GC_win32_dll_threads) {
- /* 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 GC_PTHREADS
- int i; /* pthreads may keep a pointer in the thread exit value */
- LONG my_max = GC_get_max_thread_index();
-
- for (i = 0; i <= my_max; i++)
- if (dll_thread_table[i].tm.in_use)
- GC_push_all((ptr_t)&(dll_thread_table[i].status),
- (ptr_t)(&(dll_thread_table[i].status)+1));
-# endif
+ /* Unlike the other threads implementations, the thread table */
+ /* here contains no pointers to the collectible heap (note also */
+ /* that GC_PTHREADS is incompatible with DllMain-based thread */
+ /* registration). Thus we have no private structures we need */
+ /* to preserve. */
} else
# endif
/* else */ {
}
# if defined(THREAD_LOCAL_ALLOC)
GC_push_all((ptr_t)(&GC_thread_key),
- (ptr_t)(&GC_thread_key)+sizeof(&GC_thread_key));
+ (ptr_t)(&GC_thread_key)+sizeof(&GC_thread_key));
/* Just in case we ever use our own TLS implementation. */
# endif
}
return result;
}
-#else /* !GC_PTHREADS */
-
-# ifndef GC_NO_THREADS_DISCOVERY
+#elif !defined(GC_NO_THREADS_DISCOVERY)
/* We avoid acquiring locks here, since this doesn't seem to be */
/* preemptible. This may run with an uninitialized collector, in */
/* which case we don't do much. This implies that no threads other */
/* collector. (The alternative of initializing the collector here */
/* seems dangerous, since DllMain is limited in what it can do.) */
-# ifdef GC_INSIDE_DLL
- /* Export only if needed by client. */
- GC_API
-# else
-# define GC_DllMain DllMain
-# endif
- BOOL WINAPI GC_DllMain(HINSTANCE inst GC_ATTR_UNUSED, ULONG reason,
- LPVOID reserved GC_ATTR_UNUSED)
- {
+# ifdef GC_INSIDE_DLL
+ /* Export only if needed by client. */
+ GC_API
+# else
+# define GC_DllMain DllMain
+# endif
+ BOOL WINAPI GC_DllMain(HINSTANCE inst GC_ATTR_UNUSED, ULONG reason,
+ LPVOID reserved GC_ATTR_UNUSED)
+ {
DWORD thread_id;
static int entry_count = 0;
break;
}
return TRUE;
- }
-# endif /* !GC_NO_THREADS_DISCOVERY */
-
-#endif /* !GC_PTHREADS */
+ }
+#endif /* !GC_NO_THREADS_DISCOVERY && !GC_PTHREADS */
/* Perform all initializations, including those that */
/* may require allocation. */