|
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 INT64_MIN |
|
52 # define INT64_MIN (-9223372036854775807-1) |
|
53 #endif |
|
54 |
|
55 #ifndef INT64_MAX |
|
56 # define INT64_MAX (9223372036854775807) |
|
57 #endif |
|
58 |
|
59 #ifndef SIZE_MAX |
|
60 # define SIZE_MAX ((size_t)-1) |
|
61 #endif |
|
62 |
|
63 |
|
64 #ifndef M_PI |
|
65 # define M_PI 3.14159265358979323846 |
|
66 #endif |
|
67 |
|
68 #ifdef _MSC_VER |
|
69 /* 'inline' is available only in C++ in MSVC */ |
|
70 # define inline __inline |
|
71 # define force_inline __forceinline |
|
72 # define noinline __declspec(noinline) |
|
73 #elif defined __GNUC__ || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) |
|
74 # define inline __inline__ |
|
75 # define force_inline __inline__ __attribute__ ((__always_inline__)) |
|
76 # define noinline __attribute__((noinline)) |
|
77 #else |
|
78 # ifndef force_inline |
|
79 # define force_inline inline |
|
80 # endif |
|
81 # ifndef noinline |
|
82 # define noinline |
|
83 # endif |
|
84 #endif |
|
85 |
|
86 /* In libxul builds we don't ever want to export pixman symbols */ |
|
87 #if 1 |
|
88 #include "prcpucfg.h" |
|
89 |
|
90 #ifdef HAVE_VISIBILITY_HIDDEN_ATTRIBUTE |
|
91 #define CVISIBILITY_HIDDEN __attribute__((visibility("hidden"))) |
|
92 #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) |
|
93 #define CVISIBILITY_HIDDEN __hidden |
|
94 #else |
|
95 #define CVISIBILITY_HIDDEN |
|
96 #endif |
|
97 |
|
98 /* In libxul builds we don't ever want to export cairo symbols */ |
|
99 #define PIXMAN_EXPORT extern CVISIBILITY_HIDDEN |
|
100 |
|
101 #else |
|
102 |
|
103 /* GCC visibility */ |
|
104 #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(_WIN32) |
|
105 # define PIXMAN_EXPORT __attribute__ ((visibility("default"))) |
|
106 /* Sun Studio 8 visibility */ |
|
107 #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) |
|
108 # define PIXMAN_EXPORT __global |
|
109 #else |
|
110 # define PIXMAN_EXPORT |
|
111 #endif |
|
112 |
|
113 #endif |
|
114 |
|
115 /* member offsets */ |
|
116 #define CONTAINER_OF(type, member, data) \ |
|
117 ((type *)(((uint8_t *)data) - offsetof (type, member))) |
|
118 |
|
119 /* TLS */ |
|
120 #if defined(PIXMAN_NO_TLS) |
|
121 |
|
122 # define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ |
|
123 static type name |
|
124 # define PIXMAN_GET_THREAD_LOCAL(name) \ |
|
125 (&name) |
|
126 |
|
127 #elif defined(TLS) |
|
128 |
|
129 # define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ |
|
130 static TLS type name |
|
131 # define PIXMAN_GET_THREAD_LOCAL(name) \ |
|
132 (&name) |
|
133 |
|
134 #elif defined(__MINGW32__) || defined(PIXMAN_USE_XP_DLL_TLS_WORKAROUND) |
|
135 |
|
136 # define _NO_W32_PSEUDO_MODIFIERS |
|
137 # include <windows.h> |
|
138 #undef IN |
|
139 #undef OUT |
|
140 |
|
141 # define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ |
|
142 static volatile int tls_ ## name ## _initialized = 0; \ |
|
143 static void *tls_ ## name ## _mutex = NULL; \ |
|
144 static unsigned tls_ ## name ## _index; \ |
|
145 \ |
|
146 static type * \ |
|
147 tls_ ## name ## _alloc (void) \ |
|
148 { \ |
|
149 type *value = calloc (1, sizeof (type)); \ |
|
150 if (value) \ |
|
151 TlsSetValue (tls_ ## name ## _index, value); \ |
|
152 return value; \ |
|
153 } \ |
|
154 \ |
|
155 static force_inline type * \ |
|
156 tls_ ## name ## _get (void) \ |
|
157 { \ |
|
158 type *value; \ |
|
159 if (!tls_ ## name ## _initialized) \ |
|
160 { \ |
|
161 if (!tls_ ## name ## _mutex) \ |
|
162 { \ |
|
163 void *mutex = CreateMutexA (NULL, 0, NULL); \ |
|
164 if (InterlockedCompareExchangePointer ( \ |
|
165 &tls_ ## name ## _mutex, mutex, NULL) != NULL) \ |
|
166 { \ |
|
167 CloseHandle (mutex); \ |
|
168 } \ |
|
169 } \ |
|
170 WaitForSingleObject (tls_ ## name ## _mutex, 0xFFFFFFFF); \ |
|
171 if (!tls_ ## name ## _initialized) \ |
|
172 { \ |
|
173 tls_ ## name ## _index = TlsAlloc (); \ |
|
174 tls_ ## name ## _initialized = 1; \ |
|
175 } \ |
|
176 ReleaseMutex (tls_ ## name ## _mutex); \ |
|
177 } \ |
|
178 if (tls_ ## name ## _index == 0xFFFFFFFF) \ |
|
179 return NULL; \ |
|
180 value = TlsGetValue (tls_ ## name ## _index); \ |
|
181 if (!value) \ |
|
182 value = tls_ ## name ## _alloc (); \ |
|
183 return value; \ |
|
184 } |
|
185 |
|
186 # define PIXMAN_GET_THREAD_LOCAL(name) \ |
|
187 tls_ ## name ## _get () |
|
188 |
|
189 #elif defined(_MSC_VER) |
|
190 |
|
191 # define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ |
|
192 static __declspec(thread) type name |
|
193 # define PIXMAN_GET_THREAD_LOCAL(name) \ |
|
194 (&name) |
|
195 |
|
196 #elif defined(HAVE_PTHREAD_SETSPECIFIC) |
|
197 |
|
198 #include <pthread.h> |
|
199 |
|
200 # define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ |
|
201 static pthread_once_t tls_ ## name ## _once_control = PTHREAD_ONCE_INIT; \ |
|
202 static pthread_key_t tls_ ## name ## _key; \ |
|
203 \ |
|
204 static void \ |
|
205 tls_ ## name ## _destroy_value (void *value) \ |
|
206 { \ |
|
207 free (value); \ |
|
208 } \ |
|
209 \ |
|
210 static void \ |
|
211 tls_ ## name ## _make_key (void) \ |
|
212 { \ |
|
213 pthread_key_create (&tls_ ## name ## _key, \ |
|
214 tls_ ## name ## _destroy_value); \ |
|
215 } \ |
|
216 \ |
|
217 static type * \ |
|
218 tls_ ## name ## _alloc (void) \ |
|
219 { \ |
|
220 type *value = calloc (1, sizeof (type)); \ |
|
221 if (value) \ |
|
222 pthread_setspecific (tls_ ## name ## _key, value); \ |
|
223 return value; \ |
|
224 } \ |
|
225 \ |
|
226 static force_inline type * \ |
|
227 tls_ ## name ## _get (void) \ |
|
228 { \ |
|
229 type *value = NULL; \ |
|
230 if (pthread_once (&tls_ ## name ## _once_control, \ |
|
231 tls_ ## name ## _make_key) == 0) \ |
|
232 { \ |
|
233 value = pthread_getspecific (tls_ ## name ## _key); \ |
|
234 if (!value) \ |
|
235 value = tls_ ## name ## _alloc (); \ |
|
236 } \ |
|
237 return value; \ |
|
238 } |
|
239 |
|
240 # define PIXMAN_GET_THREAD_LOCAL(name) \ |
|
241 tls_ ## name ## _get () |
|
242 |
|
243 #else |
|
244 |
|
245 # 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." |
|
246 |
|
247 #endif |