aboutsummaryrefslogtreecommitdiff
path: root/gcc/gthr-win32.h
diff options
context:
space:
mode:
authorMumit Khan <khan@xraylith.wisc.edu>2000-01-04 21:11:17 +0000
committerMumit Khan <khan@xraylith.wisc.edu>2000-01-04 21:11:17 +0000
commit8278894bc594ce0ebefeb1bd78f45b32dc13651b (patch)
tree2d5ea60f0dc75c966fafac88e66f0f17507fca9f /gcc/gthr-win32.h
parent197802e5854d494a2720195504a5f63b49f9f762 (diff)
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: https://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.h92
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