Use windows.h directly for mingw32 build
[profile/ivi/pixman.git] / pixman / pixman-compiler.h
1 /* Pixman uses some non-standard compiler features. This file ensures
2  * they exist
3  *
4  * The features are:
5  *
6  *    FUNC           must be defined to expand to the current function
7  *    PIXMAN_EXPORT  should be defined to whatever is required to
8  *                   export functions from a shared library
9  *    limits         limits for various types must be defined
10  *    inline         must be defined
11  *    force_inline   must be defined
12  */
13 #if defined (__GNUC__)
14 #  define FUNC     ((const char*) (__PRETTY_FUNCTION__))
15 #elif defined (__sun) || (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
16 #  define FUNC     ((const char*) (__func__))
17 #else
18 #  define FUNC     ((const char*) ("???"))
19 #endif
20
21 #ifndef INT16_MIN
22 # define INT16_MIN              (-32767-1)
23 #endif
24
25 #ifndef INT16_MAX
26 # define INT16_MAX              (32767)
27 #endif
28
29 #ifndef INT32_MIN
30 # define INT32_MIN              (-2147483647-1)
31 #endif
32
33 #ifndef INT32_MAX
34 # define INT32_MAX              (2147483647)
35 #endif
36
37 #ifndef UINT32_MIN
38 # define UINT32_MIN             (0)
39 #endif
40
41 #ifndef UINT32_MAX
42 # define UINT32_MAX             (4294967295U)
43 #endif
44
45 #ifndef M_PI
46 # define M_PI                   3.14159265358979323846
47 #endif
48
49 #ifdef _MSC_VER
50 /* 'inline' is available only in C++ in MSVC */
51 #   define inline __inline
52 #   define force_inline __forceinline
53 #elif defined __GNUC__ || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
54 #   define inline __inline__
55 #   define force_inline __inline__ __attribute__ ((__always_inline__))
56 #else
57 #   ifndef force_inline
58 #      define force_inline inline
59 #   endif
60 #endif
61
62 /* GCC visibility */
63 #if defined(__GNUC__) && __GNUC__ >= 4
64 #   define PIXMAN_EXPORT __attribute__ ((visibility("default")))
65 /* Sun Studio 8 visibility */
66 #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
67 #   define PIXMAN_EXPORT __global
68 #else
69 #   define PIXMAN_EXPORT
70 #endif
71
72 /* TLS */
73 #if defined(PIXMAN_NO_TLS)
74
75 #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                       \
76     static type name
77 #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
78     (&name)
79
80 #elif defined(TOOLCHAIN_SUPPORTS__THREAD)
81
82 #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                       \
83     static __thread type name
84 #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
85     (&name)
86
87 #elif defined(__MINGW32__)
88
89 #   define _NO_W32_PSEUDO_MODIFIERS
90 #   include <windows.h>
91
92 #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                       \
93     static volatile int tls_ ## name ## _initialized = 0;               \
94     static void *tls_ ## name ## _mutex = NULL;                         \
95     static unsigned tls_ ## name ## _index;                             \
96                                                                         \
97     static type *                                                       \
98     tls_ ## name ## _alloc (void)                                       \
99     {                                                                   \
100         type *value = calloc (1, sizeof (type));                        \
101         if (value)                                                      \
102             TlsSetValue (tls_ ## name ## _index, value);                \
103         return value;                                                   \
104     }                                                                   \
105                                                                         \
106     static force_inline type *                                          \
107     tls_ ## name ## _get (void)                                         \
108     {                                                                   \
109         type *value;                                                    \
110         if (!tls_ ## name ## _initialized)                              \
111         {                                                               \
112             if (!tls_ ## name ## _mutex)                                \
113             {                                                           \
114                 void *mutex = CreateMutexA (NULL, 0, NULL);             \
115                 if (InterlockedCompareExchangePointer (                 \
116                         &tls_ ## name ## _mutex, mutex, NULL) != NULL)  \
117                 {                                                       \
118                     CloseHandle (mutex);                                \
119                 }                                                       \
120             }                                                           \
121             WaitForSingleObject (tls_ ## name ## _mutex, 0xFFFFFFFF);   \
122             if (!tls_ ## name ## _initialized)                          \
123             {                                                           \
124                 tls_ ## name ## _index = TlsAlloc ();                   \
125                 tls_ ## name ## _initialized = 1;                       \
126             }                                                           \
127             ReleaseMutex (tls_ ## name ## _mutex);                      \
128         }                                                               \
129         if (tls_ ## name ## _index == 0xFFFFFFFF)                       \
130             return NULL;                                                \
131         value = TlsGetValue (tls_ ## name ## _index);                   \
132         if (!value)                                                     \
133             value = tls_ ## name ## _alloc ();                          \
134         return value;                                                   \
135     }
136
137 #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
138     tls_ ## name ## _get ()
139
140 #elif defined(_MSC_VER)
141
142 #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                       \
143     static __declspec(thread) type name
144 #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
145     (&name)
146
147 #elif defined(HAVE_PTHREAD_SETSPECIFIC)
148
149 #include <pthread.h>
150
151 #  define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                        \
152     static pthread_once_t tls_ ## name ## _once_control = PTHREAD_ONCE_INIT; \
153     static pthread_key_t tls_ ## name ## _key;                          \
154                                                                         \
155     static void                                                         \
156     tls_ ## name ## _destroy_value (void *value)                        \
157     {                                                                   \
158         free (value);                                                   \
159     }                                                                   \
160                                                                         \
161     static void                                                         \
162     tls_ ## name ## _make_key (void)                                    \
163     {                                                                   \
164         pthread_key_create (&tls_ ## name ## _key,                      \
165                             tls_ ## name ## _destroy_value);            \
166     }                                                                   \
167                                                                         \
168     static type *                                                       \
169     tls_ ## name ## _alloc (void)                                       \
170     {                                                                   \
171         type *value = calloc (1, sizeof (type));                        \
172         if (value)                                                      \
173             pthread_setspecific (tls_ ## name ## _key, value);          \
174         return value;                                                   \
175     }                                                                   \
176                                                                         \
177     static force_inline type *                                          \
178     tls_ ## name ## _get (void)                                         \
179     {                                                                   \
180         type *value = NULL;                                             \
181         if (pthread_once (&tls_ ## name ## _once_control,               \
182                           tls_ ## name ## _make_key) == 0)              \
183         {                                                               \
184             value = pthread_getspecific (tls_ ## name ## _key);         \
185             if (!value)                                                 \
186                 value = tls_ ## name ## _alloc ();                      \
187         }                                                               \
188         return value;                                                   \
189     }
190
191 #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
192     tls_ ## name ## _get ()
193
194 #else
195
196 #    error "Unknown thread local support for this system. Pixman will not work with multiple threads. Define PIXMAN_NO_TLS to acknowledge and accept this limitation and compile pixman without thread-safety support."
197
198 #endif