234 lines
7.7 KiB
Markdown
234 lines
7.7 KiB
Markdown
[saferecl.rcu.domain]
|
||
|
||
# 32 Concurrency support library [[thread]](./#thread)
|
||
|
||
## 32.11 Safe reclamation [[saferecl]](saferecl#rcu.domain)
|
||
|
||
### 32.11.2 Read-copy update (RCU) [[saferecl.rcu]](saferecl.rcu#domain)
|
||
|
||
#### 32.11.2.4 Class rcu_domain [saferecl.rcu.domain]
|
||
|
||
#### [32.11.2.4.1](#general) General [[saferecl.rcu.domain.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; };}
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13089)
|
||
|
||
This class meets the requirements of[*Cpp17Lockable*](thread.req.lockable.req#:Cpp17Lockable "32.2.5.3 Cpp17Lockable requirements [thread.req.lockable.req]") ([[thread.req.lockable.req]](thread.req.lockable.req "32.2.5.3 Cpp17Lockable requirements")) and
|
||
provides regions of RCU protection[.](#general-1.sentence-1)
|
||
|
||
[*Example [1](#general-example-1)*: std::scoped_lock<rcu_domain> rlock(rcu_default_domain()); â *end example*]
|
||
|
||
[2](#general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13099)
|
||
|
||
The functions lock and unlock establish
|
||
(possibly nested) regions of RCU protection[.](#general-2.sentence-1)
|
||
|
||
#### [32.11.2.4.2](#members) Member functions [[saferecl.rcu.domain.members]](saferecl.rcu.domain.members)
|
||
|
||
[ð](#lib:lock,rcu_domain)
|
||
|
||
`void lock() noexcept;
|
||
`
|
||
|
||
[1](#members-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13111)
|
||
|
||
*Effects*: Opens a region of RCU protection[.](#members-1.sentence-1)
|
||
|
||
[2](#members-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13115)
|
||
|
||
*Remarks*: Calls to lock do not introduce a data race ([[intro.races]](intro.races "6.10.2.2 Data races")) involving *this[.](#members-2.sentence-1)
|
||
|
||
[ð](#lib:try_lock,rcu_domain)
|
||
|
||
`bool try_lock() noexcept;
|
||
`
|
||
|
||
[3](#members-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13127)
|
||
|
||
*Effects*: Equivalent to lock()[.](#members-3.sentence-1)
|
||
|
||
[4](#members-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13131)
|
||
|
||
*Returns*: true[.](#members-4.sentence-1)
|
||
|
||
[ð](#lib:unlock,rcu_domain)
|
||
|
||
`void unlock() noexcept;
|
||
`
|
||
|
||
[5](#members-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13142)
|
||
|
||
*Preconditions*: A call to lock that opened an unclosed region of RCU protection
|
||
is sequenced before the call to unlock[.](#members-5.sentence-1)
|
||
|
||
[6](#members-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13148)
|
||
|
||
*Effects*: Closes the unclosed region of RCU protection
|
||
that was most recently opened[.](#members-6.sentence-1)
|
||
|
||
May invoke scheduled evaluations in *this[.](#members-6.sentence-2)
|
||
|
||
[7](#members-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13154)
|
||
|
||
[*Note [1](#members-note-1)*:
|
||
|
||
If such evaluations acquire resources
|
||
held across any invocation of unlock on *this,
|
||
deadlock can occur[.](#members-7.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[8](#members-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13161)
|
||
|
||
*Remarks*: Calls to unlock do not introduce a data race involving *this[.](#members-8.sentence-1)
|
||
|
||
[*Note [2](#members-note-2)*:
|
||
|
||
Evaluation of scheduled evaluations can still cause a data race[.](#members-8.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
#### [32.11.2.4.3](#func) Non-member functions [[saferecl.rcu.domain.func]](saferecl.rcu.domain.func)
|
||
|
||
[ð](#lib:rcu_default_domain)
|
||
|
||
`rcu_domain& rcu_default_domain() noexcept;
|
||
`
|
||
|
||
[1](#func-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13177)
|
||
|
||
*Returns*: A reference to a static-duration object of type rcu_domain[.](#func-1.sentence-1)
|
||
|
||
A reference to the same object is returned every time this function is called[.](#func-1.sentence-2)
|
||
|
||
[ð](#lib:rcu_synchronize)
|
||
|
||
`void rcu_synchronize(rcu_domain& dom = rcu_default_domain()) noexcept;
|
||
`
|
||
|
||
[2](#func-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13189)
|
||
|
||
*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[.](#func-2.sentence-1)
|
||
|
||
[3](#func-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13195)
|
||
|
||
*Synchronization*: The unlock closing R strongly happens before the return from rcu_synchronize[.](#func-3.sentence-1)
|
||
|
||
[ð](#lib:rcu_barrier)
|
||
|
||
`void rcu_barrier(rcu_domain& dom = rcu_default_domain()) noexcept;
|
||
`
|
||
|
||
[4](#func-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13207)
|
||
|
||
*Effects*: May evaluate any scheduled evaluations in dom[.](#func-4.sentence-1)
|
||
|
||
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[.](#func-4.sentence-2)
|
||
|
||
[5](#func-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13214)
|
||
|
||
*Synchronization*: The evaluation of any such E strongly happens before the return from rcu_barrier[.](#func-5.sentence-1)
|
||
|
||
[*Note [1](#func-note-1)*:
|
||
|
||
A call to rcu_barrier does not imply
|
||
a call to rcu_synchronize and vice versa[.](#func-5.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:rcu_retire)
|
||
|
||
`template<class T, class D = default_delete<T>>
|
||
void rcu_retire(T* p, D d = D(), rcu_domain& dom = rcu_default_domain());
|
||
`
|
||
|
||
[6](#func-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13232)
|
||
|
||
*Mandates*: is_move_constructible_v<D> is true and
|
||
the expression d(p) is well-formed[.](#func-6.sentence-1)
|
||
|
||
[7](#func-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13237)
|
||
|
||
*Preconditions*: D meets the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and[*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#func-7.sentence-1)
|
||
|
||
[8](#func-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13242)
|
||
|
||
*Effects*: May allocate memory[.](#func-8.sentence-1)
|
||
|
||
It is unspecified whether the memory allocation
|
||
is performed by invoking operator new[.](#func-8.sentence-2)
|
||
|
||
Initializes an object d1 of type D from std::move(d)[.](#func-8.sentence-3)
|
||
|
||
Schedules the evaluation of d1(p) in the domain dom;
|
||
the behavior is undefined if that evaluation exits via an exception[.](#func-8.sentence-4)
|
||
|
||
May invoke scheduled evaluations in dom[.](#func-8.sentence-5)
|
||
|
||
[*Note [2](#func-note-2)*:
|
||
|
||
If rcu_retire exits via an exception, no evaluation
|
||
is scheduled[.](#func-8.sentence-6)
|
||
|
||
â *end note*]
|
||
|
||
[9](#func-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13256)
|
||
|
||
*Throws*: bad_alloc or any exception thrown by the initialization of d1[.](#func-9.sentence-1)
|
||
|
||
[10](#func-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13260)
|
||
|
||
[*Note [3](#func-note-3)*:
|
||
|
||
If scheduled evaluations acquire resources
|
||
held across any invocation of rcu_retire on dom,
|
||
deadlock can occur[.](#func-10.sentence-1)
|
||
|
||
â *end note*]
|