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