diff --git a/reference/rcu.md b/reference/rcu.md index df3358695..a318cc408 100644 --- a/reference/rcu.md +++ b/reference/rcu.md @@ -9,9 +9,9 @@ RCU同期メカニズムは、複数スレッド間で共有されるデータ | 名前 | 説明 | 対応バージョン | |-----------------|----------------|----------------| -| [`rcu_obj_base`](rcu/rcu_obj_base.md.nolink) | RCU対象オブジェクトの基底クラス(class template) | C++26 | -| [`rcu_domain`](rcu/rcu_domain.md.nolink) | RCUドメイン(class) | C++26 | -| [`rcu_default_domain`](rcu/rcu_default_domain.md.nolink) | デフォルトのRCUドメイン取得(function) | C++26 | +| [`rcu_obj_base`](rcu/rcu_obj_base.md) | RCU対象オブジェクトの基底クラス(class template) | C++26 | +| [`rcu_domain`](rcu/rcu_domain.md) | RCUドメイン(class) | C++26 | +| [`rcu_default_domain`](rcu/rcu_default_domain.md) | デフォルトのRCUドメイン取得(function) | C++26 | | [`rcu_synchronize`](rcu/rcu_synchronize.md.nolink) | RCUドメインのアンロック完了を待機(function) | C++26 | | [`rcu_barrier`](rcu/rcu_barrier.md.nolink) | メモリ解放操作完了を待機(function) | C++26 | | [`rcu_retire`](rcu/rcu_barrier.md.nolink) | メモリ解放操作をスケジュル(function template) | C++26 | diff --git a/reference/rcu/rcu_default_domain.md b/reference/rcu/rcu_default_domain.md new file mode 100644 index 000000000..8fc46425f --- /dev/null +++ b/reference/rcu/rcu_default_domain.md @@ -0,0 +1,47 @@ +# rcu_default_domain +* rcu[meta header] +* function[meta id-type] +* std[meta namespace] +* cpp26[meta cpp] + +```cpp +namespace std { + rcu_domain& rcu_default_domain() noexcept; +} +``` +* rcu_domain[link rcu_domain.md] + +## 概要 +デフォルトのRCUドメインを取得する。 + + +## 戻り値 +静的記憶域期間をもつ[`rcu_domain`](rcu_domain.md)オブジェクトへの参照を返す。 +この関数は常に同一オブジェクトへの参照を返す。 + + +## 例外 +投げない + + +## 備考 +C++26時点では、この関数が[`rcu_domain`](rcu_domain.md)オブジェクトを作成する唯一の手段となっている。 + + +## バージョン +### 言語 +- C++26 + +### 処理系 +- [Clang](/implementation.md#clang): ?? +- [GCC](/implementation.md#gcc): ?? +- [ICC](/implementation.md#icc): ?? +- [Visual C++](/implementation.md#visual_cpp): ?? + + +## 関連項目 +- [`rcu_domain`](rcu_domain.md) + + +## 参照 +- [P2545R4 Read-Copy Update(RCU)](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2545r4.pdf) diff --git a/reference/rcu/rcu_domain.md b/reference/rcu/rcu_domain.md new file mode 100644 index 000000000..b3a6b5369 --- /dev/null +++ b/reference/rcu/rcu_domain.md @@ -0,0 +1,75 @@ +# rcu_domain +* rcu[meta header] +* class[meta id-type] +* std[meta namespace] +* cpp26[meta cpp] + +```cpp +namespace std { + class rcu_domain; +} +``` + +## 概要 +RCU同期メカニズムで保護する共有データに対応付ける、RCUドメインを表現する。 + +`rcu_domain`クラスは Cpp17Lockable 要件を満たし、共有データの読み取りをおこなうRCU保護区間を表現する。 +RCU保護区間は`lock`呼び出しから`unlock()`呼び出しのまでの区間であり、RCUドメインに対して同一スレッド上でのRCU保護区間は入れ子になってもよい。 + + +## メンバ関数 + +| 名前 | 説明 | 対応バージョン | +|-----------------|----------------|-------| +| `(constructor)` | コンストラクタ | C++26 | +| `operator=` | 代入演算子 | C++26 | +| [`lock`](rcu_domain/lock.md) | 共有データの読み取り開始を宣言 | C++26 | +| [`try_lock`](rcu_domain/try_lock.md) | 共有データの読み取り開始を宣言 | C++26 | +| [`unlock`](rcu_domain/unlock.md) | 共有データの読み取り終了を宣言 | C++26 | + + +## 例 +```cpp example +#include +#include + +int main() +{ + std::rcu_domain& dom = std::rcu_default_domain(); + + { + std::scoped_lock rlock(dom); + // dom.lock()が呼ばれる + + } // dom.unlock()が呼ばれる +} +``` +* std::rcu_domain[color ff0000] +* std::rcu_default_domain[link rcu_default_domain.md] +* std::scoped_lock[link /reference/mutex/scoped_lock.md] + + +### 出力 +``` +``` + + +## バージョン +### 言語 +- C++26 + +### 処理系 +- [Clang](/implementation.md#clang): ?? +- [GCC](/implementation.md#gcc): ?? +- [ICC](/implementation.md#icc): ?? +- [Visual C++](/implementation.md#visual_cpp): ?? + + +## 関連項目 +- [`rcu_default_domain`](rcu_default_domain.md) +- [`rcu_retire`](rcu_retire.md.nolink) +- [`rcu_obj_base::retire`](rcu_obj_base/retire.md) + + +## 参照 +- [P2545R4 Read-Copy Update(RCU)](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2545r4.pdf) diff --git a/reference/rcu/rcu_domain/lock.md b/reference/rcu/rcu_domain/lock.md new file mode 100644 index 000000000..cf7096b33 --- /dev/null +++ b/reference/rcu/rcu_domain/lock.md @@ -0,0 +1,44 @@ +# lock +* rcu[meta header] +* function[meta id-type] +* std[meta namespace] +* rcu_domain[meta class] +* cpp26[meta cpp] + +```cpp +void lock() noexcept; +``` + +## 概要 +RCU機構により保護される共有データの読み取り開始を宣言する。 + + +## 効果 +RCU保護区間を開く。 + + +## 戻り値 +なし + + +## 例外 +投げない + + +## バージョン +### 言語 +- C++26 + +### 処理系 +- [Clang](/implementation.md#clang): ?? +- [GCC](/implementation.md#gcc): ?? +- [ICC](/implementation.md#icc): ?? +- [Visual C++](/implementation.md#visual_cpp): ?? + + +## 関連項目 +- [`unlock`](unlock.md) + + +## 参照 +- [P2545R4 Read-Copy Update(RCU)](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2545r4.pdf) diff --git a/reference/rcu/rcu_domain/try_lock.md b/reference/rcu/rcu_domain/try_lock.md new file mode 100644 index 000000000..686a7d9d0 --- /dev/null +++ b/reference/rcu/rcu_domain/try_lock.md @@ -0,0 +1,44 @@ +# try_lock +* rcu[meta header] +* function[meta id-type] +* std[meta namespace] +* rcu_domain[meta class] +* cpp26[meta cpp] + +```cpp +bool try_lock() noexcept; +``` + +## 概要 +RCU機構により保護される共有データの読み取り開始を宣言する。 + + +## 効果 +[`lock()`](lock.md)と等価。 + + +## 戻り値 +`true` + + +## 例外 +投げない + + +## バージョン +### 言語 +- C++26 + +### 処理系 +- [Clang](/implementation.md#clang): ?? +- [GCC](/implementation.md#gcc): ?? +- [ICC](/implementation.md#icc): ?? +- [Visual C++](/implementation.md#visual_cpp): ?? + + +## 関連項目 +- [`unlock`](unlock.md) + + +## 参照 +- [P2545R4 Read-Copy Update(RCU)](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2545r4.pdf) diff --git a/reference/rcu/rcu_domain/unlock.md b/reference/rcu/rcu_domain/unlock.md new file mode 100644 index 000000000..bd315492b --- /dev/null +++ b/reference/rcu/rcu_domain/unlock.md @@ -0,0 +1,51 @@ +# unlock +* rcu[meta header] +* function[meta id-type] +* std[meta namespace] +* rcu_domain[meta class] +* cpp26[meta cpp] + +```cpp +void unlock() noexcept; +``` + +## 概要 +RCU機構により保護される共有データの読み取り終了を宣言する。 + + +## 事前条件 +まだ閉じられていないRCU保護区間を開いた[`lock`](lock.md)呼び出しが、`unlock`呼び出しよりも前に順序付けられること。 + + +## 効果 +直近に開かれたRCU保護区間を閉じる。 +`*this`上でスケジュールされた再利用操作を呼び出す可能性がある。 + + +## 戻り値 +なし + + +## 例外 +投げない + + +## バージョン +### 言語 +- C++26 + +### 処理系 +- [Clang](/implementation.md#clang): ?? +- [GCC](/implementation.md#gcc): ?? +- [ICC](/implementation.md#icc): ?? +- [Visual C++](/implementation.md#visual_cpp): ?? + + +## 関連項目 +- [`lock`](lock.md) +- [`rcu_retire`](../rcu_retire.md.nolink) +- [`rcu_obj_base::retire`](../rcu_rcu_obj_base/retire.md.nolink) + + +## 参照 +- [P2545R4 Read-Copy Update(RCU)](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2545r4.pdf) diff --git a/reference/rcu/rcu_obj_base.md b/reference/rcu/rcu_obj_base.md new file mode 100644 index 000000000..0e2bc9bce --- /dev/null +++ b/reference/rcu/rcu_obj_base.md @@ -0,0 +1,115 @@ +# rcu_obj_base +* rcu[meta header] +* class template[meta id-type] +* std[meta namespace] +* cpp26[meta cpp] + +```cpp +namespace std { + template> + class rcu_obj_base; +} +``` +* default_delete[link /reference/memory/default_delete.md] + +## 概要 +RCU機構の保護対象とする型の基底クラス。 + +使用するときは、`T`で`rcu_obj_base`を公開継承した上で派生クラス`T`を`rcu_obj_base`のテンプレート引数にする(CRTP)。 + + +## 適格要件 +- `T`は不完全型でもよいが、特殊化された`rcu_obj_base`のメンバが参照されるまでに完全型とすること。 +- `D`は関数オブジェクト型であり、`D`型の値`d`と`T*`型の値`ptr`に対して式`d(ptr)`が有効であること。 +- `D`型は要件 Cpp17DefaultConstructible およ Cpp17MoveAssignable を満たすこと。 + + +## メンバ関数 + +| 名前 | 説明 | 対応バージョン | +|-----------------|----------------|-------| +| [`(constructor)`](rcu_obj_base/op_constructor.md) | コンストラクタ | C++26 | +| `(destructor)` | デストラクタ | C++26 | +| [`operator=`](rcu_obj_base/op_assign.md) | 代入演算子 | C++26 | +| [`retire`](rcu_obj_base/retire.md) | オブジェクト再利用をスケジュールする | C++26 | + + +## 例 +```cpp example +#include +#include +#include +#include + +struct Data : std::rcu_obj_base { + int m1, m2; +}; + +// 共有データを指すポインタ +std::atomic data; + +void reader() +{ + std::scoped_lock slk{std::rcu_default_domain()}; + // 共有データを読み取り(Read) + Data *p = data; + + std::println("{} {}", p->m1, p->m2); +} + +void updater() +{ + Data *newdata = new Data{1, 2}; + // 新しいデータで共有データを更新(Update) + Data *old_data = data.exchange(newdata); + + // 古いデータを読み取り中のスレッドがなくなったタイミングで + // データ領域の再利用(メモリ解放)を行うようスケジューリングする + old_data->retire(); +} + +int main() +{ + // 共有データ初期化 + Data *newdata = new Data{0, 0}; + data.store(newdata); + + // 共有データへ並行アクセス + std::jthread th{[] { + for (int i = 0; i < 3; i++) { + reader(); + } + }}; + updater(); +} +``` +* std::rcu_obj_base[color ff0000] +* std::rcu_default_domain[link rcu_default_domain.md] +* std::scoped_lock[link /reference/mutex/scoped_lock.md] + + +### 出力例 +``` +0 0 +1 2 +1 2 +``` + + +## バージョン +### 言語 +- C++26 + +### 処理系 +- [Clang](/implementation.md#clang): ?? +- [GCC](/implementation.md#gcc): ?? +- [ICC](/implementation.md#icc): ?? +- [Visual C++](/implementation.md#visual_cpp): ?? + + +## 関連項目 +- [`rcu_domain`](rcu_domain.md) + + +## 参照 +- [P2545R4 Read-Copy Update(RCU)](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2545r4.pdf) diff --git a/reference/rcu/rcu_obj_base/op_assign.md b/reference/rcu/rcu_obj_base/op_assign.md new file mode 100644 index 000000000..e97ced383 --- /dev/null +++ b/reference/rcu/rcu_obj_base/op_assign.md @@ -0,0 +1,31 @@ +# operator= +* rcu[meta header] +* function[meta id-type] +* std[meta namespace] +* rcu_obj_base[meta class] +* cpp26[meta cpp] + +```cpp +protected: + rcu_obj_base& operator=(const rcu_obj_base&) = default; // (1) + rcu_obj_base& operator=(rcu_obj_base&&) = default; // (2) +``` + +## 概要 +- (1): コピー代入演算子 +- (2): ムーブ代入演算子 + + +## バージョン +### 言語 +- C++26 + +### 処理系 +- [Clang](/implementation.md#clang): ?? +- [GCC](/implementation.md#gcc): ?? +- [ICC](/implementation.md#icc): ?? +- [Visual C++](/implementation.md#visual_cpp): ?? + + +## 参照 +- [P2545R4 Read-Copy Update(RCU)](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2545r4.pdf) diff --git a/reference/rcu/rcu_obj_base/op_constructor.md b/reference/rcu/rcu_obj_base/op_constructor.md new file mode 100644 index 000000000..d190c1366 --- /dev/null +++ b/reference/rcu/rcu_obj_base/op_constructor.md @@ -0,0 +1,33 @@ +# コンストラクタ +* rcu[meta header] +* function[meta id-type] +* std[meta namespace] +* rcu_obj_base[meta class] +* cpp26[meta cpp] + +```cpp +protected: + rcu_obj_base() = default; // (1) + rcu_obj_base(const rcu_obj_base&) = default; // (2) + rcu_obj_base(rcu_obj_base&&) = default; // (3) +``` + +## 概要 +- (1): デフォルトコンストラクタ +- (2): コピーコンストラクタ +- (3): ムーブコンストラクタ + + +## バージョン +### 言語 +- C++26 + +### 処理系 +- [Clang](/implementation.md#clang): ?? +- [GCC](/implementation.md#gcc): ?? +- [ICC](/implementation.md#icc): ?? +- [Visual C++](/implementation.md#visual_cpp): ?? + + +## 参照 +- [P2545R4 Read-Copy Update(RCU)](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2545r4.pdf) diff --git a/reference/rcu/rcu_obj_base/retire.md b/reference/rcu/rcu_obj_base/retire.md new file mode 100644 index 000000000..deadc7b28 --- /dev/null +++ b/reference/rcu/rcu_obj_base/retire.md @@ -0,0 +1,56 @@ +# retire +* rcu[meta header] +* function[meta id-type] +* std[meta namespace] +* rcu_obj_base[meta class] +* cpp26[meta cpp] + +```cpp +void retire(D d = D(), + rcu_domain& dom = rcu_default_domain()) noexcept; +``` +* rcu_domain[link ../rcu_domain.md] +* rcu_default_domain[link ../rcu_default_domain.md] + +## 概要 +RCU機構により保護されるオブジェクト再利用をスケジュールする。 + + +## 適格要件 +クラステンプレートパラメータ`T`がRCU保護可能(rcu-protectable)な型であること。 + + +## 事前条件 +- `*this`が型`T`のオブジェクト`x`の基底クラスサブオブジェクトであること。 +- `x`に対して`rcu_obj_base::retire`が呼び出されていないこと。 +- `D`型の説明専用メンバ変数`deleter`への代入が例外で終了しないこと。 + + +## 効果 +- `deleter = std::move(d)`を評価し、 +- RCUドメイン`dom`に対して式`deleter(addressof(x))`の評価をスケジュールする。 + - 評価が例外で終了した場合は未定義の動作を引き起こす。 +- `dom`に対してスケジュールされた評価を呼び出す可能性がある。 + + +## 戻り値 +なし + + +## バージョン +### 言語 +- C++26 + +### 処理系 +- [Clang](/implementation.md#clang): ?? +- [GCC](/implementation.md#gcc): ?? +- [ICC](/implementation.md#icc): ?? +- [Visual C++](/implementation.md#visual_cpp): ?? + + +## 関連項目 +- [`rcu_domain::unlock`](../rcu_domain/unlock.md) + + +## 参照 +- [P2545R4 Read-Copy Update(RCU)](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2545r4.pdf) diff --git a/working_style.md b/working_style.md index 0c28b90af..c102272fd 100644 --- a/working_style.md +++ b/working_style.md @@ -123,6 +123,7 @@ C++11以降対応については対応バージョンを明記します。バー | pure virtual function | 純粋仮想関数 | | random access iterator | ランダムアクセスイテレータ | | range | 一般用途の場合:範囲
Rangeアルゴリズム・Rangeアダプタ・Rangeオブジェクトの場合:Range
range-based for:範囲for文
2つのイテレータによる範囲:イテレータ範囲 | +| region of RCU protection | RCU保護区間 | | remarks | 備考 | | requires | 要件 | | returns | 戻り値 |