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