Fixes for pthread thread local storage.
[profile/ivi/pixman.git] / pixman / pixman-compiler.h
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 #ifndef INT16_MIN
22 # define INT16_MIN              (-32767-1)
23 #endif
24
25 #ifndef INT16_MAX
26 # define INT16_MAX              (32767)
27 #endif
28
29 #ifndef INT32_MIN
30 # define INT32_MIN              (-2147483647-1)
31 #endif
32
33 #ifndef INT32_MAX
34 # define INT32_MAX              (2147483647)
35 #endif
36
37 #ifndef UINT32_MIN
38 # define UINT32_MIN             (0)
39 #endif
40
41 #ifndef UINT32_MAX
42 # define UINT32_MAX             (4294967295U)
43 #endif
44
45 #ifndef M_PI
46 # define M_PI                   3.14159265358979323846
47 #endif
48
49 #ifdef _MSC_VER
50 /* 'inline' is available only in C++ in MSVC */
51 #   define inline __inline
52 #   define force_inline __forceinline
53 #elif defined __GNUC__ || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
54 #   define inline __inline__
55 #   define force_inline __inline__ __attribute__ ((__always_inline__))
56 #else
57 #   ifndef force_inline
58 #      define force_inline inline
59 #   endif
60 #endif
61
62 /* GCC visibility */
63 #if defined(__GNUC__) && __GNUC__ >= 4
64 #   define PIXMAN_EXPORT __attribute__ ((visibility("default")))
65 /* Sun Studio 8 visibility */
66 #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
67 #   define PIXMAN_EXPORT __global
68 #else
69 #   define PIXMAN_EXPORT
70 #endif
71
72 /* TLS */
73 #if defined(TOOLCHAIN_SUPPORTS__THREAD)
74
75 #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                       \
76     static __thread type name
77 #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
78     (&name)
79
80 #elif defined(_MSC_VER)
81
82 #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                       \
83     static __declspec(thread) type name
84 #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
85     (&name)
86
87 #elif defined(HAVE_PTHREAD_SETSPECIFIC)
88
89 #include <pthread.h>
90
91 #  define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                        \
92     static pthread_once_t tls_ ## name ## _once_control = PTHREAD_ONCE_INIT; \
93     static pthread_key_t tls_ ## name ## _key;                          \
94                                                                         \
95     static void                                                         \
96     tls_ ## name ## _make_key (void)                                    \
97     {                                                                   \
98         pthread_key_create (&tls_ ## name ## _key, NULL);               \
99     }                                                                   \
100                                                                         \
101     static type *                                                       \
102     tls_ ## name ## _alloc (void)                                       \
103     {                                                                   \
104         type *value = calloc (1, sizeof (type));                        \
105         if (value)                                                      \
106             pthread_setspecific (tls_ ## name ## _key, value);          \
107         return value;                                                   \
108     }                                                                   \
109                                                                         \
110     static force_inline type *                                          \
111     tls_ ## name ## _get (void)                                         \
112     {                                                                   \
113         type *value = NULL;                                             \
114         if (pthread_once (&tls_ ## name ## _once_control,               \
115                           tls_ ## name ## _make_key) == 0)              \
116         {                                                               \
117             value = pthread_getspecific (tls_ ## name ## _key);         \
118             if (!value)                                                 \
119                 value = tls_ ## name ## _alloc ();                      \
120         }                                                               \
121         return value;                                                   \
122     }
123
124 #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
125     tls_ ## name ## _get ()
126
127 #else
128
129 #    error "Unknown thread local support for this system"
130
131 #endif