Use two-page stacks
[akaros.git] / kern / include / common.h
1 #pragma once
2
3 #include <ros/common.h>
4 #include <compiler.h>
5
6 /* Force a rebuild of the whole kernel if 64BIT-ness changed */
7 #ifdef CONFIG_64BIT
8 #endif
9
10 #define PASTE_THEM(x, y) x ## y
11 #define PASTE(x, y) PASTE_THEM(x, y)
12
13 // Efficient min and max operations
14 #define MIN(_a, _b)                                             \
15 ({                                                              \
16         typeof(_a) __a = (_a);                                  \
17         typeof(_b) __b = (_b);                                  \
18         __a <= __b ? __a : __b;                                 \
19 })
20 #define MAX(_a, _b)                                             \
21 ({                                                              \
22         typeof(_a) __a = (_a);                                  \
23         typeof(_b) __b = (_b);                                  \
24         __a >= __b ? __a : __b;                                 \
25 })
26
27 /* Test for alignment, e.g. 2^6 */
28 #define ALIGNED(p, a)   (!(((uintptr_t)(p)) & ((a)-1)))
29 /* Aligns x up to the mask, e.g. (2^6 - 1) (round up if any mask bits are set)*/
30 #define __ALIGN_MASK(x, mask) (((uintptr_t)(x) + (mask)) & ~(mask))
31 /* Aligns x up to the alignment, e.g. 2^6. */
32 #define ALIGN(x, a) ((typeof(x)) __ALIGN_MASK(x, (a) - 1))
33 /* Aligns x down to the mask, e.g. (2^6 - 1)
34  * (round down if any mask bits are set)*/
35 #define __ALIGN_MASK_DOWN(x, mask) ((uintptr_t)(x) & ~(mask))
36 /* Aligns x down to the alignment, e.g. 2^6. */
37 #define ALIGN_DOWN(x, a) ((typeof(x)) __ALIGN_MASK_DOWN(x, (a) - 1))
38 /* Will return false for 0.  Debatable, based on what you want. */
39 #define IS_PWR2(x) ((x) && !((x) & (x - 1)))
40
41 #define ARRAY_SIZE(x) COUNT_OF(x)
42
43 /* Makes sure func is run exactly once.  Can handle concurrent callers, and
44  * other callers spin til the func is complete. */
45 #define run_once(func)                                                         \
46 do {                                                                           \
47         static bool ran_once = FALSE;                                              \
48         static bool is_running = FALSE;                                            \
49         if (!ran_once) {                                                           \
50                 /* fetch and set TRUE, without a header or test_and_set weirdness */   \
51                 if (!__sync_fetch_and_or(&is_running, TRUE)) {                         \
52                         /* we won the race and get to run the func */                      \
53                         func;                                                              \
54                         wmb();  /* don't let the ran_once write pass previous writes */    \
55                         ran_once = TRUE;                                                   \
56                 } else {                                                               \
57                         /* someone else won, wait til they are done to break out */        \
58                         while (!ran_once)                                                  \
59                                 cpu_relax();                                                   \
60                 }                                                                      \
61         }                                                                          \
62 } while (0)
63
64 /* Unprotected, single-threaded version, makes sure func is run exactly once */
65 #define run_once_racy(func)                                                    \
66 do {                                                                           \
67         static bool ran_once = FALSE;                                              \
68         if (!ran_once) {                                                           \
69                 func;                                                                  \
70                 ran_once = TRUE;                                                       \
71         }                                                                          \
72 } while (0)
73
74 #ifndef __ASSEMBLER__
75
76 static inline uint32_t low32(uint64_t val)
77 {
78         return val & 0xffffffff;
79 }
80
81 static inline uint32_t high32(uint64_t val)
82 {
83         return val >> 32;
84 }
85
86 #endif /* !__ASSEMBLER__ */