Monado OpenXR Runtime
xrt_compiler.h
Go to the documentation of this file.
1// Copyright 2019, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Header holding common defines.
6 * @author Jakob Bornecrantz <jakob@collabora.com>
7 * @ingroup xrt_iface
8 */
9
10#pragma once
11
12
13/*
14 * C99 is not a high bar to reach.
15 */
16#include <stddef.h>
17#include <stdint.h>
18#include <stdbool.h>
19#include <inttypes.h>
20
21#ifdef _MSC_VER
22#include <intrin.h>
23// for atomic intrinsics
24#include "xrt_windows.h"
25#endif // _MSC_VER
26
27/*!
28 * Array size helper.
29 */
30#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
31
32#if defined(__x86_64__) || defined(_M_X64) || defined(__aarch64__) || defined(_ARCH_PPC64) || defined(__s390x__) || \
33 (defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8)
34#define XRT_64_BIT
35#else
36#define XRT_32_BIT
37#endif
38
39/*
40 * Printf helper attribute.
41 */
42#if defined(__GNUC__)
43#define XRT_PRINTF_FORMAT(fmt, list) __attribute__((format(printf, fmt, list)))
44#else
45#define XRT_PRINTF_FORMAT(fmt, list)
46#endif
47
48
49/*
50 * To silence unused warnings.
51 */
52#if defined(__GNUC__)
53#define XRT_MAYBE_UNUSED __attribute__((unused))
54#elif defined(_MSC_VER) && defined(__cplusplus)
55#define XRT_MAYBE_UNUSED [[maybe_unused]]
56#else
57#define XRT_MAYBE_UNUSED
58#endif
59
60
61/*
62 * To make sure return values are checked.
63 */
64#if defined(__GNUC__) && (__GNUC__ >= 4)
65#define XRT_CHECK_RESULT __attribute__((warn_unused_result))
66#elif defined(_MSC_VER) && (_MSC_VER >= 1700)
67#define XRT_CHECK_RESULT _Check_return_
68#else
69#define XRT_CHECK_RESULT
70#endif
71
72
73/*
74 * To stop inlining.
75 */
76#if defined(__GNUC__)
77#define XRT_NO_INLINE __attribute__((noinline))
78#elif defined(_MSC_VER)
79#define XRT_NO_INLINE __declspec(noinline)
80#else
81#define XRT_NO_INLINE
82#endif
83
84
85#ifdef XRT_DOXYGEN
86/*!
87 * To trigger a trap/break in the debugger.
88 *
89 * @ingroup xrt_iface
90 */
91#define XRT_DEBUGBREAK()
92#elif defined(__clang__) || defined(__GNUC__)
93#define XRT_DEBUGBREAK() __builtin_trap()
94#elif defined(_MSC_VER)
95#define XRT_DEBUGBREAK() __debugbreak()
96#else
97#error "compiler not supported"
98#endif
99
100
101
102typedef volatile int32_t xrt_atomic_s32_t;
103
104static inline int32_t
105xrt_atomic_s32_inc_return(xrt_atomic_s32_t *p)
106{
107#if defined(__GNUC__)
108 return __sync_add_and_fetch(p, 1);
109#elif defined(_MSC_VER)
110 return InterlockedIncrement((volatile LONG *)p);
111#else
112#error "compiler not supported"
113#endif
114}
115static inline int32_t
116xrt_atomic_s32_dec_return(xrt_atomic_s32_t *p)
117{
118#if defined(__GNUC__)
119 return __sync_sub_and_fetch(p, 1);
120#elif defined(_MSC_VER)
121 return InterlockedDecrement((volatile LONG *)p);
122#else
123#error "compiler not supported"
124#endif
125}
126static inline int32_t
127xrt_atomic_s32_cmpxchg(xrt_atomic_s32_t *p, int32_t old_, int32_t new_)
128{
129#if defined(__GNUC__)
130 return __sync_val_compare_and_swap(p, old_, new_);
131#elif defined(_MSC_VER)
132 return InterlockedCompareExchange((volatile LONG *)p, old_, new_);
133#else
134#error "compiler not supported"
135#endif
136}
137
138#ifdef _MSC_VER
139typedef intptr_t ssize_t;
140#define _SSIZE_T_
141#define _SSIZE_T_DEFINED
142#endif
143
144/*!
145 * Get the holder from a pointer to a field.
146 *
147 * @ingroup xrt_iface
148 */
149#define container_of(ptr, type, field) (type *)((char *)ptr - offsetof(type, field))
150
151
152#ifdef XRT_DOXYGEN
153
154/*!
155 * Very small default init for structs that works in both C and C++. Helps with
156 * code that needs to be compiled with both C and C++.
157 *
158 * @ingroup xrt_iface
159 */
160
161// clang-format off
162#define XRT_STRUCT_INIT {}
163// clang-format on
164
165#elif defined(__cplusplus)
166
167// clang-format off
168#define XRT_STRUCT_INIT {}
169// clang-format on
170
171#else
172
173// clang-format off
174#define XRT_STRUCT_INIT {0}
175// clang-format on
176
177#endif
A minimal way to include Windows.h.