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 /* GCC visibility */ 93 #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(_WIN32) 94 # define PIXMAN_EXPORT __attribute__ ((visibility("default"))) 95 /* Sun Studio 8 visibility */ 96 #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) 97 # define PIXMAN_EXPORT __global 98 #elif defined (_MSC_VER) || defined(__MINGW32__) 99 # define PIXMAN_EXPORT PIXMAN_API 100 #else 101 # define PIXMAN_EXPORT 102 #endif 103 104 /* member offsets */ 105 #define CONTAINER_OF(type, member, data) \ 106 ((type *)(((uint8_t *)data) - offsetof (type, member))) 107 108 /* TLS */ 109 #if defined(PIXMAN_NO_TLS) 110 111 # define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ 112 static type name 113 # define PIXMAN_GET_THREAD_LOCAL(name) \ 114 (&name) 115 116 #elif defined(TLS) 117 118 # define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ 119 static TLS type name 120 # define PIXMAN_GET_THREAD_LOCAL(name) \ 121 (&name) 122 123 #elif defined(__MINGW32__) 124 125 # define _NO_W32_PSEUDO_MODIFIERS 126 # include <windows.h> 127 128 # define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ 129 static volatile int tls_ ## name ## _initialized = 0; \ 130 static void *tls_ ## name ## _mutex = NULL; \ 131 static unsigned tls_ ## name ## _index; \ 132 \ 133 static type * \ 134 tls_ ## name ## _alloc (void) \ 135 { \ 136 type *value = calloc (1, sizeof (type)); \ 137 if (value) \ 138 TlsSetValue (tls_ ## name ## _index, value); \ 139 return value; \ 140 } \ 141 \ 142 static force_inline type * \ 143 tls_ ## name ## _get (void) \ 144 { \ 145 type *value; \ 146 if (!tls_ ## name ## _initialized) \ 147 { \ 148 if (!tls_ ## name ## _mutex) \ 149 { \ 150 void *mutex = CreateMutexA (NULL, 0, NULL); \ 151 if (InterlockedCompareExchangePointer ( \ 152 &tls_ ## name ## _mutex, mutex, NULL) != NULL) \ 153 { \ 154 CloseHandle (mutex); \ 155 } \ 156 } \ 157 WaitForSingleObject (tls_ ## name ## _mutex, 0xFFFFFFFF); \ 158 if (!tls_ ## name ## _initialized) \ 159 { \ 160 tls_ ## name ## _index = TlsAlloc (); \ 161 tls_ ## name ## _initialized = 1; \ 162 } \ 163 ReleaseMutex (tls_ ## name ## _mutex); \ 164 } \ 165 if (tls_ ## name ## _index == 0xFFFFFFFF) \ 166 return NULL; \ 167 value = TlsGetValue (tls_ ## name ## _index); \ 168 if (!value) \ 169 value = tls_ ## name ## _alloc (); \ 170 return value; \ 171 } 172 173 # define PIXMAN_GET_THREAD_LOCAL(name) \ 174 tls_ ## name ## _get () 175 176 #elif defined(_MSC_VER) 177 178 # define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ 179 static __declspec(thread) type name 180 # define PIXMAN_GET_THREAD_LOCAL(name) \ 181 (&name) 182 183 #elif defined(HAVE_PTHREADS) 184 185 #include <pthread.h> 186 187 # define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ 188 static pthread_once_t tls_ ## name ## _once_control = PTHREAD_ONCE_INIT; \ 189 static pthread_key_t tls_ ## name ## _key; \ 190 \ 191 static void \ 192 tls_ ## name ## _destroy_value (void *value) \ 193 { \ 194 free (value); \ 195 } \ 196 \ 197 static void \ 198 tls_ ## name ## _make_key (void) \ 199 { \ 200 pthread_key_create (&tls_ ## name ## _key, \ 201 tls_ ## name ## _destroy_value); \ 202 } \ 203 \ 204 static type * \ 205 tls_ ## name ## _alloc (void) \ 206 { \ 207 type *value = calloc (1, sizeof (type)); \ 208 if (value) \ 209 pthread_setspecific (tls_ ## name ## _key, value); \ 210 return value; \ 211 } \ 212 \ 213 static force_inline type * \ 214 tls_ ## name ## _get (void) \ 215 { \ 216 type *value = NULL; \ 217 if (pthread_once (&tls_ ## name ## _once_control, \ 218 tls_ ## name ## _make_key) == 0) \ 219 { \ 220 value = pthread_getspecific (tls_ ## name ## _key); \ 221 if (!value) \ 222 value = tls_ ## name ## _alloc (); \ 223 } \ 224 return value; \ 225 } 226 227 # define PIXMAN_GET_THREAD_LOCAL(name) \ 228 tls_ ## name ## _get () 229 230 #else 231 232 # 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." 233 234 #endif 235