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