+void free_cds_ja_node(struct cds_ja *ja, struct cds_ja_inode *node);
+
+/*
+ * Iterate through duplicates returned by cds_ja_lookup*()
+ * Receives a struct cds_ja_node * as parameter, which is used as start
+ * of duplicate list and loop cursor.
+ */
+#define cds_ja_for_each_duplicate(pos) \
+ for (; (pos) != NULL; (pos) = (pos)->next)
+
+/*
+ * Iterate through duplicates returned by cds_ja_lookup*()
+ * Safe against removal of entries during traversal.
+ */
+#define cds_ja_for_each_duplicate_safe(_pos, _next) \
+ for (; (_pos) != NULL ? ((_next) = (_pos)->next, 1) : 0; \
+ (_pos) = (_next))
+
+//#define DEBUG
+
+#ifdef __linux__
+#include <syscall.h>
+#endif
+
+#if defined(_syscall0)
+_syscall0(pid_t, gettid)
+#elif defined(__NR_gettid)
+static inline pid_t gettid(void)
+{
+ return syscall(__NR_gettid);
+}
+#else
+#warning "use pid as tid"
+static inline pid_t gettid(void)
+{
+ return getpid();
+}
+#endif
+
+#ifdef DEBUG
+#define dbg_printf(fmt, args...) \
+ fprintf(stderr, "[debug rcuja %lu %s()@%s:%u] " fmt, \
+ (unsigned long) gettid(), __func__, \
+ __FILE__, __LINE__, ## args)
+#else
+#define dbg_printf(fmt, args...) \
+do { \
+ /* do nothing but check printf format */ \
+ if (0) \
+ fprintf(stderr, "[debug rcuja %lu %s()@%s:%u] " fmt, \
+ (unsigned long) gettid(), __func__, \
+ __FILE__, __LINE__, ## args); \
+} while (0)
+#endif