Home | History | Annotate | Line # | 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 #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