michael@0: /* Pixman uses some non-standard compiler features. This file ensures michael@0: * they exist michael@0: * michael@0: * The features are: michael@0: * michael@0: * FUNC must be defined to expand to the current function michael@0: * PIXMAN_EXPORT should be defined to whatever is required to michael@0: * export functions from a shared library michael@0: * limits limits for various types must be defined michael@0: * inline must be defined michael@0: * force_inline must be defined michael@0: */ michael@0: #if defined (__GNUC__) michael@0: # define FUNC ((const char*) (__PRETTY_FUNCTION__)) michael@0: #elif defined (__sun) || (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) michael@0: # define FUNC ((const char*) (__func__)) michael@0: #else michael@0: # define FUNC ((const char*) ("???")) michael@0: #endif michael@0: michael@0: #if defined (__GNUC__) michael@0: # define MAYBE_UNUSED __attribute__((unused)) michael@0: #else michael@0: # define MAYBE_UNUSED michael@0: #endif michael@0: michael@0: #ifndef INT16_MIN michael@0: # define INT16_MIN (-32767-1) michael@0: #endif michael@0: michael@0: #ifndef INT16_MAX michael@0: # define INT16_MAX (32767) michael@0: #endif michael@0: michael@0: #ifndef INT32_MIN michael@0: # define INT32_MIN (-2147483647-1) michael@0: #endif michael@0: michael@0: #ifndef INT32_MAX michael@0: # define INT32_MAX (2147483647) michael@0: #endif michael@0: michael@0: #ifndef UINT32_MIN michael@0: # define UINT32_MIN (0) michael@0: #endif michael@0: michael@0: #ifndef UINT32_MAX michael@0: # define UINT32_MAX (4294967295U) michael@0: #endif michael@0: michael@0: #ifndef INT64_MIN michael@0: # define INT64_MIN (-9223372036854775807-1) michael@0: #endif michael@0: michael@0: #ifndef INT64_MAX michael@0: # define INT64_MAX (9223372036854775807) michael@0: #endif michael@0: michael@0: #ifndef SIZE_MAX michael@0: # define SIZE_MAX ((size_t)-1) michael@0: #endif michael@0: michael@0: michael@0: #ifndef M_PI michael@0: # define M_PI 3.14159265358979323846 michael@0: #endif michael@0: michael@0: #ifdef _MSC_VER michael@0: /* 'inline' is available only in C++ in MSVC */ michael@0: # define inline __inline michael@0: # define force_inline __forceinline michael@0: # define noinline __declspec(noinline) michael@0: #elif defined __GNUC__ || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) michael@0: # define inline __inline__ michael@0: # define force_inline __inline__ __attribute__ ((__always_inline__)) michael@0: # define noinline __attribute__((noinline)) michael@0: #else michael@0: # ifndef force_inline michael@0: # define force_inline inline michael@0: # endif michael@0: # ifndef noinline michael@0: # define noinline michael@0: # endif michael@0: #endif michael@0: michael@0: /* In libxul builds we don't ever want to export pixman symbols */ michael@0: #if 1 michael@0: #include "prcpucfg.h" michael@0: michael@0: #ifdef HAVE_VISIBILITY_HIDDEN_ATTRIBUTE michael@0: #define CVISIBILITY_HIDDEN __attribute__((visibility("hidden"))) michael@0: #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) michael@0: #define CVISIBILITY_HIDDEN __hidden michael@0: #else michael@0: #define CVISIBILITY_HIDDEN michael@0: #endif michael@0: michael@0: /* In libxul builds we don't ever want to export cairo symbols */ michael@0: #define PIXMAN_EXPORT extern CVISIBILITY_HIDDEN michael@0: michael@0: #else michael@0: michael@0: /* GCC visibility */ michael@0: #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(_WIN32) michael@0: # define PIXMAN_EXPORT __attribute__ ((visibility("default"))) michael@0: /* Sun Studio 8 visibility */ michael@0: #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) michael@0: # define PIXMAN_EXPORT __global michael@0: #else michael@0: # define PIXMAN_EXPORT michael@0: #endif michael@0: michael@0: #endif michael@0: michael@0: /* member offsets */ michael@0: #define CONTAINER_OF(type, member, data) \ michael@0: ((type *)(((uint8_t *)data) - offsetof (type, member))) michael@0: michael@0: /* TLS */ michael@0: #if defined(PIXMAN_NO_TLS) michael@0: michael@0: # define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ michael@0: static type name michael@0: # define PIXMAN_GET_THREAD_LOCAL(name) \ michael@0: (&name) michael@0: michael@0: #elif defined(TLS) michael@0: michael@0: # define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ michael@0: static TLS type name michael@0: # define PIXMAN_GET_THREAD_LOCAL(name) \ michael@0: (&name) michael@0: michael@0: #elif defined(__MINGW32__) || defined(PIXMAN_USE_XP_DLL_TLS_WORKAROUND) michael@0: michael@0: # define _NO_W32_PSEUDO_MODIFIERS michael@0: # include michael@0: #undef IN michael@0: #undef OUT michael@0: michael@0: # define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ michael@0: static volatile int tls_ ## name ## _initialized = 0; \ michael@0: static void *tls_ ## name ## _mutex = NULL; \ michael@0: static unsigned tls_ ## name ## _index; \ michael@0: \ michael@0: static type * \ michael@0: tls_ ## name ## _alloc (void) \ michael@0: { \ michael@0: type *value = calloc (1, sizeof (type)); \ michael@0: if (value) \ michael@0: TlsSetValue (tls_ ## name ## _index, value); \ michael@0: return value; \ michael@0: } \ michael@0: \ michael@0: static force_inline type * \ michael@0: tls_ ## name ## _get (void) \ michael@0: { \ michael@0: type *value; \ michael@0: if (!tls_ ## name ## _initialized) \ michael@0: { \ michael@0: if (!tls_ ## name ## _mutex) \ michael@0: { \ michael@0: void *mutex = CreateMutexA (NULL, 0, NULL); \ michael@0: if (InterlockedCompareExchangePointer ( \ michael@0: &tls_ ## name ## _mutex, mutex, NULL) != NULL) \ michael@0: { \ michael@0: CloseHandle (mutex); \ michael@0: } \ michael@0: } \ michael@0: WaitForSingleObject (tls_ ## name ## _mutex, 0xFFFFFFFF); \ michael@0: if (!tls_ ## name ## _initialized) \ michael@0: { \ michael@0: tls_ ## name ## _index = TlsAlloc (); \ michael@0: tls_ ## name ## _initialized = 1; \ michael@0: } \ michael@0: ReleaseMutex (tls_ ## name ## _mutex); \ michael@0: } \ michael@0: if (tls_ ## name ## _index == 0xFFFFFFFF) \ michael@0: return NULL; \ michael@0: value = TlsGetValue (tls_ ## name ## _index); \ michael@0: if (!value) \ michael@0: value = tls_ ## name ## _alloc (); \ michael@0: return value; \ michael@0: } michael@0: michael@0: # define PIXMAN_GET_THREAD_LOCAL(name) \ michael@0: tls_ ## name ## _get () michael@0: michael@0: #elif defined(_MSC_VER) michael@0: michael@0: # define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ michael@0: static __declspec(thread) type name michael@0: # define PIXMAN_GET_THREAD_LOCAL(name) \ michael@0: (&name) michael@0: michael@0: #elif defined(HAVE_PTHREAD_SETSPECIFIC) michael@0: michael@0: #include michael@0: michael@0: # define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ michael@0: static pthread_once_t tls_ ## name ## _once_control = PTHREAD_ONCE_INIT; \ michael@0: static pthread_key_t tls_ ## name ## _key; \ michael@0: \ michael@0: static void \ michael@0: tls_ ## name ## _destroy_value (void *value) \ michael@0: { \ michael@0: free (value); \ michael@0: } \ michael@0: \ michael@0: static void \ michael@0: tls_ ## name ## _make_key (void) \ michael@0: { \ michael@0: pthread_key_create (&tls_ ## name ## _key, \ michael@0: tls_ ## name ## _destroy_value); \ michael@0: } \ michael@0: \ michael@0: static type * \ michael@0: tls_ ## name ## _alloc (void) \ michael@0: { \ michael@0: type *value = calloc (1, sizeof (type)); \ michael@0: if (value) \ michael@0: pthread_setspecific (tls_ ## name ## _key, value); \ michael@0: return value; \ michael@0: } \ michael@0: \ michael@0: static force_inline type * \ michael@0: tls_ ## name ## _get (void) \ michael@0: { \ michael@0: type *value = NULL; \ michael@0: if (pthread_once (&tls_ ## name ## _once_control, \ michael@0: tls_ ## name ## _make_key) == 0) \ michael@0: { \ michael@0: value = pthread_getspecific (tls_ ## name ## _key); \ michael@0: if (!value) \ michael@0: value = tls_ ## name ## _alloc (); \ michael@0: } \ michael@0: return value; \ michael@0: } michael@0: michael@0: # define PIXMAN_GET_THREAD_LOCAL(name) \ michael@0: tls_ ## name ## _get () michael@0: michael@0: #else michael@0: michael@0: # 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." michael@0: michael@0: #endif