11176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/* Pixman uses some non-standard compiler features. This file ensures 21176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * they exist 31176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * 41176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * The features are: 51176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * 61176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * FUNC must be defined to expand to the current function 71176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * PIXMAN_EXPORT should be defined to whatever is required to 81176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * export functions from a shared library 91176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * limits limits for various types must be defined 101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * inline must be defined 111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * force_inline must be defined 121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */ 131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#if defined (__GNUC__) 141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define FUNC ((const char*) (__PRETTY_FUNCTION__)) 151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#elif defined (__sun) || (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) 161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define FUNC ((const char*) (__func__)) 171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#else 181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define FUNC ((const char*) ("???")) 191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#if defined (__GNUC__) 221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define unlikely(expr) __builtin_expect ((expr), 0) 231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#else 241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define unlikely(expr) (expr) 251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#if defined (__GNUC__) 281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define MAYBE_UNUSED __attribute__((unused)) 291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#else 301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define MAYBE_UNUSED 311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#ifndef INT16_MIN 341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define INT16_MIN (-32767-1) 351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#ifndef INT16_MAX 381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define INT16_MAX (32767) 391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#ifndef INT32_MIN 421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define INT32_MIN (-2147483647-1) 431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#ifndef INT32_MAX 461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define INT32_MAX (2147483647) 471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#ifndef UINT32_MIN 501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define UINT32_MIN (0) 511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#ifndef UINT32_MAX 541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define UINT32_MAX (4294967295U) 551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#ifndef INT64_MIN 581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define INT64_MIN (-9223372036854775807-1) 591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#ifndef INT64_MAX 621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define INT64_MAX (9223372036854775807) 631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#ifndef SIZE_MAX 661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define SIZE_MAX ((size_t)-1) 671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#ifndef M_PI 711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define M_PI 3.14159265358979323846 721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#ifdef _MSC_VER 751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/* 'inline' is available only in C++ in MSVC */ 761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define inline __inline 771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define force_inline __forceinline 781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define noinline __declspec(noinline) 791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#elif defined __GNUC__ || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) 801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define inline __inline__ 811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define force_inline __inline__ __attribute__ ((__always_inline__)) 821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define noinline __attribute__((noinline)) 831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#else 841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# ifndef force_inline 851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define force_inline inline 861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# endif 871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# ifndef noinline 881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define noinline 891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# endif 901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/* GCC visibility */ 931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(_WIN32) 941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define PIXMAN_EXPORT __attribute__ ((visibility("default"))) 951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/* Sun Studio 8 visibility */ 961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) 971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define PIXMAN_EXPORT __global 981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#else 991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define PIXMAN_EXPORT 1001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 1011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/* member offsets */ 1031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define CONTAINER_OF(type, member, data) \ 1041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck ((type *)(((uint8_t *)data) - offsetof (type, member))) 1051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/* TLS */ 1071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#if defined(PIXMAN_NO_TLS) 1081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ 1101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck static type name 1111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define PIXMAN_GET_THREAD_LOCAL(name) \ 1121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (&name) 1131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#elif defined(TLS) 1151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ 1171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck static TLS type name 1181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define PIXMAN_GET_THREAD_LOCAL(name) \ 1191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (&name) 1201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#elif defined(__MINGW32__) 1221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define _NO_W32_PSEUDO_MODIFIERS 1241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# include <windows.h> 1251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ 1271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck static volatile int tls_ ## name ## _initialized = 0; \ 1281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck static void *tls_ ## name ## _mutex = NULL; \ 1291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck static unsigned tls_ ## name ## _index; \ 1301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck \ 1311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck static type * \ 1321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tls_ ## name ## _alloc (void) \ 1331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { \ 1341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck type *value = calloc (1, sizeof (type)); \ 1351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (value) \ 1361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck TlsSetValue (tls_ ## name ## _index, value); \ 1371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return value; \ 1381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } \ 1391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck \ 1401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck static force_inline type * \ 1411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tls_ ## name ## _get (void) \ 1421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { \ 1431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck type *value; \ 1441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (!tls_ ## name ## _initialized) \ 1451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { \ 1461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (!tls_ ## name ## _mutex) \ 1471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { \ 1481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck void *mutex = CreateMutexA (NULL, 0, NULL); \ 1491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (InterlockedCompareExchangePointer ( \ 1501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck &tls_ ## name ## _mutex, mutex, NULL) != NULL) \ 1511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { \ 1521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck CloseHandle (mutex); \ 1531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } \ 1541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } \ 1551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck WaitForSingleObject (tls_ ## name ## _mutex, 0xFFFFFFFF); \ 1561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (!tls_ ## name ## _initialized) \ 1571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { \ 1581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tls_ ## name ## _index = TlsAlloc (); \ 1591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tls_ ## name ## _initialized = 1; \ 1601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } \ 1611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck ReleaseMutex (tls_ ## name ## _mutex); \ 1621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } \ 1631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (tls_ ## name ## _index == 0xFFFFFFFF) \ 1641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return NULL; \ 1651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck value = TlsGetValue (tls_ ## name ## _index); \ 1661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (!value) \ 1671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck value = tls_ ## name ## _alloc (); \ 1681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return value; \ 1691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 1701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define PIXMAN_GET_THREAD_LOCAL(name) \ 1721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tls_ ## name ## _get () 1731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#elif defined(_MSC_VER) 1751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ 1771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck static __declspec(thread) type name 1781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define PIXMAN_GET_THREAD_LOCAL(name) \ 1791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (&name) 1801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#elif defined(HAVE_PTHREAD_SETSPECIFIC) 1821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <pthread.h> 1841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ 1861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck static pthread_once_t tls_ ## name ## _once_control = PTHREAD_ONCE_INIT; \ 1871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck static pthread_key_t tls_ ## name ## _key; \ 1881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck \ 1891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck static void \ 1901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tls_ ## name ## _destroy_value (void *value) \ 1911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { \ 1921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck free (value); \ 1931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } \ 1941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck \ 1951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck static void \ 1961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tls_ ## name ## _make_key (void) \ 1971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { \ 1981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pthread_key_create (&tls_ ## name ## _key, \ 1991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tls_ ## name ## _destroy_value); \ 2001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } \ 2011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck \ 2021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck static type * \ 2031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tls_ ## name ## _alloc (void) \ 2041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { \ 2051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck type *value = calloc (1, sizeof (type)); \ 2061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (value) \ 2071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pthread_setspecific (tls_ ## name ## _key, value); \ 2081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return value; \ 2091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } \ 2101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck \ 2111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck static force_inline type * \ 2121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tls_ ## name ## _get (void) \ 2131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { \ 2141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck type *value = NULL; \ 2151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (pthread_once (&tls_ ## name ## _once_control, \ 2161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tls_ ## name ## _make_key) == 0) \ 2171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { \ 2181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck value = pthread_getspecific (tls_ ## name ## _key); \ 2191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (!value) \ 2201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck value = tls_ ## name ## _alloc (); \ 2211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } \ 2221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck return value; \ 2231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 2241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# define PIXMAN_GET_THREAD_LOCAL(name) \ 2261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck tls_ ## name ## _get () 2271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#else 2291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck# 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." 2311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 2321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 233