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 51 /* descriptive types */ 52 typedef int32 status_t; 53 typedef int64 bigtime_t; 54 typedef int64 nanotime_t; 55 typedef uint32 type_code; 56 typedef uint32 perform_code; 57 58 typedef __haiku_phys_addr_t phys_addr_t; 59 typedef phys_addr_t phys_size_t; 60 61 typedef __haiku_generic_addr_t generic_addr_t; 62 typedef 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 201 extern 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 231 extern "C" { 232 #endif 233 234 /* Other stuff */ 235 extern 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 260 static __inline__ void 261 atomic_set(int32* value, int32 newValue) 262 { 263 __atomic_store_n(value, newValue, __ATOMIC_RELEASE); 264 } 265 266 267 static __inline__ int32 268 atomic_get_and_set(int32* value, int32 newValue) 269 { 270 return __atomic_exchange_n(value, newValue, __ATOMIC_SEQ_CST); 271 } 272 273 274 static __inline__ int32 275 atomic_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 283 static __inline__ int32 284 atomic_add(int32* value, int32 addValue) 285 { 286 return __atomic_fetch_add(value, addValue, __ATOMIC_SEQ_CST); 287 } 288 289 290 static __inline__ int32 291 atomic_and(int32* value, int32 andValue) 292 { 293 return __atomic_fetch_and(value, andValue, __ATOMIC_SEQ_CST); 294 } 295 296 297 static __inline__ int32 298 atomic_or(int32* value, int32 orValue) 299 { 300 return __atomic_fetch_or(value, orValue, __ATOMIC_SEQ_CST); 301 } 302 303 304 static __inline__ int32 305 atomic_get(int32* value) 306 { 307 return __atomic_load_n(value, __ATOMIC_ACQUIRE); 308 } 309 310 311 static __inline__ void 312 atomic_set64(int64* value, int64 newValue) 313 { 314 __atomic_store_n(value, newValue, __ATOMIC_RELEASE); 315 } 316 317 318 static __inline__ int64 319 atomic_get_and_set64(int64* value, int64 newValue) 320 { 321 return __atomic_exchange_n(value, newValue, __ATOMIC_SEQ_CST); 322 } 323 324 325 static __inline__ int64 326 atomic_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 334 static __inline__ int64 335 atomic_add64(int64* value, int64 addValue) 336 { 337 return __atomic_fetch_add(value, addValue, __ATOMIC_SEQ_CST); 338 } 339 340 341 static __inline__ int64 342 atomic_and64(int64* value, int64 andValue) 343 { 344 return __atomic_fetch_and(value, andValue, __ATOMIC_SEQ_CST); 345 } 346 347 348 static __inline__ int64 349 atomic_or64(int64* value, int64 orValue) 350 { 351 return __atomic_fetch_or(value, orValue, __ATOMIC_SEQ_CST); 352 } 353 354 355 static __inline__ int64 356 atomic_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 365 extern "C" { 366 #endif 367 368 /* Atomic functions; previous value is returned */ 369 extern void atomic_set(int32* value, int32 newValue); 370 extern int32 atomic_get_and_set(int32* value, int32 newValue); 371 extern int32 atomic_test_and_set(int32 *value, int32 newValue, int32 testAgainst); 372 extern int32 atomic_add(int32 *value, int32 addValue); 373 extern int32 atomic_and(int32 *value, int32 andValue); 374 extern int32 atomic_or(int32 *value, int32 orValue); 375 extern int32 atomic_get(int32 *value); 376 377 extern void atomic_set64(int64* value, int64 newValue); 378 extern int64 atomic_get_and_set64(int64* value, int64 newValue); 379 extern int64 atomic_test_and_set64(int64 *value, int64 newValue, int64 testAgainst); 380 extern int64 atomic_add64(int64 *value, int64 addValue); 381 extern int64 atomic_and64(int64 *value, int64 andValue); 382 extern int64 atomic_or64(int64 *value, int64 orValue); 383 extern int64 atomic_get64(int64 *value); 384 385 #ifdef __cplusplus 386 } 387 #endif 388 389 #endif 390 391 392 #endif /* _SUPPORT_DEFS_H */ 393