Subversion Repositories Kolibri OS

Rev

Rev 1891 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1891 serge 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
 
3931 Serge 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
 
1891 serge 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
 
3931 Serge 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
 
1891 serge 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
 
3931 Serge 102
/* member offsets */
103
#define CONTAINER_OF(type, member, data)				\
104
    ((type *)(((uint8_t *)data) - offsetof (type, member)))
105
 
1891 serge 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
 
3931 Serge 114
#elif defined(TLS)
1891 serge 115
 
116
#   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)			\
3931 Serge 117
    static TLS type name
1891 serge 118
#   define PIXMAN_GET_THREAD_LOCAL(name)				\
119
    (&name)
120
 
121
#elif defined(__MINGW32__)
122
 
123
#   define _NO_W32_PSEUDO_MODIFIERS
124
#   include 
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 
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;							\
3931 Serge 223
    }
1891 serge 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