+struct side_rcu_read_state {
+ struct side_rcu_percpu_count *percpu_count;
+ int cpu;
+};
+
+extern unsigned int side_rcu_rseq_membarrier_available __attribute__((visibility("hidden")));
+
+static inline
+int futex(int32_t *uaddr, int op, int32_t val,
+ const struct timespec *timeout, int32_t *uaddr2, int32_t val3)
+{
+ return syscall(__NR_futex, uaddr, op, val, timeout, uaddr2, val3);
+}
+
+/*
+ * Wake-up side_rcu_wait_grace_period. Called concurrently from many
+ * threads.
+ */
+static inline
+void side_rcu_wake_up_gp(struct side_rcu_gp_state *gp_state)
+{
+ if (side_unlikely(__atomic_load_n(&gp_state->futex, __ATOMIC_RELAXED) == -1)) {
+ __atomic_store_n(&gp_state->futex, 0, __ATOMIC_RELAXED);
+ /* TODO: handle futex return values. */
+ (void) futex(&gp_state->futex, FUTEX_WAKE, 1, NULL, NULL, 0);
+ }
+}
+