1/**************************************************************************
2 *
3 * Copyright 2007-2008 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28#ifndef P_COMPILER_H
29#define P_COMPILER_H
30
31
32#include "c99_compat.h" /* inline, __func__, etc. */
33
34#include "p_config.h"
35
36#include "util/macros.h"
37
38#include <stdlib.h>
39#include <string.h>
40#include <stddef.h>
41#include <stdarg.h>
42#include <limits.h>
43
44
45#if defined(_WIN32) && !defined(__WIN32__)
46#define __WIN32__
47#endif
48
49#if defined(_MSC_VER)
50
51#include <intrin.h>
52
53/* Avoid 'expression is always true' warning */
54#pragma warning(disable: 4296)
55
56#endif /* _MSC_VER */
57
58
59/*
60 * Alternative stdint.h and stdbool.h headers are supplied in include/c99 for
61 * systems that lack it.
62 */
63#include <stdint.h>
64#include <stdbool.h>
65
66
67#ifdef __cplusplus
68extern "C" {
69#endif
70
71
72#if !defined(__HAIKU__) && !defined(__USE_MISC) && !defined(_NETBSD_SOURCE)
73#if !defined(PIPE_OS_ANDROID)
74typedef unsigned int       uint;
75#endif
76typedef unsigned short     ushort;
77#endif
78typedef unsigned char      ubyte;
79
80typedef unsigned char boolean;
81#ifndef TRUE
82#define TRUE  true
83#endif
84#ifndef FALSE
85#define FALSE false
86#endif
87
88#ifndef va_copy
89#ifdef __va_copy
90#define va_copy(dest, src) __va_copy((dest), (src))
91#else
92#define va_copy(dest, src) (dest) = (src)
93#endif
94#endif
95
96
97/* XXX: Use standard `__func__` instead */
98#ifndef __FUNCTION__
99#  define __FUNCTION__ __func__
100#endif
101
102
103/* This should match linux gcc cdecl semantics everywhere, so that we
104 * just codegen one calling convention on all platforms.
105 */
106#ifdef _MSC_VER
107#define PIPE_CDECL __cdecl
108#else
109#define PIPE_CDECL
110#endif
111
112
113
114#if defined(__GNUC__)
115#define PIPE_DEPRECATED  __attribute__((__deprecated__))
116#else
117#define PIPE_DEPRECATED
118#endif
119
120
121
122/* Macros for data alignment. */
123#if defined(__GNUC__)
124
125/* See http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Type-Attributes.html */
126#define PIPE_ALIGN_TYPE(_alignment, _type) _type __attribute__((aligned(_alignment)))
127
128/* See http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Variable-Attributes.html */
129#define PIPE_ALIGN_VAR(_alignment) __attribute__((aligned(_alignment)))
130
131#if defined(__GNUC__) && defined(PIPE_ARCH_X86)
132#define PIPE_ALIGN_STACK __attribute__((force_align_arg_pointer))
133#else
134#define PIPE_ALIGN_STACK
135#endif
136
137#elif defined(_MSC_VER)
138
139/* See http://msdn.microsoft.com/en-us/library/83ythb65.aspx */
140#define PIPE_ALIGN_TYPE(_alignment, _type) __declspec(align(_alignment)) _type
141#define PIPE_ALIGN_VAR(_alignment) __declspec(align(_alignment))
142
143#define PIPE_ALIGN_STACK
144
145#elif defined(SWIG) || defined(__lint__)
146
147#define PIPE_ALIGN_TYPE(_alignment, _type) _type
148#define PIPE_ALIGN_VAR(_alignment)
149
150#define PIPE_ALIGN_STACK
151
152#else
153
154#error "Unsupported compiler"
155
156#endif
157
158/**
159 * Declare a variable on its own cache line.
160 *
161 * This helps eliminate "False sharing" to make atomic operations
162 * on pipe_reference::count faster and/or access to adjacent fields faster.
163 *
164 * https://en.wikipedia.org/wiki/False_sharing
165 *
166 * CALLOC_STRUCT_CL or MALLOC_STRUCT_CL and FREE_CL should be used to allocate
167 * structures that contain this.
168 *
169 * NOTE: Don't use PIPE_ALIGN_VAR because it causes the whole structure to be
170 *       aligned, but we only want to align the field.
171 */
172#define EXCLUSIVE_CACHELINE(decl) \
173   union { char __cl_space[CACHE_LINE_SIZE]; \
174           decl; }
175
176#if defined(__GNUC__)
177
178#define PIPE_READ_WRITE_BARRIER() __asm__("":::"memory")
179
180#elif defined(_MSC_VER)
181
182#define PIPE_READ_WRITE_BARRIER() _ReadWriteBarrier()
183
184#elif defined(__lint__)
185
186#define PIPE_READ_WRITE_BARRIER() /* */
187
188#else
189
190#warning "Unsupported compiler"
191#define PIPE_READ_WRITE_BARRIER() /* */
192
193#endif
194
195#if defined(__cplusplus)
196}
197#endif
198
199
200#endif /* P_COMPILER_H */
201