[saferecl.hp.general]

# 32 Concurrency support library [[thread]](./#thread)

## 32.11 Safe reclamation [[saferecl]](saferecl#hp.general)

### 32.11.3 Hazard pointers [[saferecl.hp]](saferecl.hp#general)

#### 32.11.3.1 General [saferecl.hp.general]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13272)

A hazard pointer is a single-writer multi-reader pointer
that can be owned by at most one thread at any time[.](#1.sentence-1)

Only the owner of the hazard pointer can set its value,
while any number of threads may read its value[.](#1.sentence-2)

The owner thread sets the value of a hazard pointer to point to an object
in order to indicate to concurrent threadsâwhich
may delete such an objectâthat
the object is not yet safe to delete[.](#1.sentence-3)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13283)

A class type T is [*hazard-protectable*](#def:hazard-protectable "32.11.3.1 General [saferecl.hp.general]") if it has exactly one base class of type hazard_pointer_obj_base<T, D> for some D,
that base is public and non-virtual, and
it has no base classes of type hazard_pointer_obj_base<T2, D2> for any other combination T2, D2[.](#2.sentence-1)

An object is [*hazard-protectable*](#def:hazard-protectable "32.11.3.1 General [saferecl.hp.general]") if it is of hazard-protectable type[.](#2.sentence-2)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13292)

The time span between creation and destruction of a hazard pointer h is partitioned into a series of [*protection epochs*](#def:epoch,protection "32.11.3.1 General [saferecl.hp.general]");
in each protection epoch,h either is [*associated with*](#def:hazard_pointer,associated "32.11.3.1 General [saferecl.hp.general]") a hazard-protectable object, or is [*unassociated*](#def:hazard_pointer,unassociated "32.11.3.1 General [saferecl.hp.general]")[.](#3.sentence-1)

Upon creation, a hazard pointer is unassociated[.](#3.sentence-2)

Changing the association (possibly to the same object)
initiates a new protection epoch and ends the preceding one[.](#3.sentence-3)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13302)

An object x of hazard-protectable type T is[*retired*](#def:retired "32.11.3.1 General [saferecl.hp.general]") with a deleter of type D when the member function hazard_pointer_obj_base<T, D>​::​retire is invoked on x[.](#4.sentence-1)

Any given object x shall be retired at most once[.](#4.sentence-2)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13309)

A retired object x is [*reclaimed*](#def:reclaimed "32.11.3.1 General [saferecl.hp.general]") by invoking its deleter with a pointer to x;
the behavior is undefined if that invocation exits via an exception[.](#5.sentence-1)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13314)

A hazard-protectable object x is [*possibly-reclaimable*](#def:possibly-reclaimable "32.11.3.1 General [saferecl.hp.general]") with respect to an evaluation A if

- [(6.1)](#6.1)

x is not reclaimed; and

- [(6.2)](#6.2)

x is retired in an evaluation R andA does not happen before R; and

- [(6.3)](#6.3)

for all hazard pointers h and for every protection epoch E of h during which h is associated with x:
  * [(6.3.1)](#6.3.1)

if the beginning of E happens before R,
the end of E strongly happens before A; and

  * [(6.3.2)](#6.3.2)

if E began by an evaluation of try_protect with argument src,
label its atomic load operation L[.](#6.sentence-1)
      If there exists an atomic modification B on src such that L observes a modification that is modification-ordered before B, andB happens before x is retired,
the end of E strongly happens before A[.](#6.3.2.sentence-2)
      [*Note [1](#note-1)*:
      In typical use, a store to src sequenced before retiring x will be such an atomic operation B[.](#6.3.2.sentence-3)
 â *end note*]

  [*Note [2](#note-2)*:
  The latter two conditions convey the informal notion
that a protection epoch that began before retiring x,
as implied either by the happens-before relation or
the coherence order of some source,
delays the reclamation of x[.](#6.3.sentence-2)
 â *end note*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L13351)

The number of possibly-reclaimable objects has an unspecified bound[.](#7.sentence-1)

[*Note [3](#note-3)*:

The bound can be a function of the number of hazard pointers,
the number of threads that retire objects, and
the number of threads that use hazard pointers[.](#7.sentence-2)

â *end note*]

[*Example [1](#example-1)*:

The following example shows how hazard pointers allow updates to be carried out
in the presence of concurrent readers[.](#7.sentence-3)

The object of type hazard_pointer in print_name protects the object *ptr from being reclaimed by ptr->retire until the end of the protection epoch[.](#7.sentence-4)

struct Name : public hazard_pointer_obj_base<Name> { /* details */ };
atomic<Name*> name;// called often and in parallel!void print_name() { hazard_pointer h = make_hazard_pointer();
 Name* ptr = h.protect(name); // Protection epoch starts// ... safe to access *ptr} // Protection epoch ends.// called rarely, but possibly concurrently with print_namevoid update_name(Name* new_name) { Name* ptr = name.exchange(new_name);
 ptr->retire();} â *end example*]
