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 */ 20 typedef __haiku_int8 int8; 21 typedef __haiku_uint8 uint8; 22 typedef __haiku_int16 int16; 23 typedef __haiku_uint16 uint16; 24 typedef __haiku_int32 int32; 25 typedef __haiku_uint32 uint32; 26 typedef __haiku_int64 int64; 27 typedef __haiku_uint64 uint64; 28 29 /* shorthand types */ 30 typedef volatile int8 vint8; 31 typedef volatile uint8 vuint8; 32 typedef volatile int16 vint16; 33 typedef volatile uint16 vuint16; 34 typedef volatile int32 vint32; 35 typedef volatile uint32 vuint32; 36 typedef volatile int64 vint64; 37 typedef volatile uint64 vuint64; 38 39 typedef volatile long vlong; 40 typedef volatile int vint; 41 typedef volatile short vshort; 42 typedef volatile char vchar; 43 44 typedef volatile unsigned long vulong; 45 typedef volatile unsigned int vuint; 46 typedef volatile unsigned short vushort; 47 typedef volatile unsigned char vuchar; 48 49 typedef unsigned char uchar; 50 typedef unsigned short unichar; 51 52 /* descriptive types */ 53 typedef int32 status_t; 54 typedef int64 bigtime_t; 55 typedef int64 nanotime_t; 56 typedef uint32 type_code; 57 typedef uint32 perform_code; 58 59 typedef __haiku_phys_addr_t phys_addr_t; 60 typedef phys_addr_t phys_size_t; 61 62 typedef __haiku_generic_addr_t generic_addr_t; 63 typedef 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 202 extern 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 232 extern "C" { 233 #endif 234 235 /* Other stuff */ 236 extern 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 261 static __inline__ void 262 atomic_set(int32* value, int32 newValue) 263 { 264 __atomic_store_n(value, newValue, __ATOMIC_RELEASE); 265 } 266 267 268 static __inline__ int32 269 atomic_get_and_set(int32* value, int32 newValue) 270 { 271 return __atomic_exchange_n(value, newValue, __ATOMIC_SEQ_CST); 272 } 273 274 275 static __inline__ int32 276 atomic_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 284 static __inline__ int32 285 atomic_add(int32* value, int32 addValue) 286 { 287 return __atomic_fetch_add(value, addValue, __ATOMIC_SEQ_CST); 288 } 289 290 291 static __inline__ int32 292 atomic_and(int32* value, int32 andValue) 293 { 294 return __atomic_fetch_and(value, andValue, __ATOMIC_SEQ_CST); 295 } 296 297 298 static __inline__ int32 299 atomic_or(int32* value, int32 orValue) 300 { 301 return __atomic_fetch_or(value, orValue, __ATOMIC_SEQ_CST); 302 } 303 304 305 static __inline__ int32 306 atomic_get(int32* value) 307 { 308 return __atomic_load_n(value, __ATOMIC_ACQUIRE); 309 } 310 311 312 static __inline__ void 313 atomic_set64(int64* value, int64 newValue) 314 { 315 __atomic_store_n(value, newValue, __ATOMIC_RELEASE); 316 } 317 318 319 static __inline__ int64 320 atomic_get_and_set64(int64* value, int64 newValue) 321 { 322 return __atomic_exchange_n(value, newValue, __ATOMIC_SEQ_CST); 323 } 324 325 326 static __inline__ int64 327 atomic_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 335 static __inline__ int64 336 atomic_add64(int64* value, int64 addValue) 337 { 338 return __atomic_fetch_add(value, addValue, __ATOMIC_SEQ_CST); 339 } 340 341 342 static __inline__ int64 343 atomic_and64(int64* value, int64 andValue) 344 { 345 return __atomic_fetch_and(value, andValue, __ATOMIC_SEQ_CST); 346 } 347 348 349 static __inline__ int64 350 atomic_or64(int64* value, int64 orValue) 351 { 352 return __atomic_fetch_or(value, orValue, __ATOMIC_SEQ_CST); 353 } 354 355 356 static __inline__ int64 357 atomic_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 366 extern "C" { 367 #endif 368 369 /* Atomic functions; previous value is returned */ 370 extern void atomic_set(int32* value, int32 newValue); 371 extern int32 atomic_get_and_set(int32* value, int32 newValue); 372 extern int32 atomic_test_and_set(int32 *value, int32 newValue, int32 testAgainst); 373 extern int32 atomic_add(int32 *value, int32 addValue); 374 extern int32 atomic_and(int32 *value, int32 andValue); 375 extern int32 atomic_or(int32 *value, int32 orValue); 376 extern int32 atomic_get(int32 *value); 377 378 extern void atomic_set64(int64* value, int64 newValue); 379 extern int64 atomic_get_and_set64(int64* value, int64 newValue); 380 extern int64 atomic_test_and_set64(int64 *value, int64 newValue, int64 testAgainst); 381 extern int64 atomic_add64(int64 *value, int64 addValue); 382 extern int64 atomic_and64(int64 *value, int64 andValue); 383 extern int64 atomic_or64(int64 *value, int64 orValue); 384 extern int64 atomic_get64(int64 *value); 385 386 #ifdef __cplusplus 387 } 388 #endif 389 390 #endif 391 392 393 #endif /* _SUPPORT_DEFS_H */ 394