From Jason Turner

[saferecl.rcu]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpti98r3f2/{from.md → to.md} +250 -0
tmp/tmpti98r3f2/{from.md → to.md} RENAMED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Read-copy update (RCU) <a id="saferecl.rcu">[[saferecl.rcu]]</a>
2
+
3
+ #### General <a id="saferecl.rcu.general">[[saferecl.rcu.general]]</a>
4
+
5
+ RCU is a synchronization mechanism that can be used for linked data
6
+ structures that are frequently read, but seldom updated. RCU does not
7
+ provide mutual exclusion, but instead allows the user to schedule
8
+ specified actions such as deletion at some later time.
9
+
10
+ A class type `T` is *rcu-protectable* if it has exactly one base class
11
+ of type `rcu_obj_base<T, D>` for some `D`, and that base is public and
12
+ non-virtual, and it has no base classes of type `rcu_obj_base<X, Y>` for
13
+ any other combination `X`, `Y`. An object is rcu-protectable if it is of
14
+ rcu-protectable type.
15
+
16
+ An invocation of `unlock` U on an `rcu_domain dom` corresponds to an
17
+ invocation of `lock` L on `dom` if L is sequenced before U and either
18
+
19
+ - no other invocation of `lock` on `dom` is sequenced after L and before
20
+ U, or
21
+ - every invocation of `unlock` U2 on `dom` such that L is sequenced
22
+ before U2 and U2 is sequenced before U corresponds to an invocation of
23
+ `lock` L2 on `dom` such that L is sequenced before L2 and L2 is
24
+ sequenced before U2.
25
+
26
+ [*Note 1*: This pairs nested locks and unlocks on a given domain in
27
+ each thread. — *end note*]
28
+
29
+ A *region of RCU protection* on a domain `dom` starts with a `lock` L on
30
+ `dom` and ends with its corresponding `unlock` U.
31
+
32
+ Given a region of RCU protection R on a domain `dom` and given an
33
+ evaluation E that scheduled another evaluation F in `dom`, if E does not
34
+ strongly happen before the start of R, the end of R strongly happens
35
+ before evaluating F.
36
+
37
+ The evaluation of a scheduled evaluation is potentially concurrent with
38
+ any other scheduled evaluation. Each scheduled evaluation is evaluated
39
+ at most once.
40
+
41
+ #### Header `<rcu>` synopsis <a id="rcu.syn">[[rcu.syn]]</a>
42
+
43
+ ``` cpp
44
+ namespace std {
45
+ // [saferecl.rcu.base], class template rcu_obj_base
46
+ template<class T, class D = default_delete<T>> class rcu_obj_base;
47
+
48
+ // [saferecl.rcu.domain], class rcu_domain
49
+ class rcu_domain;
50
+
51
+ // [saferecl.rcu.domain.func], non-member functions
52
+ rcu_domain& rcu_default_domain() noexcept;
53
+ void rcu_synchronize(rcu_domain& dom = rcu_default_domain()) noexcept;
54
+ void rcu_barrier(rcu_domain& dom = rcu_default_domain()) noexcept;
55
+ template<class T, class D = default_delete<T>>
56
+ void rcu_retire(T* p, D d = D(), rcu_domain& dom = rcu_default_domain());
57
+ }
58
+ ```
59
+
60
+ #### Class template `rcu_obj_base` <a id="saferecl.rcu.base">[[saferecl.rcu.base]]</a>
61
+
62
+ Objects of type `T` to be protected by RCU inherit from a specialization
63
+ `rcu_obj_base<T, D>` for some `D`.
64
+
65
+ ``` cpp
66
+ namespace std {
67
+ template<class T, class D = default_delete<T>>
68
+ class rcu_obj_base {
69
+ public:
70
+ void retire(D d = D(), rcu_domain& dom = rcu_default_domain()) noexcept;
71
+ protected:
72
+ rcu_obj_base() = default;
73
+ rcu_obj_base(const rcu_obj_base&) = default;
74
+ rcu_obj_base(rcu_obj_base&&) = default;
75
+ rcu_obj_base& operator=(const rcu_obj_base&) = default;
76
+ rcu_obj_base& operator=(rcu_obj_base&&) = default;
77
+ ~rcu_obj_base() = default;
78
+ private:
79
+ D deleter; // exposition only
80
+ };
81
+ }
82
+ ```
83
+
84
+ The behavior of a program that adds specializations for `rcu_obj_base`
85
+ is undefined.
86
+
87
+ `T` may be an incomplete type. It shall be complete before any member of
88
+ the resulting specialization of `rcu_obj_base` is referenced.
89
+
90
+ `D` shall be a function object type [[function.objects]] for which,
91
+ given a value `d` of type `D` and a value `ptr` of type `T*`, the
92
+ expression `d(ptr)` is valid.
93
+
94
+ `D` shall meet the requirements for *Cpp17DefaultConstructible* and
95
+ *Cpp17MoveAssignable*.
96
+
97
+ If `D` is trivially copyable, all specializations of
98
+ `rcu_obj_base<T, D>` are trivially copyable.
99
+
100
+ ``` cpp
101
+ void retire(D d = D(), rcu_domain& dom = rcu_default_domain()) noexcept;
102
+ ```
103
+
104
+ *Mandates:* `T` is an rcu-protectable type.
105
+
106
+ *Preconditions:* `*this` is a base class subobject of an object `x` of
107
+ type `T`. The member function `rcu_obj_base<T, D>::retire` was not
108
+ invoked on `x` before. The assignment to *deleter* does not exit via an
109
+ exception.
110
+
111
+ *Effects:* Evaluates *`deleter`*` = std::move(d)` and schedules the
112
+ evaluation of the expression *`deleter`*`( addressof(x))` in the domain
113
+ `dom`; the behavior is undefined if that evaluation exits via an
114
+ exception. May invoke scheduled evaluations in `dom`.
115
+
116
+ [*Note 1*: If such evaluations acquire resources held across any
117
+ invocation of `retire` on `dom`, deadlock can occur. — *end note*]
118
+
119
+ #### Class `rcu_domain` <a id="saferecl.rcu.domain">[[saferecl.rcu.domain]]</a>
120
+
121
+ ##### General <a id="saferecl.rcu.domain.general">[[saferecl.rcu.domain.general]]</a>
122
+
123
+ ``` cpp
124
+ namespace std {
125
+ class rcu_domain {
126
+ public:
127
+ rcu_domain(const rcu_domain&) = delete;
128
+ rcu_domain& operator=(const rcu_domain&) = delete;
129
+
130
+ void lock() noexcept;
131
+ bool try_lock() noexcept;
132
+ void unlock() noexcept;
133
+ };
134
+ }
135
+ ```
136
+
137
+ This class meets the requirements of *Cpp17Lockable*
138
+ [[thread.req.lockable.req]] and provides regions of RCU protection.
139
+
140
+ [*Example 1*:
141
+
142
+ ``` cpp
143
+ std::scoped_lock<rcu_domain> rlock(rcu_default_domain());
144
+ ```
145
+
146
+ — *end example*]
147
+
148
+ The functions `lock` and `unlock` establish (possibly nested) regions of
149
+ RCU protection.
150
+
151
+ ##### Member functions <a id="saferecl.rcu.domain.members">[[saferecl.rcu.domain.members]]</a>
152
+
153
+ ``` cpp
154
+ void lock() noexcept;
155
+ ```
156
+
157
+ *Effects:* Opens a region of RCU protection.
158
+
159
+ *Remarks:* Calls to `lock` do not introduce a data race [[intro.races]]
160
+ involving `*this`.
161
+
162
+ ``` cpp
163
+ bool try_lock() noexcept;
164
+ ```
165
+
166
+ *Effects:* Equivalent to `lock()`.
167
+
168
+ *Returns:* `true`.
169
+
170
+ ``` cpp
171
+ void unlock() noexcept;
172
+ ```
173
+
174
+ *Preconditions:* A call to `lock` that opened an unclosed region of RCU
175
+ protection is sequenced before the call to `unlock`.
176
+
177
+ *Effects:* Closes the unclosed region of RCU protection that was most
178
+ recently opened. May invoke scheduled evaluations in `*this`.
179
+
180
+ [*Note 1*: If such evaluations acquire resources held across any
181
+ invocation of `unlock` on `*this`, deadlock can occur. — *end note*]
182
+
183
+ *Remarks:* Calls to `unlock` do not introduce a data race involving
184
+ `*this`.
185
+
186
+ [*Note 2*: Evaluation of scheduled evaluations can still cause a data
187
+ race. — *end note*]
188
+
189
+ ##### Non-member functions <a id="saferecl.rcu.domain.func">[[saferecl.rcu.domain.func]]</a>
190
+
191
+ ``` cpp
192
+ rcu_domain& rcu_default_domain() noexcept;
193
+ ```
194
+
195
+ *Returns:* A reference to a static-duration object of type `rcu_domain`.
196
+ A reference to the same object is returned every time this function is
197
+ called.
198
+
199
+ ``` cpp
200
+ void rcu_synchronize(rcu_domain& dom = rcu_default_domain()) noexcept;
201
+ ```
202
+
203
+ *Effects:* If the call to `rcu_synchronize` does not strongly happen
204
+ before the lock opening an RCU protection region `R` on `dom`, blocks
205
+ until the `unlock` closing `R` happens.
206
+
207
+ *Synchronization:* The `unlock` closing `R` strongly happens before the
208
+ return from `rcu_synchronize`.
209
+
210
+ ``` cpp
211
+ void rcu_barrier(rcu_domain& dom = rcu_default_domain()) noexcept;
212
+ ```
213
+
214
+ *Effects:* May evaluate any scheduled evaluations in `dom`. For any
215
+ evaluation that happens before the call to `rcu_barrier` and that
216
+ schedules an evaluation E in `dom`, blocks until E has been evaluated.
217
+
218
+ *Synchronization:* The evaluation of any such E strongly happens before
219
+ the return from `rcu_barrier`.
220
+
221
+ [*Note 3*: A call to `rcu_barrier` does not imply a call to
222
+ `rcu_synchronize` and vice versa. — *end note*]
223
+
224
+ ``` cpp
225
+ template<class T, class D = default_delete<T>>
226
+ void rcu_retire(T* p, D d = D(), rcu_domain& dom = rcu_default_domain());
227
+ ```
228
+
229
+ *Mandates:* `is_move_constructible_v<D>` is `true` and the expression
230
+ `d(p)` is well-formed.
231
+
232
+ *Preconditions:* `D` meets the *Cpp17MoveConstructible* and
233
+ *Cpp17Destructible* requirements.
234
+
235
+ *Effects:* May allocate memory. It is unspecified whether the memory
236
+ allocation is performed by invoking `operator new`. Initializes an
237
+ object `d1` of type `D` from `std::move(d)`. Schedules the evaluation of
238
+ `d1(p)` in the domain `dom`; the behavior is undefined if that
239
+ evaluation exits via an exception. May invoke scheduled evaluations in
240
+ `dom`.
241
+
242
+ [*Note 4*: If `rcu_retire` exits via an exception, no evaluation is
243
+ scheduled. — *end note*]
244
+
245
+ *Throws:* `bad_alloc` or any exception thrown by the initialization of
246
+ `d1`.
247
+
248
+ [*Note 5*: If scheduled evaluations acquire resources held across any
249
+ invocation of `rcu_retire` on `dom`, deadlock can occur. — *end note*]
250
+