> A related question: Is there any support in the Windows versions of > GCC for either __thread or __declspec(thread)?
There is support for __thread (it gets recognized by the configure script), but I strongly suspect it might be broken. I think I would prefer to just use explicit code, as in the pthread case. In fact, I was just hacking on that last weekend. Below is what I came up with before abandoning it... I.e. this is not really tested that well, as the thread-local storage is used, if I understood correctly, only when SSE2 is used, and as seen in another thread, SSE2 intrinsics are broken in MinGW, so I disable it anyway currently... This looks more complex than I like. The complexity comes mostly from the way the equivalent of pthread_once() is implemented; I got this idea from http://stackoverflow.com/questions/631879/library-initialization-pthread-once-in-win32-implementation . Also, not being able to just #include <windows.h> is a pain. (That's the reason for the !defined(__WIN64); on 64-bit Windows the Win32 API declarations would be slightly different.) This has to be before the check for if defined(TOOLCHAIN_SUPPORTS__THREAD), as that gets set for MinGW, too. #if defined(__MINGW32__) && !defined(__WIN64) /* We can't include <windows.h> 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 = malloc (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 () --tml _______________________________________________ Pixman mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/pixman
