aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Tietz <kai.tietz@onevision.com>2009-05-30 09:05:56 +0000
committerKai Tietz <ktietz@gcc.gnu.org>2009-05-30 11:05:56 +0200
commita1bda0d7e8e5f4aac6287f4f607952f056c8bedf (patch)
treef42b3ca66b386fb3dfc7ef132a6272431158fccf
parentec5c6f4a5fa9bba3cff80441b46b9ed6e16fa961 (diff)
downloadgcc-a1bda0d7e8e5f4aac6287f4f607952f056c8bedf.zip
gcc-a1bda0d7e8e5f4aac6287f4f607952f056c8bedf.tar.gz
gcc-a1bda0d7e8e5f4aac6287f4f607952f056c8bedf.tar.bz2
mingw-tls.c: New file.
2009-05-30 Kai Tietz <kai.tietz@onevision.com> * config/i386/mingw-tls.c: New file. * config/i386/t-gthr-win32 (LIB2FUNCS_EXTRA): Add mingw-tls.c file. * gthr-win32.h (MINGW32_SUPPORTS_MT_EH): Define it for targets defining _WIN32 but not __CYGWIN__. From-SVN: r148000
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/i386/mingw-tls.c233
-rw-r--r--gcc/config/i386/t-gthr-win324
-rw-r--r--gcc/gthr-win32.h5
4 files changed, 245 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 17c0715..6c28aeb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2009-05-30 Kai Tietz <kai.tietz@onevision.com>
+
+ * config/i386/mingw-tls.c: New file.
+ * config/i386/t-gthr-win32 (LIB2FUNCS_EXTRA): Add
+ mingw-tls.c file.
+ * gthr-win32.h (MINGW32_SUPPORTS_MT_EH): Define
+ it for targets defining _WIN32 but not __CYGWIN__.
+
2009-05-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* configure.ac: Add MPC support.
diff --git a/gcc/config/i386/mingw-tls.c b/gcc/config/i386/mingw-tls.c
new file mode 100644
index 0000000..7a5c775
--- /dev/null
+++ b/gcc/config/i386/mingw-tls.c
@@ -0,0 +1,233 @@
+/* Catch and clean up data allocated in TLS.
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2009 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* This part is based on the implementation of Mumit Khan <khan@nanotech.wisc.edu>
+ * provided to mingw under public domain and ported for libgcc by Kai Tietz.
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+#include <stdlib.h>
+
+/* The list of threads active with key/dtor pairs. */
+typedef struct __mingwthr_key {
+ DWORD key;
+ void (*dtor) (void *);
+ struct __mingwthr_key *next;
+} __mingwthr_key_t;
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+/* Possibly we could define this here for none MT too and avoid use of
+ mingwthrd.a at all, but well ... */
+#ifdef SHARED
+__declspec(dllexport)
+int _CRT_MT = 1;
+#else
+#if 0
+int _CRT_MT = 0;
+#endif
+#endif
+
+/* Static functions for libgcc. */
+#ifndef SHARED
+
+int __mingwthr_key_dtor (DWORD,void (*dtor)(void *));
+int __mingwthr_remove_key_dtor (DWORD);
+
+
+int
+__mingwthr_key_dtor (DWORD key __attribute__ ((__unused__)),
+ void (*dtor) (void *) __attribute__ ((__unused__)))
+{
+ return 0;
+}
+
+int
+__mingwthr_remove_key_dtor (DWORD key __attribute__ ((__unused__)))
+{
+ return 0;
+}
+
+#else
+/* Shared functions for libgcc. */
+
+/* Prototypes. */
+__declspec(dllexport) int __mingwthr_key_dtor (DWORD key, void (*) (void *));
+__declspec(dllexport) int __mingwthr_remove_key_dtor (DWORD);
+BOOL APIENTRY DllMain (HANDLE, DWORD, LPVOID);
+
+
+/* To protect the thread/key association data structure modifications. */
+static CRITICAL_SECTION __mingwthr_cs;
+static __mingwthr_key_t *key_dtor_list;
+
+/*
+ * __mingwthr_key_add:
+ *
+ * Add key/dtor association for this thread. If the thread entry does not
+ * exist, create a new one and add to the head of the threads list; add
+ * the new assoc at the head of the keys list.
+ *
+ */
+
+static int
+___mingwthr_add_key_dtor (DWORD key, void (*dtor) (void *))
+{
+ __mingwthr_key_t *new_key;
+
+ new_key = (__mingwthr_key_t *) calloc (1, sizeof (__mingwthr_key_t));
+ if (new_key == NULL)
+ return -1;
+
+ new_key->key = key;
+ new_key->dtor = dtor;
+
+ EnterCriticalSection (&__mingwthr_cs);
+
+ new_key->next = key_dtor_list;
+ key_dtor_list = new_key;
+
+ LeaveCriticalSection (&__mingwthr_cs);
+
+ return 0;
+}
+
+static int
+___mingwthr_remove_key_dtor (DWORD key)
+{
+ __mingwthr_key_t *prev_key;
+ __mingwthr_key_t *cur_key;
+
+ EnterCriticalSection (&__mingwthr_cs);
+
+ prev_key = NULL;
+ cur_key = key_dtor_list;
+
+ while (cur_key != NULL)
+ {
+ if( cur_key->key == key )
+ {
+ /* take key/dtor out of list */
+ if (prev_key == NULL)
+ key_dtor_list = cur_key->next;
+ else
+ prev_key->next = cur_key->next;
+
+ free (cur_key);
+ break;
+ }
+
+ prev_key = cur_key;
+ cur_key = cur_key->next;
+ }
+
+ LeaveCriticalSection (&__mingwthr_cs);
+
+ return 0;
+}
+
+/*
+ * __mingwthr_run_key_dtors (void):
+ *
+ * Callback from DllMain when thread detaches to clean up the key
+ * storage.
+ *
+ * Note that this does not delete the key itself, but just runs
+ * the dtor if the current value are both non-NULL. Note that the
+ * keys with NULL dtors are not added by __mingwthr_key_dtor, the
+ * only public interface, so we don't need to check.
+ *
+ */
+
+static void
+__mingwthr_run_key_dtors (void)
+{
+ __mingwthr_key_t *keyp;
+
+ EnterCriticalSection (&__mingwthr_cs);
+
+ for (keyp = key_dtor_list; keyp; )
+ {
+ LPVOID value = TlsGetValue (keyp->key);
+ if (GetLastError () == ERROR_SUCCESS)
+ {
+ if (value)
+ (*keyp->dtor) (value);
+ }
+ keyp = keyp->next;
+ }
+
+ LeaveCriticalSection (&__mingwthr_cs);
+}
+
+/*
+ * __mingwthr_register_key_dtor (DWORD key, void (*dtor) (void *))
+ *
+ * Public interface called by C++ exception handling mechanism in
+ * libgcc (cf: __gthread_key_create).
+ *
+ */
+
+__declspec(dllexport)
+int
+__mingwthr_key_dtor (DWORD key, void (*dtor) (void *))
+{
+ if (dtor)
+ return ___mingwthr_add_key_dtor (key, dtor);
+
+ return 0;
+}
+
+__declspec(dllexport)
+int
+__mingwthr_remove_key_dtor (DWORD key)
+{
+ return ___mingwthr_remove_key_dtor (key);
+}
+
+BOOL APIENTRY
+DllMain (HANDLE hDllHandle __attribute__ ((__unused__)),
+ DWORD reason /* Reason this function is being called. */,
+ LPVOID reserved __attribute__ ((__unused__)))
+{
+ switch (reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ InitializeCriticalSection (&__mingwthr_cs);
+ break;
+
+ case DLL_PROCESS_DETACH:
+ __mingwthr_run_key_dtors ();
+ DeleteCriticalSection (&__mingwthr_cs);
+ break;
+
+ case DLL_THREAD_ATTACH:
+ break;
+
+ case DLL_THREAD_DETACH:
+ __mingwthr_run_key_dtors ();
+ break;
+ }
+ return TRUE;
+}
+#endif
+#endif
diff --git a/gcc/config/i386/t-gthr-win32 b/gcc/config/i386/t-gthr-win32
index 204a485..e3977ce 100644
--- a/gcc/config/i386/t-gthr-win32
+++ b/gcc/config/i386/t-gthr-win32
@@ -1,3 +1,3 @@
# We hide calls to w32api needed for w32 thread support here:
-LIB2FUNCS_EXTRA = $(srcdir)/config/i386/gthr-win32.c
-
+LIB2FUNCS_EXTRA = $(srcdir)/config/i386/gthr-win32.c \
+ $(srcdir)/config/i386/mingw-tls.c
diff --git a/gcc/gthr-win32.h b/gcc/gthr-win32.h
index a4fd32b..74ac617 100644
--- a/gcc/gthr-win32.h
+++ b/gcc/gthr-win32.h
@@ -361,15 +361,14 @@ typedef struct {
__gthread_recursive_mutex_init_function
#define __GTHREAD_RECURSIVE_MUTEX_INIT_DEFAULT {-1, 0, 0, 0}
-#if __MINGW32_MAJOR_VERSION >= 1 || \
- (__MINGW32_MAJOR_VERSION == 0 && __MINGW32_MINOR_VERSION > 2)
+#if defined (_WIN32) && !defined(__CYGWIN__)
#define MINGW32_SUPPORTS_MT_EH 1
/* Mingw runtime >= v0.3 provides a magic variable that is set to nonzero
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;
extern int __mingwthr_key_dtor (unsigned long, void (*) (void *));
-#endif /* __MINGW32__ version */
+#endif /* _WIN32 && !__CYGWIN__ */
/* The Windows95 kernel does not export InterlockedCompareExchange.
This provides a substitute. When building apps that reference