Home | History | Annotate | Download | only in pixman
      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