32 Concurrency support library [thread]

32.11 Safe reclamation [saferecl]

32.11.2 Read-copy update (RCU) [saferecl.rcu]

32.11.2.4 Class rcu_domain [saferecl.rcu.domain]

32.11.2.4.1 General [saferecl.rcu.domain.general]

namespace std { class rcu_domain { public: rcu_domain(const rcu_domain&) = delete; rcu_domain& operator=(const rcu_domain&) = delete; void lock() noexcept; bool try_lock() noexcept; void unlock() noexcept; }; }
This class meets the requirements of Cpp17Lockable ([thread.req.lockable.req]) and provides regions of RCU protection.
[Example 1: std::scoped_lock<rcu_domain> rlock(rcu_default_domain()); — end example]
The functions lock and unlock establish (possibly nested) regions of RCU protection.

32.11.2.4.2 Member functions [saferecl.rcu.domain.members]

void lock() noexcept;
Effects: Opens a region of RCU protection.
Remarks: Calls to lock do not introduce a data race ([intro.races]) involving *this.
bool try_lock() noexcept;
Effects: Equivalent to lock().
Returns: true.
void unlock() noexcept;
Preconditions: A call to lock that opened an unclosed region of RCU protection is sequenced before the call to unlock.
Effects: Closes the unclosed region of RCU protection that was most recently opened.
May invoke scheduled evaluations in *this.
[Note 1: 
If such evaluations acquire resources held across any invocation of unlock on *this, deadlock can occur.
— end note]
Remarks: Calls to unlock do not introduce a data race involving *this.
[Note 2: 
Evaluation of scheduled evaluations can still cause a data race.
— end note]

32.11.2.4.3 Non-member functions [saferecl.rcu.domain.func]

rcu_domain& rcu_default_domain() noexcept;
Returns: A reference to a static-duration object of type rcu_domain.
A reference to the same object is returned every time this function is called.
void rcu_synchronize(rcu_domain& dom = rcu_default_domain()) noexcept;
Effects: If the call to rcu_synchronize does not strongly happen before the lock opening an RCU protection region R on dom, blocks until the unlock closing R happens.
Synchronization: The unlock closing R strongly happens before the return from rcu_synchronize.
void rcu_barrier(rcu_domain& dom = rcu_default_domain()) noexcept;
Effects: May evaluate any scheduled evaluations in dom.
For any evaluation that happens before the call to rcu_barrier and that schedules an evaluation E in dom, blocks until E has been evaluated.
Synchronization: The evaluation of any such E strongly happens before the return from rcu_barrier.
[Note 1: 
A call to rcu_barrier does not imply a call to rcu_synchronize and vice versa.
— end note]
template<class T, class D = default_delete<T>> void rcu_retire(T* p, D d = D(), rcu_domain& dom = rcu_default_domain());
Mandates: is_move_constructible_v<D> is true and the expression d(p) is well-formed.
Preconditions: D meets the Cpp17MoveConstructible and Cpp17Destructible requirements.
Effects: May allocate memory.
It is unspecified whether the memory allocation is performed by invoking operator new.
Initializes an object d1 of type D from std​::​move(d).
Schedules the evaluation of d1(p) in the domain dom; the behavior is undefined if that evaluation exits via an exception.
May invoke scheduled evaluations in dom.
[Note 2: 
If rcu_retire exits via an exception, no evaluation is scheduled.
— end note]
Throws: bad_alloc or any exception thrown by the initialization of d1.
[Note 3: 
If scheduled evaluations acquire resources held across any invocation of rcu_retire on dom, deadlock can occur.
— end note]