diff options
author | khan <khan@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-01-04 21:11:17 +0000 |
---|---|---|
committer | khan <khan@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-01-04 21:11:17 +0000 |
commit | c13f265cc29471a33e3bb17c4c00f78afb0dd172 (patch) | |
tree | 2d5ea60f0dc75c966fafac88e66f0f17507fca9f /gcc/gthr-win32.h | |
parent | b99e5aef5eb295200bb2c5fc1b0d2ea1a0649018 (diff) | |
download | gcc-c13f265cc29471a33e3bb17c4c00f78afb0dd172.tar.gz |
2000-01-04 Mumit Khan <khan@xraylith.wisc.edu>
* gthr-win32.h (__gthread_active_p): Support Mingw MT runtime.
(__gthread_key_create): Likewise.
(__gthread_key_dtor): Likewise.
(__gthread_once): Fix logic.
(__gthread_key_delete): Cast away constness.
* i386/cygwin.h (SUBTARGET_SWITCHES): Add -mthreads option.
* invoke.texi: Document.
* i386/mingw32.h (CPP_SPEC): Use.
(LIBGCC_SPEC): Likewise.
* i386/crtdll.h (LIBGCC_SPEC): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31215 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gthr-win32.h')
-rw-r--r-- | gcc/gthr-win32.h | 92 |
1 files changed, 64 insertions, 28 deletions
diff --git a/gcc/gthr-win32.h b/gcc/gthr-win32.h index b9402202722..c5c5899c8f8 100644 --- a/gcc/gthr-win32.h +++ b/gcc/gthr-win32.h @@ -1,6 +1,6 @@ /* Threads compatibily routines for libgcc2. */ /* Compile this one with gcc. */ -/* Copyright (C) 1999 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2000 Free Software Foundation, Inc. Contributed by Mumit Khan <khan@xraylith.wisc.edu>. This file is part of GNU CC. @@ -34,23 +34,41 @@ Boston, MA 02111-1307, USA. */ does not map well into pthread-inspired gcc's threading model, and so there are caveats one needs to be aware of. - 1. The destructor supplied to __gthread_key_create is ignored. This - will certainly cause memory leaks due to unreclaimed eh contexts - (sizeof (eh_context) is at least 24 bytes for x86 currently). + 1. The destructor supplied to __gthread_key_create is ignored for + generic x86-win32 ports. This will certainly cause memory leaks + due to unreclaimed eh contexts (sizeof (eh_context) is at least + 24 bytes for x86 currently). This memory leak may be significant for long-running applications that make heavy use of C++ EH. + However, Mingw runtime (version 0.3 or newer) provides a mechanism + to emulate pthreads key dtors; the runtime provides a special DLL, + linked in if -mthreads option is specified, that runs the dtors in + the reverse order of registration when each thread exits. If + -mthreads option is not given, a stub is linked in instead of the + DLL, which results in memory leak. Other x86-win32 ports can use + the same technique of course to avoid the leak. + 2. The error codes returned are non-POSIX like, and cast into ints. This may cause incorrect error return due to truncation values on hw where sizeof (DWORD) > sizeof (int). + + 3. We might consider using Critical Sections instead of Windows32 + mutexes for better performance, but emulating __gthread_mutex_trylock + interface becomes more complicated (Win9x does not support + TryEnterCriticalSectioni, while NT does). - The basic framework should work well enough. */ + The basic framework should work well enough. In the long term, GCC + needs to use Structured Exception Handling on Windows32. */ #define __GTHREADS 1 #include <windows.h> #include <errno.h> +#ifdef __MINGW32__ +#include <_mingw.h> +#endif typedef DWORD __gthread_key_t; @@ -64,10 +82,24 @@ typedef HANDLE __gthread_mutex_t; #define __GTHREAD_ONCE_INIT {FALSE, -1} #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function +#if __MINGW32_MAJOR_VERSION >= 1 || \ + (__MINGW32_MAJOR_VERSION == 0 && __MINGW32_MINOR_VERSION > 2) +#define MINGW32_SUPPORTS_MT_EH 1 +extern int __mingwthr_key_dtor PROTO((DWORD, void (*) (void *))); +/* Mingw runtime >= v0.3 provides a magic variable that is set to non-zero + if -mthreads option was specified, or 0 otherwise. This is to get around + the lack of weak symbols in PE-COFF. */ +extern int _CRT_MT; +#endif + static inline int __gthread_active_p () { +#ifdef MINGW32_SUPPORTS_MT_EH + return _CRT_MT; +#else return 1; +#endif } static inline int @@ -85,48 +117,52 @@ __gthread_once (__gthread_once_t *once, void (*func) ()) (*func) (); once->done = TRUE; } - } - else - { - /* Another thread is currently executing the code, so wait for it to - finish; yield the CPU in the meantime. */ - while (! once->done) - Sleep (0); + else + { + /* Another thread is currently executing the code, so wait for it + to finish; yield the CPU in the meantime. If performance + does become an issue, the solution is to use an Event that + we wait on here (and set above), but that implies a place to + create the event before this routine is called. */ + while (! once->done) + Sleep (0); + } } return 0; } -/* Windows32 thread local keys don't support destructors; to avoid leaks, - we will have to figure something out in the future. */ +/* Windows32 thread local keys don't support destructors; this leads to + leaks, especially in threaded applications making extensive use of + C++ EH. Mingw uses a thread-support DLL to work-around this problem. */ static inline int -__gthread_key_create (__gthread_key_t *key, - void (*dtor) (void *) __attribute__((__unused__))) +__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) { int status = 0; DWORD tls_index = TlsAlloc (); if (tls_index != 0xFFFFFFFF) - *key = tls_index; + { + *key = tls_index; +#ifdef MINGW32_SUPPORTS_MT_EH + /* Mingw runtime will run the dtors in reverse order for each thread + when the thread exits. */ + status = __mingwthr_key_dtor (*key, dtor); +#endif + } else status = (int) GetLastError (); return status; } -/* Currently, this routine is never called since win32 keys don't support - destructors. Hopefully we'll find a way in the future. */ +/* Currently, this routine is called only for Mingw runtime, and if + -mthreads option is chosen to link in the thread support DLL. */ static inline int __gthread_key_dtor (__gthread_key_t key, void *ptr) { - int status = 0; - - /* Just reset the key value to zero. */ - if (ptr) - status = (TlsSetValue (key, 0) != 0) ? 0 : (int) GetLastError (); - return status; + /* Nothing needed. */ + return 0; } -/* Currently, this routine is never called since win32 keys don't support - destructors. Hopefully we'll find a way in the future. */ static inline int __gthread_key_delete (__gthread_key_t key) { @@ -142,7 +178,7 @@ __gthread_getspecific (__gthread_key_t key) static inline int __gthread_setspecific (__gthread_key_t key, const void *ptr) { - return (TlsSetValue (key, ptr) != 0) ? 0 : (int) GetLastError (); + return (TlsSetValue (key, (void*) ptr) != 0) ? 0 : (int) GetLastError (); } static inline void |