1 |
#if defined(GC_WIN32_THREADS) |
#if defined(GC_WIN32_THREADS) |
2 |
|
|
3 |
#include "private/gc_priv.h" |
#include "private/gc_priv.h" |
4 |
|
#include <windows.h> |
5 |
|
|
6 |
#ifdef CYGWIN32 |
#ifdef CYGWIN32 |
7 |
# include <errno.h> |
# include <errno.h> |
20 |
|
|
21 |
#endif |
#endif |
22 |
|
|
23 |
|
#ifndef MAX_THREADS |
24 |
#if 0 |
# define MAX_THREADS 64 |
|
#define STRICT |
|
|
#include <windows.h> |
|
25 |
#endif |
#endif |
26 |
|
|
|
#define MAX_THREADS 64 |
|
|
|
|
27 |
struct thread_entry { |
struct thread_entry { |
28 |
LONG in_use; |
LONG in_use; |
29 |
DWORD id; |
DWORD id; |
370 |
if (*lo < start) *lo = start; |
if (*lo < start) *lo = start; |
371 |
} |
} |
372 |
|
|
373 |
#if !defined(MSWINCE) && !(defined(__MINGW32__) && !defined(_DLL)) |
#if !defined(CYGWIN32) |
374 |
|
|
375 |
HANDLE WINAPI GC_CreateThread( |
#if !defined(MSWINCE) && defined(GC_DLL) |
376 |
|
|
377 |
|
/* We register threads from DllMain */ |
378 |
|
|
379 |
|
GC_API HANDLE GC_CreateThread( |
380 |
LPSECURITY_ATTRIBUTES lpThreadAttributes, |
LPSECURITY_ATTRIBUTES lpThreadAttributes, |
381 |
DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, |
DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, |
382 |
LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ) |
LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ) |
385 |
lpParameter, dwCreationFlags, lpThreadId); |
lpParameter, dwCreationFlags, lpThreadId); |
386 |
} |
} |
387 |
|
|
388 |
#else /* !defined(MSWINCE) && !(defined(__MINGW32__) && !defined(_DLL)) */ |
#else /* defined(MSWINCE) || !defined(GC_DLL)) */ |
389 |
|
|
390 |
|
/* We have no DllMain to take care of new threads. Thus we */ |
391 |
|
/* must properly intercept thread creation. */ |
392 |
|
|
393 |
typedef struct { |
typedef struct { |
394 |
HANDLE child_ready_h, parent_ready_h; |
HANDLE child_ready_h, parent_ready_h; |
514 |
} |
} |
515 |
#endif /* !defined(MSWINCE) && !(defined(__MINGW32__) && !defined(_DLL)) */ |
#endif /* !defined(MSWINCE) && !(defined(__MINGW32__) && !defined(_DLL)) */ |
516 |
|
|
517 |
|
#endif /* !CYGWIN32 */ |
518 |
|
|
519 |
#ifdef MSWINCE |
#ifdef MSWINCE |
520 |
|
|
521 |
typedef struct { |
typedef struct { |
571 |
|
|
572 |
LONG WINAPI GC_write_fault_handler(struct _EXCEPTION_POINTERS *exc_info); |
LONG WINAPI GC_write_fault_handler(struct _EXCEPTION_POINTERS *exc_info); |
573 |
|
|
574 |
/* threadAttach/threadDetach routines used by both CYGWIN and DLL implementation, |
/* threadAttach/threadDetach routines used by both CYGWIN and DLL |
575 |
since both recieve explicit notification on thread creation/destruction |
* implementation, since both recieve explicit notification on thread |
576 |
|
* creation/destruction. |
577 |
*/ |
*/ |
578 |
void threadAttach() { |
static void threadAttach() { |
579 |
int i; |
int i; |
580 |
/* It appears to be unsafe to acquire a lock here, since this */ |
/* It appears to be unsafe to acquire a lock here, since this */ |
581 |
/* code is apparently not preeemptible on some systems. */ |
/* code is apparently not preeemptible on some systems. */ |
624 |
while (GC_please_stop) Sleep(20); |
while (GC_please_stop) Sleep(20); |
625 |
} |
} |
626 |
|
|
627 |
void threadDetach(DWORD thread_id) { |
static void threadDetach(DWORD thread_id) { |
628 |
int i; |
int i; |
629 |
|
|
630 |
LOCK(); |
LOCK(); |
790 |
int i; |
int i; |
791 |
|
|
792 |
# if DEBUG_CYGWIN_THREADS |
# if DEBUG_CYGWIN_THREADS |
793 |
GC_printf2("thread 0x%x(0x%x) called pthread_exit().\n",(int)pthread_self(),GetCurrentThreadId()); |
GC_printf2("thread 0x%x(0x%x) called pthread_exit().\n", |
794 |
|
(int)pthread_self(),GetCurrentThreadId()); |
795 |
# endif |
# endif |
796 |
|
|
797 |
LOCK(); |
LOCK(); |
814 |
int GC_pthread_detach(pthread_t thread) { |
int GC_pthread_detach(pthread_t thread) { |
815 |
return pthread_detach(thread); |
return pthread_detach(thread); |
816 |
} |
} |
817 |
#else |
#else /* !CYGWIN32 */ |
818 |
|
|
819 |
/* |
/* |
820 |
* We avoid acquiring locks here, since this doesn't seem to be preemptable. |
* We avoid acquiring locks here, since this doesn't seem to be preemptable. |
821 |
* Pontus Rydin suggests wrapping the thread start routine instead. |
* Pontus Rydin suggests wrapping the thread start routine instead. |
822 |
*/ |
*/ |
823 |
|
#ifdef GC_DLL |
824 |
BOOL WINAPI DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved) |
BOOL WINAPI DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved) |
825 |
{ |
{ |
826 |
switch (reason) { |
switch (reason) { |
861 |
} |
} |
862 |
return TRUE; |
return TRUE; |
863 |
} |
} |
864 |
#endif /* CYGWIN32 */ |
#endif /* GC_DLL */ |
865 |
|
#endif /* !CYGWIN32 */ |
866 |
|
|
867 |
# endif /* !MSWINCE */ |
# endif /* !MSWINCE */ |
868 |
|
|