fe0c98e74a745e310202e0e8d17dae3a10e69178
[akaros.git] / inc / types.h
1 #ifndef ROS_INC_TYPES_H
2 #define ROS_INC_TYPES_H
3
4 #ifndef NULL
5 #define NULL ((void*) 0)
6 #endif
7
8 #define TRUE    1
9 #define FALSE   0
10
11 // Represents true-or-false values
12 typedef int bool;
13
14 // Explicitly-sized versions of integer types
15 typedef __signed char int8_t;
16 typedef unsigned char uint8_t;
17 typedef short int16_t;
18 typedef unsigned short uint16_t;
19 typedef int int32_t;
20 typedef unsigned int uint32_t;
21 typedef long long int64_t;
22 typedef unsigned long long uint64_t;
23
24 // Pointers and addresses are 32 bits long.
25 // We use pointer types to represent virtual addresses,
26 // uintptr_t to represent the numerical values of virtual addresses,
27 // and physaddr_t to represent physical addresses.
28 typedef int32_t intptr_t;
29 typedef uint32_t uintptr_t;
30 typedef uint32_t physaddr_t;
31
32 // Page numbers are 32 bits long.
33 typedef uint32_t ppn_t;
34
35 // size_t is used for memory object sizes.
36 typedef uint32_t size_t;
37 // ssize_t is a signed version of ssize_t, used in case there might be an
38 // error return.
39 typedef int32_t ssize_t;
40
41 // off_t is used for file offsets and lengths.
42 typedef int32_t off_t;
43
44 // Efficient min and max operations
45 #define MIN(_a, _b)                                             \
46 ({                                                              \
47         typeof(_a) __a = (_a);                                  \
48         typeof(_b) __b = (_b);                                  \
49         __a <= __b ? __a : __b;                                 \
50 })
51 #define MAX(_a, _b)                                             \
52 ({                                                              \
53         typeof(_a) __a = (_a);                                  \
54         typeof(_b) __b = (_b);                                  \
55         __a >= __b ? __a : __b;                                 \
56 })
57
58 // Rounding operations (efficient when n is a power of 2)
59 // Round down to the nearest multiple of n
60 #define ROUNDDOWN(a, n)                                         \
61 ({                                                              \
62         uint32_t __a = (uint32_t) (a);                          \
63         (typeof(a)) (__a - __a % (n));                          \
64 })
65 // Round up to the nearest multiple of n
66 #define ROUNDUP(a, n)                                           \
67 ({                                                              \
68         uint32_t __n = (uint32_t) (n);                          \
69         (typeof(a)) (ROUNDDOWN((uint32_t) (a) + __n - 1, __n)); \
70 })
71
72 // Return the offset of 'member' relative to the beginning of a struct type
73 #define offsetof(type, member)  ((size_t) (&((type*)0)->member))
74
75 // Ivy currently can only handle 63 bits (OCaml thing), so use this to make
76 // a uint64_t programatically
77 #define UINT64(upper, lower) ( (((uint64_t)(upper)) << 32) | (lower) )
78
79 /*********************** Bitmask stuff **********************/
80 #define BYTES_FOR_BITMASK(size) (((size) - 1) / 8 + 1)
81 #define BYTES_FOR_BITMASK_WITH_CHECK(size) ((size) ? ((size) - (1)) / (8) + (1) : (0))
82 #define DECL_BITMASK(name, size) uint8_t (name)[BYTES_FOR_BITMASK((size))]
83
84 #define GET_BITMASK_BIT(name, bit) (((name)[(bit)/8] & (1 << ((bit) % 8))) ? 1 : 0)
85 // TODO - Need to do these atomically, or provide alternatives
86 #define SET_BITMASK_BIT(name, bit) ((name)[(bit)/8] |= (1 << ((bit) % 8)))
87 #define CLR_BITMASK_BIT(name, bit) ((name)[(bit)/8] &= ~(1 << ((bit) % 8)))
88 #define CLR_BITMASK_BIT_ATOMIC(name, bit) (atomic_andb(&(name)[(bit)/8], ~(1 << ((bit) % 8))))
89
90 #define CLR_BITMASK(name, size) (memset((name), 0, BYTES_FOR_BITMASK((size))))
91 #define FILL_BITMASK(name, size) ({ \
92         memset((name), 255, BYTES_FOR_BITMASK((size))); \
93         (name)[BYTES_FOR_BITMASK((size))-1] >>= (((size) % 8) ? (8 - ((size) % 8)) : 0 );}) 
94
95 #define COPY_BITMASK(newmask, oldmask, size) (memcpy((newmask), (oldmask), BYTES_FOR_BITMASK((size))))
96
97 // this checks the entire last byte, so keep it 0 in the other macros
98 #define BITMASK_IS_CLEAR(name, size) ({ \
99         uint32_t __n = BYTES_FOR_BITMASK((size)); \
100         bool clear = 1; \
101         while (__n-- > 0) { \
102                 if ((name)[__n]) { \
103                         clear = 0; \
104                         break;\
105                 }\
106         } \
107         clear; })
108
109 #define PRINT_MASK(name, size) { \
110         int i;  \
111         for (i = 0; i < BYTES_FOR_BITMASK(size); i++) { \
112                 int j;  \
113                 for (j = 0; j < 8; j++) \
114                         printk("%x", ((name)[i] >> j) & 1);     \
115         } \
116         printk("\n"); \
117 }
118 /**************************************************************/
119
120 #endif /* !ROS_INC_TYPES_H */