1/*
2 * Copyright 2004-2010 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Author:
6 *		Erik Jaesler (erik@cgsoftware.com)
7 */
8#ifndef _SUPPORT_DEFS_H
9#define _SUPPORT_DEFS_H
10
11
12#include <BeBuild.h>
13#include <Errors.h>
14
15#include <inttypes.h>
16#include <sys/types.h>
17
18
19/* fixed-size integer types */
20typedef	__haiku_int8			int8;
21typedef __haiku_uint8			uint8;
22typedef	__haiku_int16			int16;
23typedef __haiku_uint16			uint16;
24typedef	__haiku_int32			int32;
25typedef __haiku_uint32			uint32;
26typedef	__haiku_int64			int64;
27typedef __haiku_uint64			uint64;
28
29/* shorthand types */
30typedef volatile int8			vint8;
31typedef volatile uint8			vuint8;
32typedef volatile int16			vint16;
33typedef volatile uint16			vuint16;
34typedef volatile int32			vint32;
35typedef volatile uint32			vuint32;
36typedef volatile int64			vint64;
37typedef volatile uint64			vuint64;
38
39typedef volatile long			vlong;
40typedef volatile int			vint;
41typedef volatile short			vshort;
42typedef volatile char			vchar;
43
44typedef volatile unsigned long	vulong;
45typedef volatile unsigned int	vuint;
46typedef volatile unsigned short	vushort;
47typedef volatile unsigned char	vuchar;
48
49typedef unsigned char			uchar;
50
51/* descriptive types */
52typedef int32					status_t;
53typedef int64					bigtime_t;
54typedef int64					nanotime_t;
55typedef uint32					type_code;
56typedef uint32					perform_code;
57
58typedef __haiku_phys_addr_t		phys_addr_t;
59typedef phys_addr_t				phys_size_t;
60
61typedef	__haiku_generic_addr_t	generic_addr_t;
62typedef	generic_addr_t			generic_size_t;
63
64
65/* printf()/scanf() format strings for [u]int* types */
66#define B_PRId8			"d"
67#define B_PRIi8			"i"
68#define B_PRId16		"d"
69#define B_PRIi16		"i"
70#define B_PRId32		__HAIKU_PRI_PREFIX_32 "d"
71#define B_PRIi32		__HAIKU_PRI_PREFIX_32 "i"
72#define B_PRId64		__HAIKU_PRI_PREFIX_64 "d"
73#define B_PRIi64		__HAIKU_PRI_PREFIX_64 "i"
74#define B_PRIu8			"u"
75#define B_PRIo8			"o"
76#define B_PRIx8			"x"
77#define B_PRIX8			"X"
78#define B_PRIu16		"u"
79#define B_PRIo16		"o"
80#define B_PRIx16		"x"
81#define B_PRIX16		"X"
82#define B_PRIu32		__HAIKU_PRI_PREFIX_32 "u"
83#define B_PRIo32		__HAIKU_PRI_PREFIX_32 "o"
84#define B_PRIx32		__HAIKU_PRI_PREFIX_32 "x"
85#define B_PRIX32		__HAIKU_PRI_PREFIX_32 "X"
86#define B_PRIu64		__HAIKU_PRI_PREFIX_64 "u"
87#define B_PRIo64		__HAIKU_PRI_PREFIX_64 "o"
88#define B_PRIx64		__HAIKU_PRI_PREFIX_64 "x"
89#define B_PRIX64		__HAIKU_PRI_PREFIX_64 "X"
90
91#define B_SCNd8			"hhd"
92#define B_SCNi8			"hhi"
93#define B_SCNd16		"hd"
94#define B_SCNi16		"hi"
95#define B_SCNd32		__HAIKU_PRI_PREFIX_32 "d"
96#define B_SCNi32		__HAIKU_PRI_PREFIX_32 "i"
97#define B_SCNd64		__HAIKU_PRI_PREFIX_64 "d"
98#define B_SCNi64		__HAIKU_PRI_PREFIX_64 "i"
99#define B_SCNu8			"hhu"
100#define B_SCNo8			"hho"
101#define B_SCNx8			"hhx"
102#define B_SCNu16		"hu"
103#define B_SCNo16		"ho"
104#define B_SCNx16		"hx"
105#define B_SCNu32		__HAIKU_PRI_PREFIX_32 "u"
106#define B_SCNo32		__HAIKU_PRI_PREFIX_32 "o"
107#define B_SCNx32		__HAIKU_PRI_PREFIX_32 "x"
108#define B_SCNu64		__HAIKU_PRI_PREFIX_64 "u"
109#define B_SCNo64		__HAIKU_PRI_PREFIX_64 "o"
110#define B_SCNx64		__HAIKU_PRI_PREFIX_64 "x"
111
112/* printf()/scanf() format strings for some standard types */
113/* size_t */
114#define B_PRIuSIZE		__HAIKU_PRI_PREFIX_ADDR "u"
115#define B_PRIoSIZE		__HAIKU_PRI_PREFIX_ADDR "o"
116#define B_PRIxSIZE		__HAIKU_PRI_PREFIX_ADDR "x"
117#define B_PRIXSIZE		__HAIKU_PRI_PREFIX_ADDR "X"
118
119#define B_SCNuSIZE		__HAIKU_PRI_PREFIX_ADDR "u"
120#define B_SCNoSIZE		__HAIKU_PRI_PREFIX_ADDR "o"
121#define B_SCNxSIZE		__HAIKU_PRI_PREFIX_ADDR "x"
122
123/* ssize_t */
124#define B_PRIdSSIZE		__HAIKU_PRI_PREFIX_ADDR "d"
125#define B_PRIiSSIZE		__HAIKU_PRI_PREFIX_ADDR "i"
126
127#define B_SCNdSSIZE		__HAIKU_PRI_PREFIX_ADDR "d"
128#define B_SCNiSSIZE		__HAIKU_PRI_PREFIX_ADDR "i"
129
130/* addr_t */
131#define B_PRIuADDR		__HAIKU_PRI_PREFIX_ADDR "u"
132#define B_PRIoADDR		__HAIKU_PRI_PREFIX_ADDR "o"
133#define B_PRIxADDR		__HAIKU_PRI_PREFIX_ADDR "x"
134#define B_PRIXADDR		__HAIKU_PRI_PREFIX_ADDR "X"
135
136#define B_SCNuADDR		__HAIKU_PRI_PREFIX_ADDR "u"
137#define B_SCNoADDR		__HAIKU_PRI_PREFIX_ADDR "o"
138#define B_SCNxADDR		__HAIKU_PRI_PREFIX_ADDR "x"
139
140/* phys_addr_t */
141#define B_PRIuPHYSADDR	__HAIKU_PRI_PREFIX_PHYS_ADDR "u"
142#define B_PRIoPHYSADDR	__HAIKU_PRI_PREFIX_PHYS_ADDR "o"
143#define B_PRIxPHYSADDR	__HAIKU_PRI_PREFIX_PHYS_ADDR "x"
144#define B_PRIXPHYSADDR	__HAIKU_PRI_PREFIX_PHYS_ADDR "X"
145
146#define B_SCNuPHYSADDR	__HAIKU_PRI_PREFIX_PHYS_ADDR "u"
147#define B_SCNoPHYSADDR	__HAIKU_PRI_PREFIX_PHYS_ADDR "o"
148#define B_SCNxPHYSADDR	__HAIKU_PRI_PREFIX_PHYS_ADDR "x"
149
150/* generic_addr_t */
151#define B_PRIuGENADDR	__HAIKU_PRI_PREFIX_GENERIC_ADDR "u"
152#define B_PRIoGENADDR	__HAIKU_PRI_PREFIX_GENERIC_ADDR "o"
153#define B_PRIxGENADDR	__HAIKU_PRI_PREFIX_GENERIC_ADDR "x"
154#define B_PRIXGENADDR	__HAIKU_PRI_PREFIX_GENERIC_ADDR "X"
155
156#define B_SCNuGENADDR	__HAIKU_PRI_PREFIX_GENERIC_ADDR "u"
157#define B_SCNoGENADDR	__HAIKU_PRI_PREFIX_GENERIC_ADDR "o"
158#define B_SCNxGENADDR	__HAIKU_PRI_PREFIX_GENERIC_ADDR "x"
159
160/* off_t */
161#define B_PRIdOFF		B_PRId64
162#define B_PRIiOFF		B_PRIi64
163#define B_PRIxOFF		B_PRIx64
164
165#define B_SCNdOFF		B_SCNd64
166#define B_SCNiOFF		B_SCNi64
167#define B_SCNxOFF		B_SCNx64
168
169/* dev_t */
170#define B_PRIdDEV		B_PRId32
171#define B_PRIiDEV		B_PRIi32
172
173/* ino_t */
174#define B_PRIdINO		B_PRId64
175#define B_PRIiINO		B_PRIi64
176
177/* time_t */
178#if defined(__i386__) && !defined(__x86_64__)
179#	define B_PRIdTIME	B_PRId32
180#	define B_PRIiTIME	B_PRIi32
181#else
182#	define B_PRIdTIME	B_PRId64
183#	define B_PRIiTIME	B_PRIi64
184#endif
185
186/* bigtime_t */
187#define B_PRIdBIGTIME	B_PRId64
188#define B_PRIiBIGTIME	B_PRIi64
189
190
191/* Printed width of a pointer with the %p format (minus 0x prefix). */
192#ifdef B_HAIKU_64_BIT
193#	define B_PRINTF_POINTER_WIDTH	16
194#else
195#	define B_PRINTF_POINTER_WIDTH	8
196#endif
197
198
199/* Empty string ("") */
200#ifdef __cplusplus
201extern const char *B_EMPTY_STRING;
202#endif
203
204
205/* min and max comparisons */
206#ifndef __cplusplus
207#	ifndef min
208#		define min(a,b) ((a)>(b)?(b):(a))
209#	endif
210#	ifndef max
211#		define max(a,b) ((a)>(b)?(a):(b))
212#	endif
213#endif
214
215/* min() and max() are functions in C++ */
216#define min_c(a,b) ((a)>(b)?(b):(a))
217#define max_c(a,b) ((a)>(b)?(a):(b))
218
219
220/* Grandfathering */
221#ifndef __cplusplus
222#	include <stdbool.h>
223#endif
224
225#ifndef NULL
226#	define NULL (0)
227#endif
228
229
230#ifdef __cplusplus
231extern "C" {
232#endif
233
234/* Other stuff */
235extern void*	get_stack_frame(void);
236
237#ifdef __cplusplus
238}
239#endif
240
241/* Count items in an array, count_of is a common define */
242#define B_COUNT_OF(a) (sizeof(a) / sizeof(a[0]))
243
244/* Obsolete or discouraged API */
245
246/* use 'true' and 'false' */
247#ifndef FALSE
248#	define FALSE	0
249#endif
250#ifndef TRUE
251#	define TRUE		1
252#endif
253
254
255/* Use the built-in atomic functions, if requested and available. */
256
257#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || defined(__clang__)
258
259
260static __inline__ void
261atomic_set(int32* value, int32 newValue)
262{
263	__atomic_store_n(value, newValue, __ATOMIC_RELEASE);
264}
265
266
267static __inline__ int32
268atomic_get_and_set(int32* value, int32 newValue)
269{
270	return __atomic_exchange_n(value, newValue, __ATOMIC_SEQ_CST);
271}
272
273
274static __inline__ int32
275atomic_test_and_set(int32* value, int32 newValue, int32 testAgainst)
276{
277	__atomic_compare_exchange_n(value, &testAgainst, newValue, 1,
278		__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
279	return testAgainst;
280}
281
282
283static __inline__ int32
284atomic_add(int32* value, int32 addValue)
285{
286	return __atomic_fetch_add(value, addValue, __ATOMIC_SEQ_CST);
287}
288
289
290static __inline__ int32
291atomic_and(int32* value, int32 andValue)
292{
293	return __atomic_fetch_and(value, andValue, __ATOMIC_SEQ_CST);
294}
295
296
297static __inline__ int32
298atomic_or(int32* value, int32 orValue)
299{
300	return __atomic_fetch_or(value, orValue, __ATOMIC_SEQ_CST);
301}
302
303
304static __inline__ int32
305atomic_get(int32* value)
306{
307	return __atomic_load_n(value, __ATOMIC_ACQUIRE);
308}
309
310
311static __inline__ void
312atomic_set64(int64* value, int64 newValue)
313{
314	__atomic_store_n(value, newValue, __ATOMIC_RELEASE);
315}
316
317
318static __inline__ int64
319atomic_get_and_set64(int64* value, int64 newValue)
320{
321	return __atomic_exchange_n(value, newValue, __ATOMIC_SEQ_CST);
322}
323
324
325static __inline__ int64
326atomic_test_and_set64(int64* value, int64 newValue, int64 testAgainst)
327{
328	__atomic_compare_exchange_n(value, &testAgainst, newValue, 1,
329		__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
330	return testAgainst;
331}
332
333
334static __inline__ int64
335atomic_add64(int64* value, int64 addValue)
336{
337	return __atomic_fetch_add(value, addValue, __ATOMIC_SEQ_CST);
338}
339
340
341static __inline__ int64
342atomic_and64(int64* value, int64 andValue)
343{
344	return __atomic_fetch_and(value, andValue, __ATOMIC_SEQ_CST);
345}
346
347
348static __inline__ int64
349atomic_or64(int64* value, int64 orValue)
350{
351	return __atomic_fetch_or(value, orValue, __ATOMIC_SEQ_CST);
352}
353
354
355static __inline__ int64
356atomic_get64(int64* value)
357{
358	return __atomic_load_n(value, __ATOMIC_ACQUIRE);
359}
360
361
362#else	/* __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) */
363
364#ifdef __cplusplus
365extern "C" {
366#endif
367
368/* Atomic functions; previous value is returned */
369extern void		atomic_set(int32* value, int32 newValue);
370extern int32	atomic_get_and_set(int32* value, int32 newValue);
371extern int32	atomic_test_and_set(int32 *value, int32 newValue, int32 testAgainst);
372extern int32	atomic_add(int32 *value, int32 addValue);
373extern int32	atomic_and(int32 *value, int32 andValue);
374extern int32	atomic_or(int32 *value, int32 orValue);
375extern int32	atomic_get(int32 *value);
376
377extern void		atomic_set64(int64* value, int64 newValue);
378extern int64	atomic_get_and_set64(int64* value, int64 newValue);
379extern int64	atomic_test_and_set64(int64 *value, int64 newValue, int64 testAgainst);
380extern int64	atomic_add64(int64 *value, int64 addValue);
381extern int64	atomic_and64(int64 *value, int64 andValue);
382extern int64	atomic_or64(int64 *value, int64 orValue);
383extern int64	atomic_get64(int64 *value);
384
385#ifdef __cplusplus
386}
387#endif
388
389#endif
390
391
392#endif	/* _SUPPORT_DEFS_H */
393