Skip to content

Commit eda1e0c

Browse files
committed
rcu: rcu_domain, rcu_obj_base (#1183)
1 parent 8fba13b commit eda1e0c

File tree

11 files changed

+500
-3
lines changed

11 files changed

+500
-3
lines changed

reference/rcu.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ RCU同期メカニズムは、複数スレッド間で共有されるデータ
99

1010
| 名前 | 説明 | 対応バージョン |
1111
|-----------------|----------------|----------------|
12-
| [`rcu_obj_base`](rcu/rcu_obj_base.md.nolink) | RCU対象オブジェクトの基底クラス(class template) | C++26 |
13-
| [`rcu_domain`](rcu/rcu_domain.md.nolink) | RCUドメイン(class) | C++26 |
14-
| [`rcu_default_domain`](rcu/rcu_default_domain.md.nolink) | デフォルトのRCUドメイン取得(function) | C++26 |
12+
| [`rcu_obj_base`](rcu/rcu_obj_base.md) | RCU対象オブジェクトの基底クラス(class template) | C++26 |
13+
| [`rcu_domain`](rcu/rcu_domain.md) | RCUドメイン(class) | C++26 |
14+
| [`rcu_default_domain`](rcu/rcu_default_domain.md) | デフォルトのRCUドメイン取得(function) | C++26 |
1515
| [`rcu_synchronize`](rcu/rcu_synchronize.md.nolink) | RCUドメインのアンロック完了を待機(function) | C++26 |
1616
| [`rcu_barrier`](rcu/rcu_barrier.md.nolink) | メモリ解放操作完了を待機(function) | C++26 |
1717
| [`rcu_retire`](rcu/rcu_barrier.md.nolink) | メモリ解放操作をスケジュル(function template) | C++26 |
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# rcu_default_domain
2+
* rcu[meta header]
3+
* function[meta id-type]
4+
* std[meta namespace]
5+
* cpp26[meta cpp]
6+
7+
```cpp
8+
namespace std {
9+
rcu_domain& rcu_default_domain() noexcept;
10+
}
11+
```
12+
* rcu_domain[link rcu_domain.md]
13+
14+
## 概要
15+
デフォルトのRCUドメインを取得する。
16+
17+
18+
## 戻り値
19+
静的記憶域期間をもつ[`rcu_domain`](rcu_domain.md)オブジェクトへの参照を返す。
20+
この関数は常に同一オブジェクトへの参照を返す。
21+
22+
23+
## 例外
24+
投げない
25+
26+
27+
## 備考
28+
C++26時点では、この関数が[`rcu_domain`](rcu_domain.md)オブジェクトを作成する唯一の手段となっている。
29+
30+
31+
## バージョン
32+
### 言語
33+
- C++26
34+
35+
### 処理系
36+
- [Clang](/implementation.md#clang): ??
37+
- [GCC](/implementation.md#gcc): ??
38+
- [ICC](/implementation.md#icc): ??
39+
- [Visual C++](/implementation.md#visual_cpp): ??
40+
41+
42+
## 関連項目
43+
- [`rcu_domain`](rcu_domain.md)
44+
45+
46+
## 参照
47+
- [P2545R4 Read-Copy Update(RCU)](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2545r4.pdf)

reference/rcu/rcu_domain.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# rcu_domain
2+
* rcu[meta header]
3+
* class[meta id-type]
4+
* std[meta namespace]
5+
* cpp26[meta cpp]
6+
7+
```cpp
8+
namespace std {
9+
class rcu_domain;
10+
}
11+
```
12+
13+
## 概要
14+
RCU同期メカニズムで保護する共有データに対応付ける、RCUドメインを表現する。
15+
16+
`rcu_domain`クラスは Cpp17Lockable 要件を満たし、共有データの読み取りをおこなうRCU保護区間を表現する。
17+
RCU保護区間は`lock`呼び出しから`unlock()`呼び出しのまでの区間であり、RCUドメインに対して同一スレッド上でのRCU保護区間は入れ子になってもよい。
18+
19+
20+
## メンバ関数
21+
22+
| 名前 | 説明 | 対応バージョン |
23+
|-----------------|----------------|-------|
24+
| `(constructor)` | コンストラクタ | C++26 |
25+
| `operator=` | 代入演算子 | C++26 |
26+
| [`lock`](rcu_domain/lock.md) | 共有データの読み取り開始を宣言 | C++26 |
27+
| [`try_lock`](rcu_domain/try_lock.md) | 共有データの読み取り開始を宣言 | C++26 |
28+
| [`unlock`](rcu_domain/unlock.md) | 共有データの読み取り終了を宣言 | C++26 |
29+
30+
31+
## 例
32+
```cpp example
33+
#include <rcu>
34+
#include <mutex>
35+
36+
int main()
37+
{
38+
std::rcu_domain& dom = std::rcu_default_domain();
39+
40+
{
41+
std::scoped_lock rlock(dom);
42+
// dom.lock()が呼ばれる
43+
44+
} // dom.unlock()が呼ばれる
45+
}
46+
```
47+
* std::rcu_domain[color ff0000]
48+
* std::rcu_default_domain[link rcu_default_domain.md]
49+
* std::scoped_lock[link /reference/mutex/scoped_lock.md]
50+
51+
52+
### 出力
53+
```
54+
```
55+
56+
57+
## バージョン
58+
### 言語
59+
- C++26
60+
61+
### 処理系
62+
- [Clang](/implementation.md#clang): ??
63+
- [GCC](/implementation.md#gcc): ??
64+
- [ICC](/implementation.md#icc): ??
65+
- [Visual C++](/implementation.md#visual_cpp): ??
66+
67+
68+
## 関連項目
69+
- [`rcu_default_domain`](rcu_default_domain.md)
70+
- [`rcu_retire`](rcu_retire.md.nolink)
71+
- [`rcu_obj_base::retire`](rcu_obj_base/retire.md)
72+
73+
74+
## 参照
75+
- [P2545R4 Read-Copy Update(RCU)](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2545r4.pdf)

reference/rcu/rcu_domain/lock.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# lock
2+
* rcu[meta header]
3+
* function[meta id-type]
4+
* std[meta namespace]
5+
* rcu_domain[meta class]
6+
* cpp26[meta cpp]
7+
8+
```cpp
9+
void lock() noexcept;
10+
```
11+
12+
## 概要
13+
RCU機構により保護される共有データの読み取り開始を宣言する。
14+
15+
16+
## 効果
17+
RCU保護区間を開く。
18+
19+
20+
## 戻り値
21+
なし
22+
23+
24+
## 例外
25+
投げない
26+
27+
28+
## バージョン
29+
### 言語
30+
- C++26
31+
32+
### 処理系
33+
- [Clang](/implementation.md#clang): ??
34+
- [GCC](/implementation.md#gcc): ??
35+
- [ICC](/implementation.md#icc): ??
36+
- [Visual C++](/implementation.md#visual_cpp): ??
37+
38+
39+
## 関連項目
40+
- [`unlock`](unlock.md)
41+
42+
43+
## 参照
44+
- [P2545R4 Read-Copy Update(RCU)](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2545r4.pdf)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# try_lock
2+
* rcu[meta header]
3+
* function[meta id-type]
4+
* std[meta namespace]
5+
* rcu_domain[meta class]
6+
* cpp26[meta cpp]
7+
8+
```cpp
9+
bool try_lock() noexcept;
10+
```
11+
12+
## 概要
13+
RCU機構により保護される共有データの読み取り開始を宣言する。
14+
15+
16+
## 効果
17+
[`lock()`](lock.md)と等価。
18+
19+
20+
## 戻り値
21+
`true`
22+
23+
24+
## 例外
25+
投げない
26+
27+
28+
## バージョン
29+
### 言語
30+
- C++26
31+
32+
### 処理系
33+
- [Clang](/implementation.md#clang): ??
34+
- [GCC](/implementation.md#gcc): ??
35+
- [ICC](/implementation.md#icc): ??
36+
- [Visual C++](/implementation.md#visual_cpp): ??
37+
38+
39+
## 関連項目
40+
- [`unlock`](unlock.md)
41+
42+
43+
## 参照
44+
- [P2545R4 Read-Copy Update(RCU)](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2545r4.pdf)

reference/rcu/rcu_domain/unlock.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# unlock
2+
* rcu[meta header]
3+
* function[meta id-type]
4+
* std[meta namespace]
5+
* rcu_domain[meta class]
6+
* cpp26[meta cpp]
7+
8+
```cpp
9+
void unlock() noexcept;
10+
```
11+
12+
## 概要
13+
RCU機構により保護される共有データの読み取り終了を宣言する。
14+
15+
16+
## 事前条件
17+
まだ閉じられていないRCU保護区間を開いた[`lock`](lock.md)呼び出しが、`unlock`呼び出しよりも前に順序付けられること。
18+
19+
20+
## 効果
21+
直近に開かれたRCU保護区間を閉じる。
22+
`*this`上でスケジュールされた再利用操作を呼び出す可能性がある。
23+
24+
25+
## 戻り値
26+
なし
27+
28+
29+
## 例外
30+
投げない
31+
32+
33+
## バージョン
34+
### 言語
35+
- C++26
36+
37+
### 処理系
38+
- [Clang](/implementation.md#clang): ??
39+
- [GCC](/implementation.md#gcc): ??
40+
- [ICC](/implementation.md#icc): ??
41+
- [Visual C++](/implementation.md#visual_cpp): ??
42+
43+
44+
## 関連項目
45+
- [`lock`](lock.md)
46+
- [`rcu_retire`](../rcu_retire.md.nolink)
47+
- [`rcu_obj_base::retire`](../rcu_rcu_obj_base/retire.md.nolink)
48+
49+
50+
## 参照
51+
- [P2545R4 Read-Copy Update(RCU)](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2545r4.pdf)

reference/rcu/rcu_obj_base.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# rcu_obj_base
2+
* rcu[meta header]
3+
* class template[meta id-type]
4+
* std[meta namespace]
5+
* cpp26[meta cpp]
6+
7+
```cpp
8+
namespace std {
9+
template<class T, class D = default_delete<T>>
10+
class rcu_obj_base;
11+
}
12+
```
13+
* default_delete[link /reference/memory/default_delete.md]
14+
15+
## 概要
16+
RCU機構の保護対象とする型の基底クラス。
17+
18+
使用するときは、`T`で`rcu_obj_base`を公開継承した上で派生クラス`T`を`rcu_obj_base`のテンプレート引数にする(CRTP)。
19+
20+
21+
## 適格要件
22+
- `T`は不完全型でもよいが、特殊化された`rcu_obj_base`のメンバが参照されるまでに完全型とすること。
23+
- `D`は関数オブジェクト型であり、`D`型の値`d`と`T*`型の値`ptr`に対して式`d(ptr)`が有効であること。
24+
- `D`型は要件 Cpp17DefaultConstructible およ Cpp17MoveAssignable を満たすこと。
25+
26+
27+
## メンバ関数
28+
29+
| 名前 | 説明 | 対応バージョン |
30+
|-----------------|----------------|-------|
31+
| [`(constructor)`](rcu_obj_base/op_constructor.md) | コンストラクタ | C++26 |
32+
| `(destructor)` | デストラクタ | C++26 |
33+
| [`operator=`](rcu_obj_base/op_assign.md) | 代入演算子 | C++26 |
34+
| [`retire`](rcu_obj_base/retire.md) | オブジェクト再利用をスケジュールする | C++26 |
35+
36+
37+
## 例
38+
```cpp example
39+
#include <atomic>
40+
#include <mutex>
41+
#include <thread>
42+
#include <rcu>
43+
44+
struct Data : std::rcu_obj_base<Data> {
45+
int m1, m2;
46+
};
47+
48+
// 共有データを指すポインタ
49+
std::atomic<Data*> data;
50+
51+
void reader()
52+
{
53+
std::scoped_lock slk{std::rcu_default_domain()};
54+
// 共有データを読み取り(Read)
55+
Data *p = data;
56+
57+
std::println("{} {}", p->m1, p->m2);
58+
}
59+
60+
void updater()
61+
{
62+
Data *newdata = new Data{1, 2};
63+
// 新しいデータで共有データを更新(Update)
64+
Data *old_data = data.exchange(newdata);
65+
66+
// 古いデータを読み取り中のスレッドがなくなったタイミングで
67+
// データ領域の再利用(メモリ解放)を行うようスケジューリングする
68+
old_data->retire();
69+
}
70+
71+
int main()
72+
{
73+
// 共有データ初期化
74+
Data *newdata = new Data{0, 0};
75+
data.store(newdata);
76+
77+
// 共有データへ並行アクセス
78+
std::jthread th{[] {
79+
for (int i = 0; i < 3; i++) {
80+
reader();
81+
}
82+
}};
83+
updater();
84+
}
85+
```
86+
* std::rcu_obj_base[color ff0000]
87+
* std::rcu_default_domain[link rcu_default_domain.md]
88+
* std::scoped_lock[link /reference/mutex/scoped_lock.md]
89+
90+
91+
### 出力例
92+
```
93+
0 0
94+
1 2
95+
1 2
96+
```
97+
98+
99+
## バージョン
100+
### 言語
101+
- C++26
102+
103+
### 処理系
104+
- [Clang](/implementation.md#clang): ??
105+
- [GCC](/implementation.md#gcc): ??
106+
- [ICC](/implementation.md#icc): ??
107+
- [Visual C++](/implementation.md#visual_cpp): ??
108+
109+
110+
## 関連項目
111+
- [`rcu_domain`](rcu_domain.md)
112+
113+
114+
## 参照
115+
- [P2545R4 Read-Copy Update(RCU)](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2545r4.pdf)

0 commit comments

Comments
 (0)