163 lines
4.4 KiB
Markdown
163 lines
4.4 KiB
Markdown
[saferecl.hp.holder.mem]
|
||
|
||
# 32 Concurrency support library [[thread]](./#thread)
|
||
|
||
## 32.11 Safe reclamation [[saferecl]](saferecl#hp.holder.mem)
|
||
|
||
### 32.11.3 Hazard pointers [[saferecl.hp]](saferecl.hp#holder.mem)
|
||
|
||
#### 32.11.3.4 Class hazard_pointer [[saferecl.hp.holder]](saferecl.hp.holder#mem)
|
||
|
||
#### 32.11.3.4.3 Member functions [saferecl.hp.holder.mem]
|
||
|
||
[ð](#lib:empty,hazard_pointer)
|
||
|
||
`bool empty() const noexcept;
|
||
`
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13573)
|
||
|
||
*Returns*: true if and only if *this is empty[.](#1.sentence-1)
|
||
|
||
[ð](#lib:protect,hazard_pointer)
|
||
|
||
`template<class T> T* protect(const atomic<T*>& src) noexcept;
|
||
`
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13584)
|
||
|
||
*Effects*: Equivalent to:T* ptr = src.load(memory_order::relaxed);while (!try_protect(ptr, src)) {}return ptr;
|
||
|
||
[ð](#lib:try_protect,hazard_pointer)
|
||
|
||
`template<class T> bool try_protect(T*& ptr, const atomic<T*>& src) noexcept;
|
||
`
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13600)
|
||
|
||
*Mandates*: T is a hazard-protectable type[.](#3.sentence-1)
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13604)
|
||
|
||
*Preconditions*: *this is not empty[.](#4.sentence-1)
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13608)
|
||
|
||
*Effects*: Performs the following steps in order:
|
||
|
||
- [(5.1)](#5.1)
|
||
|
||
Initializes a variable old of type T* with the value of ptr[.](#5.1.sentence-1)
|
||
|
||
- [(5.2)](#5.2)
|
||
|
||
Evaluates reset_protection(old)[.](#5.2.sentence-1)
|
||
|
||
- [(5.3)](#5.3)
|
||
|
||
Assigns the value of src.load(memory_order::acquire) to ptr[.](#5.3.sentence-1)
|
||
|
||
- [(5.4)](#5.4)
|
||
|
||
If old == ptr is false,
|
||
evaluates reset_protection()[.](#5.4.sentence-1)
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13619)
|
||
|
||
*Returns*: old == ptr[.](#6.sentence-1)
|
||
|
||
[ð](#lib:reset_protection,hazard_pointer)
|
||
|
||
`template<class T> void reset_protection(const T* ptr) noexcept;
|
||
`
|
||
|
||
[7](#7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13630)
|
||
|
||
*Mandates*: T is a hazard-protectable type[.](#7.sentence-1)
|
||
|
||
[8](#8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13634)
|
||
|
||
*Preconditions*: *this is not empty[.](#8.sentence-1)
|
||
|
||
[9](#9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13638)
|
||
|
||
*Effects*: If ptr is a null pointer value, invokes reset_protection()[.](#9.sentence-1)
|
||
|
||
Otherwise,
|
||
associates the hazard pointer owned by *this with *ptr,
|
||
thereby ending the current protection epoch[.](#9.sentence-2)
|
||
|
||
[10](#10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13645)
|
||
|
||
*Complexity*: Constant[.](#10.sentence-1)
|
||
|
||
[ð](#lib:reset_protection,hazard_pointer_)
|
||
|
||
`void reset_protection(nullptr_t = nullptr) noexcept;
|
||
`
|
||
|
||
[11](#11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13656)
|
||
|
||
*Preconditions*: *this is not empty[.](#11.sentence-1)
|
||
|
||
[12](#12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13660)
|
||
|
||
*Postconditions*: The hazard pointer owned by *this is unassociated[.](#12.sentence-1)
|
||
|
||
[13](#13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13664)
|
||
|
||
*Complexity*: Constant[.](#13.sentence-1)
|
||
|
||
[ð](#lib:swap,hazard_pointer)
|
||
|
||
`void swap(hazard_pointer& other) noexcept;
|
||
`
|
||
|
||
[14](#14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13675)
|
||
|
||
*Effects*: Swaps the hazard pointer ownership of this object with that of other[.](#14.sentence-1)
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
The owned hazard pointers, if any, remain unchanged during the swap and
|
||
continue to be associated with the respective objects
|
||
that they were protecting before the swap, if any[.](#14.sentence-2)
|
||
|
||
No protection epochs are ended or initiated[.](#14.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[15](#15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13685)
|
||
|
||
*Complexity*: Constant[.](#15.sentence-1)
|