aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/config/i386/crtdll.h5
-rw-r--r--gcc/config/i386/cygwin.h5
-rw-r--r--gcc/config/i386/mingw32.h8
-rw-r--r--gcc/gthr-win32.h92
-rw-r--r--gcc/invoke.texi11
6 files changed, 99 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 159036699fb..d6909f6b278 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+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.
+
2000-01-04 David Edelsohn <edelsohn@gnu.org>
* rs6000/sysv4.h (ASM_OUTPUT_DEF): Undefine.
diff --git a/gcc/config/i386/crtdll.h b/gcc/config/i386/crtdll.h
index 6ec3f50d79a..ae353c30599 100644
--- a/gcc/config/i386/crtdll.h
+++ b/gcc/config/i386/crtdll.h
@@ -3,7 +3,7 @@
as distinct from winnt.h, which is used to build GCC for use with a
windows style library and tool set and uses the Microsoft tools.
This variant uses CRTDLL.DLL insted of MSVCRTDLL.DLL.
- Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -32,7 +32,8 @@ Boston, MA 02111-1307, USA. */
-Asystem(winnt) -Acpu(i386) -Amachine(i386)"
#undef LIBGCC_SPEC
-#define LIBGCC_SPEC "-lmingw32 -lgcc -lmoldname -lcrtdll"
+#define LIBGCC_SPEC \
+ "%{mthreads:-lmingwthrd} -lmingw32 -lgcc -lmoldname -lcrtdll"
/* Specify a different entry point when linking a DLL */
#undef STARTFILE_SPEC
diff --git a/gcc/config/i386/cygwin.h b/gcc/config/i386/cygwin.h
index 20dc576524d..2a3e82d2f75 100644
--- a/gcc/config/i386/cygwin.h
+++ b/gcc/config/i386/cygwin.h
@@ -2,7 +2,7 @@
hosting on Windows NT 3.x, using a Unix style C library and tools,
as distinct from winnt.h, which is used to build GCC for use with a
windows style library and tool set and uses the Microsoft tools.
- Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1995-2000 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -51,7 +51,8 @@ Boston, MA 02111-1307, USA. */
{ "console", -MASK_WINDOWS, "Create console application" }, \
{ "dll", MASK_DLL, "Generate code for a DLL" }, \
{ "nop-fun-dllimport", MASK_NOP_FUN_DLLIMPORT, "Ignore dllimport for functions" }, \
-{ "no-nop-fun-dllimport", -MASK_NOP_FUN_DLLIMPORT, "" },
+{ "no-nop-fun-dllimport", -MASK_NOP_FUN_DLLIMPORT, "" }, \
+{ "threads", 0, "Use Mingw-specific thread support" },
/* Support the __declspec keyword by turning them into attributes.
diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h
index 15528e669c1..9516065dc19 100644
--- a/gcc/config/i386/mingw32.h
+++ b/gcc/config/i386/mingw32.h
@@ -2,7 +2,7 @@
hosting on Windows32, using GNU tools and the Windows32 API Library,
as distinct from winnt.h, which is used to build GCC for use with a
windows style library and tool set and uses the Microsoft tools.
- Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1997-2000 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -45,7 +45,8 @@ Boston, MA 02111-1307, USA. */
#define STANDARD_INCLUDE_COMPONENT "MINGW32"
#undef CPP_SPEC
-#define CPP_SPEC "-remap %(cpp_cpu) %{posix:-D_POSIX_SOURCE}"
+#define CPP_SPEC \
+ "-remap %(cpp_cpu) %{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT}"
/* For Windows applications, include more libraries, but always include
kernel32. */
@@ -55,7 +56,8 @@ Boston, MA 02111-1307, USA. */
/* Include in the mingw32 libraries with libgcc */
#undef LIBGCC_SPEC
-#define LIBGCC_SPEC "-lmingw32 -lgcc -lmoldname -lmsvcrt"
+#define LIBGCC_SPEC \
+ "%{mthreads:-lmingwthrd} -lmingw32 -lgcc -lmoldname -lmsvcrt"
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{mdll:dllcrt2%O%s} %{!mdll:crt2%O%s} %{pg:gcrt2%O%s}"
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
diff --git a/gcc/invoke.texi b/gcc/invoke.texi
index 3fbcba6ab85..25dd6ed31c2 100644
--- a/gcc/invoke.texi
+++ b/gcc/invoke.texi
@@ -1,4 +1,4 @@
-@c Copyright (C) 1988, 89, 92-98, 1999 Free Software Foundation, Inc.
+@c Copyright (C) 1988, 89, 92-99, 2000 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -360,6 +360,7 @@ in the following sections.
-mreg-alloc=@var{list} -mregparm=@var{num}
-malign-jumps=@var{num} -malign-loops=@var{num}
-malign-functions=@var{num} -mpreferred-stack-boundary=@var{num}
+-mthreads
@emph{HPPA Options}
-march=@var{architecture type}
@@ -5945,6 +5946,14 @@ This extra alignment does consume extra stack space. Code that is sensitive
to stack space usage, such as embedded systems and operating system kernels,
may want to reduce the preferred alignment to
@samp{-mpreferred-stack-boundary=2}.
+
+@item -mthreads
+@kindex -mthreads
+Support thread-safe exception handling on @samp{Mingw32}. Code that relies
+on thread-safe exception handling must compile and link all code with the
+@samp{-mthreads} option. When compiling, @samp{-mthreads} defines
+@samp{-D_MT}; when linking, it links in a special thread helper library
+@samp{-lmingwthrd} which cleans up per thread exception handling data.
@end table
@node HPPA Options