14a49301eSmrg/**************************************************************************
24a49301eSmrg *
3af69d88dSmrg * Copyright 2007-2008 VMware, Inc.
44a49301eSmrg * All Rights Reserved.
54a49301eSmrg *
64a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a
74a49301eSmrg * copy of this software and associated documentation files (the
84a49301eSmrg * "Software"), to deal in the Software without restriction, including
94a49301eSmrg * without limitation the rights to use, copy, modify, merge, publish,
104a49301eSmrg * distribute, sub license, and/or sell copies of the Software, and to
114a49301eSmrg * permit persons to whom the Software is furnished to do so, subject to
124a49301eSmrg * the following conditions:
134a49301eSmrg *
144a49301eSmrg * The above copyright notice and this permission notice (including the
154a49301eSmrg * next paragraph) shall be included in all copies or substantial portions
164a49301eSmrg * of the Software.
174a49301eSmrg *
184a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
194a49301eSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
204a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21af69d88dSmrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
224a49301eSmrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
234a49301eSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
244a49301eSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
254a49301eSmrg *
264a49301eSmrg **************************************************************************/
274a49301eSmrg
284a49301eSmrg#ifndef P_COMPILER_H
294a49301eSmrg#define P_COMPILER_H
304a49301eSmrg
314a49301eSmrg
32af69d88dSmrg#include "c99_compat.h" /* inline, __func__, etc. */
33af69d88dSmrg
344a49301eSmrg#include "p_config.h"
354a49301eSmrg
3601e04c3fSmrg#include "util/macros.h"
3701e04c3fSmrg
384a49301eSmrg#include <stdlib.h>
394a49301eSmrg#include <string.h>
40cdc920a0Smrg#include <stddef.h>
41cdc920a0Smrg#include <stdarg.h>
423464ebd5Sriastradh#include <limits.h>
434a49301eSmrg
444a49301eSmrg
454a49301eSmrg#if defined(_WIN32) && !defined(__WIN32__)
464a49301eSmrg#define __WIN32__
474a49301eSmrg#endif
484a49301eSmrg
494a49301eSmrg#if defined(_MSC_VER)
504a49301eSmrg
5101e04c3fSmrg#include <intrin.h>
5201e04c3fSmrg
534a49301eSmrg/* Avoid 'expression is always true' warning */
544a49301eSmrg#pragma warning(disable: 4296)
554a49301eSmrg
564a49301eSmrg#endif /* _MSC_VER */
574a49301eSmrg
584a49301eSmrg
59cdc920a0Smrg/*
60cdc920a0Smrg * Alternative stdint.h and stdbool.h headers are supplied in include/c99 for
61cdc920a0Smrg * systems that lack it.
62cdc920a0Smrg */
634a49301eSmrg#include <stdint.h>
644a49301eSmrg#include <stdbool.h>
654a49301eSmrg
664a49301eSmrg
673464ebd5Sriastradh#ifdef __cplusplus
683464ebd5Sriastradhextern "C" {
693464ebd5Sriastradh#endif
703464ebd5Sriastradh
713464ebd5Sriastradh
72bf246d0eSchristos#if !defined(__HAIKU__) && !defined(__USE_MISC) && !defined(_NETBSD_SOURCE)
73af69d88dSmrg#if !defined(PIPE_OS_ANDROID)
744a49301eSmrgtypedef unsigned int       uint;
75af69d88dSmrg#endif
764a49301eSmrgtypedef unsigned short     ushort;
774a49301eSmrg#endif
784a49301eSmrgtypedef unsigned char      ubyte;
794a49301eSmrg
804a49301eSmrgtypedef unsigned char boolean;
814a49301eSmrg#ifndef TRUE
824a49301eSmrg#define TRUE  true
834a49301eSmrg#endif
844a49301eSmrg#ifndef FALSE
854a49301eSmrg#define FALSE false
864a49301eSmrg#endif
874a49301eSmrg
883464ebd5Sriastradh#ifndef va_copy
893464ebd5Sriastradh#ifdef __va_copy
903464ebd5Sriastradh#define va_copy(dest, src) __va_copy((dest), (src))
913464ebd5Sriastradh#else
923464ebd5Sriastradh#define va_copy(dest, src) (dest) = (src)
933464ebd5Sriastradh#endif
943464ebd5Sriastradh#endif
954a49301eSmrg
96cdc920a0Smrg
97af69d88dSmrg/* XXX: Use standard `__func__` instead */
984a49301eSmrg#ifndef __FUNCTION__
99af69d88dSmrg#  define __FUNCTION__ __func__
1003464ebd5Sriastradh#endif
1014a49301eSmrg
1024a49301eSmrg
1034a49301eSmrg/* This should match linux gcc cdecl semantics everywhere, so that we
1044a49301eSmrg * just codegen one calling convention on all platforms.
1054a49301eSmrg */
1064a49301eSmrg#ifdef _MSC_VER
1074a49301eSmrg#define PIPE_CDECL __cdecl
1084a49301eSmrg#else
1094a49301eSmrg#define PIPE_CDECL
1104a49301eSmrg#endif
1114a49301eSmrg
1124a49301eSmrg
1134a49301eSmrg
1144a49301eSmrg#if defined(__GNUC__)
115cdc920a0Smrg#define PIPE_DEPRECATED  __attribute__((__deprecated__))
1164a49301eSmrg#else
117cdc920a0Smrg#define PIPE_DEPRECATED
1184a49301eSmrg#endif
119cdc920a0Smrg
120cdc920a0Smrg
121cdc920a0Smrg
122cdc920a0Smrg/* Macros for data alignment. */
12301e04c3fSmrg#if defined(__GNUC__)
124cdc920a0Smrg
125cdc920a0Smrg/* See http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Type-Attributes.html */
126cdc920a0Smrg#define PIPE_ALIGN_TYPE(_alignment, _type) _type __attribute__((aligned(_alignment)))
127cdc920a0Smrg
128cdc920a0Smrg/* See http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Variable-Attributes.html */
129cdc920a0Smrg#define PIPE_ALIGN_VAR(_alignment) __attribute__((aligned(_alignment)))
130cdc920a0Smrg
1311463c08dSmrg#if defined(__GNUC__) && defined(PIPE_ARCH_X86)
132cdc920a0Smrg#define PIPE_ALIGN_STACK __attribute__((force_align_arg_pointer))
1334a49301eSmrg#else
134cdc920a0Smrg#define PIPE_ALIGN_STACK
135cdc920a0Smrg#endif
136cdc920a0Smrg
137cdc920a0Smrg#elif defined(_MSC_VER)
138cdc920a0Smrg
139cdc920a0Smrg/* See http://msdn.microsoft.com/en-us/library/83ythb65.aspx */
140cdc920a0Smrg#define PIPE_ALIGN_TYPE(_alignment, _type) __declspec(align(_alignment)) _type
141cdc920a0Smrg#define PIPE_ALIGN_VAR(_alignment) __declspec(align(_alignment))
142cdc920a0Smrg
143cdc920a0Smrg#define PIPE_ALIGN_STACK
144cdc920a0Smrg
145bf246d0eSchristos#elif defined(SWIG) || defined(__lint__)
146cdc920a0Smrg
147cdc920a0Smrg#define PIPE_ALIGN_TYPE(_alignment, _type) _type
148cdc920a0Smrg#define PIPE_ALIGN_VAR(_alignment)
149cdc920a0Smrg
150cdc920a0Smrg#define PIPE_ALIGN_STACK
151cdc920a0Smrg
152cdc920a0Smrg#else
153cdc920a0Smrg
154cdc920a0Smrg#error "Unsupported compiler"
155cdc920a0Smrg
1564a49301eSmrg#endif
1574a49301eSmrg
1581463c08dSmrg/**
1591463c08dSmrg * Declare a variable on its own cache line.
1601463c08dSmrg *
1611463c08dSmrg * This helps eliminate "False sharing" to make atomic operations
1621463c08dSmrg * on pipe_reference::count faster and/or access to adjacent fields faster.
1631463c08dSmrg *
1641463c08dSmrg * https://en.wikipedia.org/wiki/False_sharing
1651463c08dSmrg *
1661463c08dSmrg * CALLOC_STRUCT_CL or MALLOC_STRUCT_CL and FREE_CL should be used to allocate
1671463c08dSmrg * structures that contain this.
1681463c08dSmrg *
1691463c08dSmrg * NOTE: Don't use PIPE_ALIGN_VAR because it causes the whole structure to be
1701463c08dSmrg *       aligned, but we only want to align the field.
1711463c08dSmrg */
1721463c08dSmrg#define EXCLUSIVE_CACHELINE(decl) \
1731463c08dSmrg   union { char __cl_space[CACHE_LINE_SIZE]; \
1741463c08dSmrg           decl; }
1754a49301eSmrg
1763464ebd5Sriastradh#if defined(__GNUC__)
1773464ebd5Sriastradh
1783464ebd5Sriastradh#define PIPE_READ_WRITE_BARRIER() __asm__("":::"memory")
1793464ebd5Sriastradh
1803464ebd5Sriastradh#elif defined(_MSC_VER)
1813464ebd5Sriastradh
1823464ebd5Sriastradh#define PIPE_READ_WRITE_BARRIER() _ReadWriteBarrier()
1833464ebd5Sriastradh
184bf246d0eSchristos#elif defined(__lint__)
185bf246d0eSchristos
186bf246d0eSchristos#define PIPE_READ_WRITE_BARRIER() /* */
187bf246d0eSchristos
1883464ebd5Sriastradh#else
1893464ebd5Sriastradh
1903464ebd5Sriastradh#warning "Unsupported compiler"
1913464ebd5Sriastradh#define PIPE_READ_WRITE_BARRIER() /* */
1923464ebd5Sriastradh
1933464ebd5Sriastradh#endif
1943464ebd5Sriastradh
1953464ebd5Sriastradh#if defined(__cplusplus)
1963464ebd5Sriastradh}
1973464ebd5Sriastradh#endif
1983464ebd5Sriastradh
1994a49301eSmrg
2004a49301eSmrg#endif /* P_COMPILER_H */
201