Support atomic printks
[akaros.git] / kern / include / ros / common.h
index 5063567..7bf4958 100644 (file)
@@ -1,15 +1,12 @@
-#ifndef ROS_COMMON_H
-#define ROS_COMMON_H
+#pragma once
 
 #ifndef __ASSEMBLER__
-#ifndef __IVY__
-#include <ros/noivy.h>
-#endif
 
 #include <stddef.h>
 #include <stdint.h>
 #include <sys/types.h>
 #include <stdbool.h>
+#include <string.h>
 
 typedef uintptr_t physaddr_t;
 typedef long intreg_t;
@@ -27,37 +24,23 @@ typedef unsigned long uintreg_t;
 #define FALSE  0
 #endif
 
-#define KiB    1024u
-#define MiB    1048576u
-#define GiB    1073741824u
-#define TiB    1099511627776ull
-#define PiB    1125899906842624ull
-#define EiB    1152921504606846976ull
+#define FOR_CIRC_BUFFER(next, size, var) \
+       for (int _var = 0, var = (next); _var < (size); _var++, var = (var + 1) % (size))
 
-#define ALIGNED(p, a)  (!(((uintptr_t)(p)) & ((a)-1)))
+#define STRINGIFY(s) __STRINGIFY(s)
+#define __STRINGIFY(s) #s
 
-#define ARRAY_SIZE(x) (sizeof((x))/sizeof((x)[0]))
+/* A macro for testing if another macro has been #defined or not.  Can be used
+ * wherever you need a boolean defined.  Returns 0 or 1. */
+#define is_defined(macro) is_defined_(macro)
+#define is_defined_test_1 ,
+#define is_defined_(value) is_defined__(is_defined_test_##value, value)
+#define is_defined__(comma, value) is_defined___(comma 1, 0)
+#define is_defined___(_, v, ...) v
 
-#define CHECK_FLAG(flags,bit)   ((flags) & (1 << (bit)))
+#define COUNT_OF(x) (sizeof((x))/sizeof((x)[0]))
 
-#define FOR_CIRC_BUFFER(next, size, var) \
-       for (int _var = 0, var = (next); _var < (size); _var++, var = (var + 1) % (size))
-
-// Efficient min and max operations
-#ifdef ROS_KERNEL /* Glibc has their own */
-#define MIN(_a, _b)                                            \
-({                                                             \
-       typeof(_a) __a = (_a);                                  \
-       typeof(_b) __b = (_b);                                  \
-       __a <= __b ? __a : __b;                                 \
-})
-#define MAX(_a, _b)                                            \
-({                                                             \
-       typeof(_a) __a = (_a);                                  \
-       typeof(_b) __b = (_b);                                  \
-       __a >= __b ? __a : __b;                                 \
-})
-#endif
+#define ZERO_DATA(s) memset(&(s), 0, sizeof(s))
 
 /* Rounding operations (efficient when n is a power of 2)
  * Round down to the nearest multiple of n.
@@ -91,22 +74,22 @@ typedef unsigned long uintreg_t;
 })
 
 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
+
 // Return the integer logarithm of the value provided rounded down
 static inline uintptr_t LOG2_DOWN(uintptr_t value)
 {
-       uintptr_t l = 0;
-       while( (value >> l) > 1 ) ++l;
-       return l;
+       value |= 1;  // clz(0) is undefined, just or in a 1 bit and define it
+       // intrinsic __builtin_clz supported by both > gcc4.6 and LLVM > 1.5
+       return (sizeof(value) == 8) ? 63 - __builtin_clzll(value)
+                                   : 31 - __builtin_clz(value);
 }
 
 // Return the integer logarithm of the value provided rounded up
 static inline uintptr_t LOG2_UP(uintptr_t value)
 {
-       uintptr_t _v = LOG2_DOWN(value);
-       if (value ^ (1 << _v))
-               return _v + 1;
-       else
-               return _v;
+       uintptr_t ret = LOG2_DOWN(value);
+       ret += 0 != (value ^ ((uintptr_t) 1 << ret));  // Add 1 if a lower bit set
+       return ret;
 }
 
 static inline uintptr_t ROUNDUPPWR2(uintptr_t value)
@@ -137,22 +120,15 @@ static inline bool mult_will_overflow_u64(uint64_t a, uint64_t b)
        (type*)((char*)ptr - offsetof(type, member));                             \
 })
 
-/* Force the reading exactly once of x.  You may still need mbs().  See
- * http://lwn.net/Articles/508991/ for more info. */
-#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
-
-// Ivy currently can only handle 63 bits (OCaml thing), so use this to make
-// a uint64_t programatically
-#define UINT64(upper, lower) ( (((uint64_t)(upper)) << 32) | (lower) )
-
 /* Makes sure func is run exactly once.  Can handle concurrent callers, and
  * other callers spin til the func is complete. */
 #define run_once(func)                                                         \
-{                                                                              \
+do {                                                                           \
        static bool ran_once = FALSE;                                              \
-       static atomic_t is_running = FALSE;                                        \
+       static bool is_running = FALSE;                                            \
        if (!ran_once) {                                                           \
-               if (!atomic_swap(&is_running, TRUE)) {                                 \
+               /* fetch and set TRUE, without a header or test_and_set weirdness */   \
+               if (!__sync_fetch_and_or(&is_running, TRUE)) {                         \
                        /* we won the race and get to run the func */                      \
                        func;                                                              \
                        wmb();  /* don't let the ran_once write pass previous writes */    \
@@ -161,33 +137,28 @@ static inline bool mult_will_overflow_u64(uint64_t a, uint64_t b)
                        /* someone else won, wait til they are done to break out */        \
                        while (!ran_once)                                                  \
                                cpu_relax();                                                   \
-                                                                               \
                }                                                                      \
        }                                                                          \
-}
+} while (0)
 
 /* Unprotected, single-threaded version, makes sure func is run exactly once */
 #define run_once_racy(func)                                                    \
-{                                                                              \
+do {                                                                           \
        static bool ran_once = FALSE;                                              \
        if (!ran_once) {                                                           \
                func;                                                                  \
                ran_once = TRUE;                                                       \
        }                                                                          \
-}
+} while (0)
 
-/* Aborts with 'retcmd' if this function has already been called.  Compared to
- * run_once, this is put at the top of a function that can be called from
- * multiple sources but should only execute once. */
-#define init_once_racy(retcmd)                                                 \
-{                                                                              \
-       static bool initialized = FALSE;                                           \
-       if (initialized) {                                                         \
-               retcmd;                                                                \
-       }                                                                          \
-       initialized = TRUE;                                                        \
-}
+#ifdef ROS_KERNEL
+#include <compiler.h>
+#else
+/* Force the reading/writing exactly once of x.  You may still need mbs().  See
+ * http://lwn.net/Articles/508991/ for more info. */
+#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
+#define READ_ONCE(x) ACCESS_ONCE(x)
+#define WRITE_ONCE(x, val) ((*(volatile typeof(x) *)&(x)) = val)
+#endif
 
 #endif /* __ASSEMBLER__ */
-
-#endif /* ROS_COMMON_H */