#include <urcu/list.h>
#include <urcu/system.h>
#include <urcu/tls-compat.h>
+#include "urcu-die.h"
/*
* Number of entries in the per-thread defer queue. Must be power of 2.
* This is required to permit relinking with newer versions of the library.
*/
-#ifdef DEBUG_RCU
-#define rcu_assert(args...) assert(args)
-#else
-#define rcu_assert(args...)
-#endif
-
/*
* defer queue.
* Contains pointers. Encoded to save space when same callback is often used.
#ifndef DISTRUST_SIGNALS_EXTREME
ret = pthread_mutex_lock(mutex);
- if (ret) {
- perror("Error in pthread mutex lock");
- exit(-1);
- }
+ if (ret)
+ urcu_die(ret);
#else /* #ifndef DISTRUST_SIGNALS_EXTREME */
while ((ret = pthread_mutex_trylock(mutex)) != 0) {
- if (ret != EBUSY && ret != EINTR) {
- printf("ret = %d, errno = %d\n", ret, errno);
- perror("Error in pthread mutex lock");
- exit(-1);
- }
- poll(NULL,0,10);
+ if (ret != EBUSY && ret != EINTR)
+ urcu_die(ret);
+ (void) poll(NULL,0,10);
}
#endif /* #else #ifndef DISTRUST_SIGNALS_EXTREME */
}
{
if (caa_unlikely(uatomic_read(&defer_thread_futex) == -1)) {
uatomic_set(&defer_thread_futex, 0);
- futex_noasync(&defer_thread_futex, FUTEX_WAKE, 1,
- NULL, NULL, 0);
+ if (futex_noasync(&defer_thread_futex, FUTEX_WAKE, 1,
+ NULL, NULL, 0) < 0)
+ urcu_die(errno);
}
}
uatomic_set(&defer_thread_futex, 0);
} else {
cmm_smp_rmb(); /* Read queue before read futex */
- if (uatomic_read(&defer_thread_futex) == -1)
- futex_noasync(&defer_thread_futex, FUTEX_WAIT, -1,
- NULL, NULL, 0);
+ if (uatomic_read(&defer_thread_futex) != -1)
+ return;
+ while (futex_noasync(&defer_thread_futex, FUTEX_WAIT, -1,
+ NULL, NULL, 0)) {
+ switch (errno) {
+ case EWOULDBLOCK:
+ /* Value already changed. */
+ return;
+ case EINTR:
+ /* Retry if interrupted by signal. */
+ break; /* Get out of switch. */
+ default:
+ /* Unexpected error. */
+ urcu_die(errno);
+ }
+ }
}
}
/*
* _defer_rcu - Queue a RCU callback.
*/
-void _defer_rcu(void (*fct)(void *p), void *p)
+static void _defer_rcu(void (*fct)(void *p), void *p)
{
unsigned long head, tail;
wake_up_defer();
}
-void *thr_defer(void *args)
+static void *thr_defer(void *args)
{
for (;;) {
/*
*/
wait_defer();
/* Sleeping after wait_defer to let many callbacks enqueue */
- poll(NULL,0,100); /* wait for 100ms */
+ (void) poll(NULL,0,100); /* wait for 100ms */
rcu_defer_barrier();
}