WG21/P0461R1 3
Lines 4 and 5 show call rcu(), which, after a subsequent grace period
elapses, causes the cbf(rhp) RCU callback function to be invoked. Thus,
call rcu() is the asynchronous counterpart to synchronize rcu(). In most
cases, synchronize rcu() is easier to use, however, call rcu() has the ben-
efit of moving the grace-period delay off of the updater’s critical path. Use of
call rcu() is thus critically important for good performance of update-heavy
workloads, as has been repeatedly discovered by any number of people new to
RCU [2].
Note that although call rcu()’s callbacks are guaranteed not to be invoked
too early, there is no guarantee that their execution won’t be deferred for a con-
siderable time. This can be a problem if a given program requires that all
outstanding RCU callbacks be invoked before that program terminates. The
rcu barrier() function shown on line 6 is intended for this situation. This
function blocks until all callbacks corresponding to previous call rcu() invo-
cations have been invoked and also until after those invocations have returned.
Therefore, taking the following steps just before terminating a program will
guarantee that all callbacks have completed:
1. Take whatever steps are required to ensure that there are no further in-
vocations of call rcu().
2. Invoke rcu barrier().
Carrying out this procedure just prior to program termination can be very
helpful for avoiding false positives when using tools such as valgrind.
Many RCU implementations require that every thread announce itself to
RCU prior to entering the first RCU read-side critical section, and to announce
its departure after exiting the last RCU read-side critical section. These tasks
are carried out via the rcu register thread() and rcu unregister thread(),
respectively.
The implementations of RCU that feature the most aggressive implemen-
tations of rcu read lock() and rcu read unlock() require that each thread
periodically pass through a quiescent state, which is announced to RCU using
rcu quiescent state(). A thread in a quiescent state is guaranteed not to
be in an RCU read-side critical section. Threads can also announce entry into
and exit from extended quiescent states, for example, before and after blocking
system calls, using rcu thread offline() and rcu thread online().
2.1 RCU Domains
The userspace RCU library features several RCU implementations, each opti-
mized for different use cases.
The quiescent-state based reclamation (QSBR) implementation is intended
for standalone applications where the developers have full control over the en-
tire application, and where extreme read-side performance and scalability is
required. Applications use #include "urcu-qsbr.hpp" to select QSBR and