Replace argumentxs to composite functions with a pointer to a struct
[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 #if defined (__GNUC__)
22 #  define MAYBE_UNUSED  __attribute__((unused))
23 #else
24 #  define MAYBE_UNUSED
25 #endif
26
27 #ifndef INT16_MIN
28 # define INT16_MIN              (-32767-1)
29 #endif
30
31 #ifndef INT16_MAX
32 # define INT16_MAX              (32767)
33 #endif
34
35 #ifndef INT32_MIN
36 # define INT32_MIN              (-2147483647-1)
37 #endif
38
39 #ifndef INT32_MAX
40 # define INT32_MAX              (2147483647)
41 #endif
42
43 #ifndef UINT32_MIN
44 # define UINT32_MIN             (0)
45 #endif
46
47 #ifndef UINT32_MAX
48 # define UINT32_MAX             (4294967295U)
49 #endif
50
51 #ifndef M_PI
52 # define M_PI                   3.14159265358979323846
53 #endif
54
55 #ifdef _MSC_VER
56 /* 'inline' is available only in C++ in MSVC */
57 #   define inline __inline
58 #   define force_inline __forceinline
59 #   define noinline __declspec(noinline)
60 #elif defined __GNUC__ || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
61 #   define inline __inline__
62 #   define force_inline __inline__ __attribute__ ((__always_inline__))
63 #   define noinline __attribute__((noinline))
64 #else
65 #   ifndef force_inline
66 #      define force_inline inline
67 #   endif
68 #   ifndef noinline
69 #      define noinline
70 #   endif
71 #endif
72
73 /* GCC visibility */
74 #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(_WIN32)
75 #   define PIXMAN_EXPORT __attribute__ ((visibility("default")))
76 /* Sun Studio 8 visibility */
77 #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
78 #   define PIXMAN_EXPORT __global
79 #else
80 #   define PIXMAN_EXPORT
81 #endif
82
83 /* TLS */
84 #if defined(PIXMAN_NO_TLS)
85
86 #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                       \
87     static type name
88 #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
89     (&name)
90
91 #elif defined(TOOLCHAIN_SUPPORTS__THREAD)
92
93 #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                       \
94     static __thread type name
95 #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
96     (&name)
97
98 #elif defined(__MINGW32__)
99
100 #   define _NO_W32_PSEUDO_MODIFIERS
101 #   include <windows.h>
102
103 #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                       \
104     static volatile int tls_ ## name ## _initialized = 0;               \
105     static void *tls_ ## name ## _mutex = NULL;                         \
106     static unsigned tls_ ## name ## _index;                             \
107                                                                         \
108     static type *                                                       \
109     tls_ ## name ## _alloc (void)                                       \
110     {                                                                   \
111         type *value = calloc (1, sizeof (type));                        \
112         if (value)                                                      \
113             TlsSetValue (tls_ ## name ## _index, value);                \
114         return value;                                                   \
115     }                                                                   \
116                                                                         \
117     static force_inline type *                                          \
118     tls_ ## name ## _get (void)                                         \
119     {                                                                   \
120         type *value;                                                    \
121         if (!tls_ ## name ## _initialized)                              \
122         {                                                               \
123             if (!tls_ ## name ## _mutex)                                \
124             {                                                           \
125                 void *mutex = CreateMutexA (NULL, 0, NULL);             \
126                 if (InterlockedCompareExchangePointer (                 \
127                         &tls_ ## name ## _mutex, mutex, NULL) != NULL)  \
128                 {                                                       \
129                     CloseHandle (mutex);                                \
130                 }                                                       \
131             }                                                           \
132             WaitForSingleObject (tls_ ## name ## _mutex, 0xFFFFFFFF);   \
133             if (!tls_ ## name ## _initialized)                          \
134             {                                                           \
135                 tls_ ## name ## _index = TlsAlloc ();                   \
136                 tls_ ## name ## _initialized = 1;                       \
137             }                                                           \
138             ReleaseMutex (tls_ ## name ## _mutex);                      \
139         }                                                               \
140         if (tls_ ## name ## _index == 0xFFFFFFFF)                       \
141             return NULL;                                                \
142         value = TlsGetValue (tls_ ## name ## _index);                   \
143         if (!value)                                                     \
144             value = tls_ ## name ## _alloc ();                          \
145         return value;                                                   \
146     }
147
148 #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
149     tls_ ## name ## _get ()
150
151 #elif defined(_MSC_VER)
152
153 #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                       \
154     static __declspec(thread) type name
155 #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
156     (&name)
157
158 #elif defined(HAVE_PTHREAD_SETSPECIFIC)
159
160 #include <pthread.h>
161
162 #  define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                        \
163     static pthread_once_t tls_ ## name ## _once_control = PTHREAD_ONCE_INIT; \
164     static pthread_key_t tls_ ## name ## _key;                          \
165                                                                         \
166     static void                                                         \
167     tls_ ## name ## _destroy_value (void *value)                        \
168     {                                                                   \
169         free (value);                                                   \
170     }                                                                   \
171                                                                         \
172     static void                                                         \
173     tls_ ## name ## _make_key (void)                                    \
174     {                                                                   \
175         pthread_key_create (&tls_ ## name ## _key,                      \
176                             tls_ ## name ## _destroy_value);            \
177     }                                                                   \
178                                                                         \
179     static type *                                                       \
180     tls_ ## name ## _alloc (void)                                       \
181     {                                                                   \
182         type *value = calloc (1, sizeof (type));                        \
183         if (value)                                                      \
184             pthread_setspecific (tls_ ## name ## _key, value);          \
185         return value;                                                   \
186     }                                                                   \
187                                                                         \
188     static force_inline type *                                          \
189     tls_ ## name ## _get (void)                                         \
190     {                                                                   \
191         type *value = NULL;                                             \
192         if (pthread_once (&tls_ ## name ## _once_control,               \
193                           tls_ ## name ## _make_key) == 0)              \
194         {                                                               \
195             value = pthread_getspecific (tls_ ## name ## _key);         \
196             if (!value)                                                 \
197                 value = tls_ ## name ## _alloc ();                      \
198         }                                                               \
199         return value;                                                   \
200     }
201
202 #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
203     tls_ ## name ## _get ()
204
205 #else
206
207 #    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."
208
209 #endif