#ifndef _UCW_LIB_H
#define _UCW_LIB_H
-#include "ucw/config.h"
+#include <ucw/config.h>
#include <stdarg.h>
/*** === Macros for handling structures, offsets and alignment ***/
#define NONRET __attribute__((noreturn)) /** Function does not return **/
#define UNUSED __attribute__((unused)) /** Variable/parameter is knowingly unused **/
#define CONSTRUCTOR __attribute__((constructor)) /** Call function upon start of program **/
+#define CONSTRUCTOR_WITH_PRIORITY(p) __attribute__((constructor(p))) /** Define constructor with a given priority **/
#define PACKED __attribute__((packed)) /** Structure should be packed **/
#define CONST __attribute__((const)) /** Function depends only on arguments **/
#define PURE __attribute__((pure)) /** Function depends only on arguments and global vars **/
#ifdef LOCAL_DEBUG
#define DBG(x,y...) msg(L_DEBUG, x,##y) /** If `LOCAL_DEBUG` is defined before including <ucw/lib.h>, log a debug message. Otherwise do nothing. **/
+/**
+ * If `LOCAL_DEBUG` is defined before including <ucw/lib.h>, log current
+ * file name and line number. Otherwise do nothing.
+ **/
+#define DBG_SPOT msg(L_DEBUG, "%s:%d (%s)", __FILE__, __LINE__, __func__)
#else
#define DBG(x,y...) do { } while(0)
+#define DBG_SPOT do { } while(0)
+#endif
+
+#ifdef DEBUG_ASSERTS
+/**
+ * Sometimes, we may want to check that a pointer points to a valid memory
+ * location before we start using it for anything more complicated. This
+ * macro checks pointer validity by reading the byte it points to.
+ **/
+#define ASSERT_READABLE(ptr) ({ volatile char *__p = (ptr); *__p; })
+/** Like the previous macro, but it checks writeability, too. **/
+#define ASSERT_WRITEABLE(ptr) ({ volatile char *__p = (ptr); *__p = *__p; })
+#else
+#define ASSERT_READABLE(ptr) do { } while(0)
+#define ASSERT_WRITEABLE(ptr) do { } while(0)
#endif
/*** === Memory allocation ***/
void *big_alloc_zero(u64 len) LIKE_MALLOC; /** Allocate and clear a large memory block. **/
void big_free(void *start, u64 len); /** Free block allocated by @big_alloc() or @big_alloc_zero(). **/
-/*** === Trivial timers (timer.c) ***/
-
-timestamp_t get_timestamp(void); /** Get current time as a millisecond timestamp. **/
-
-void init_timer(timestamp_t *timer); /** Initialize a timer. **/
-uns get_timer(timestamp_t *timer); /** Get the number of milliseconds since last init/get of a timer. **/
-uns switch_timer(timestamp_t *oldt, timestamp_t *newt); /** Stop ticking of one timer and resume another. **/
-
/*** === Random numbers (random.c) ***/
uns random_u32(void); /** Return a pseudorandom 32-bit number. **/