From 582fa58bba7008c2b852ba56557612866f7522d5 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Fri, 23 Apr 2010 12:34:19 -0400 Subject: Don't use __thread on MinGW. It is apparently broken. See this: http://mingw-users.1079350.n2.nabble.com/gcc-4-4-multi-threaded-exception-handling-thread-specifier-not-working-td3440749.html We'll need to support thread local storage on MinGW32 some other way. Cc: tml@iki.fi --- configure.ac | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure.ac b/configure.ac index aabe721..c9d0c66 100644 --- a/configure.ac +++ b/configure.ac @@ -524,6 +524,9 @@ support_for__thread=no AC_MSG_CHECKING(for __thread) AC_COMPILE_IFELSE([ +#ifdef __MINGW32__ +#error MinGW has broken __thread support +#endif __thread int x ; int main () { return 0; } ], support_for__thread=yes) -- cgit v1.2.3 From 5158d6740c8e2643611a623a0caa649f4b0bc5bd Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Sat, 24 Apr 2010 18:43:38 -0400 Subject: Add macros for thread local storage on MinGW 32 These macros are identical to the ones that Tor Lillqvist posted here: http://lists.freedesktop.org/archives/pixman/2010-April/000160.html with one exception: the variable is allocated with calloc() and not malloc(). Cc: tml@iki.fi --- pixman/pixman-compiler.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/pixman/pixman-compiler.h b/pixman/pixman-compiler.h index 531c8c9..1a1350d 100644 --- a/pixman/pixman-compiler.h +++ b/pixman/pixman-compiler.h @@ -77,6 +77,71 @@ # define PIXMAN_GET_THREAD_LOCAL(name) \ (&name) +#elif defined(__MINGW32__) && !defined(__WIN64) + +/* We can't include as it causes carious clashes with + * identifiers in pixman, sigh. So just declare the functions we need + * here. + */ +extern __stdcall long InterlockedCompareExchange(long volatile *, long, long); +#define InterlockedCompareExchangePointer(d,e,c) \ + (void *)InterlockedCompareExchange((long volatile *)(d),(long)(e),(long)(c)) +extern __stdcall int TlsAlloc (void); +extern __stdcall void *TlsGetValue (unsigned); +extern __stdcall int TlsSetValue (unsigned, void *); +extern __stdcall void *CreateMutexA(void *, int, char *); +extern __stdcall int CloseHandle(void *); +extern __stdcall unsigned WaitForSingleObject (void *, unsigned); +extern __stdcall int ReleaseMutex (void *); + +# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ + static volatile int tls_ ## name ## _initialized = 0; \ + static void *tls_ ## name ## _mutex = NULL; \ + static unsigned tls_ ## name ## _index; \ + \ + static type * \ + tls_ ## name ## _alloc (void) \ + { \ + type *value = calloc (1, sizeof (type)); \ + if (value) \ + TlsSetValue (tls_ ## name ## _index, value); \ + return value; \ + } \ + \ + static force_inline type * \ + tls_ ## name ## _get (void) \ + { \ + type *value; \ + if (!tls_ ## name ## _initialized) \ + { \ + if (!tls_ ## name ## _mutex) \ + { \ + void *mutex = CreateMutexA (NULL, 0, NULL); \ + if (InterlockedCompareExchangePointer ( \ + &tls_ ## name ## _mutex, mutex, NULL) != NULL) \ + { \ + CloseHandle (mutex); \ + } \ + } \ + WaitForSingleObject (tls_ ## name ## _mutex, 0xFFFFFFFF); \ + if (!tls_ ## name ## _initialized) \ + { \ + tls_ ## name ## _index = TlsAlloc (); \ + tls_ ## name ## _initialized = 1; \ + } \ + ReleaseMutex (tls_ ## name ## _mutex); \ + } \ + if (tls_ ## name ## _index == 0xFFFFFFFF) \ + return NULL; \ + value = TlsGetValue (tls_ ## name ## _index); \ + if (!value) \ + value = tls_ ## name ## _alloc (); \ + return value; \ + } + +# define PIXMAN_GET_THREAD_LOCAL(name) \ + tls_ ## name ## _get () + #elif defined(_MSC_VER) # define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ -- cgit v1.2.3