[saferecl.hp.general] (original) (raw)

32 Concurrency support library [thread]

32.11 Safe reclamation [saferecl]

32.11.3 Hazard pointers [saferecl.hp]

32.11.3.1 General [saferecl.hp.general]

A hazard pointer is a single-writer multi-reader pointer that can be owned by at most one thread at any time.

Only the owner of the hazard pointer can set its value, while any number of threads may read its value.

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.

A class type T is hazard-protectableif 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.

An object is hazard-protectable if it is of hazard-protectable type.

The time span between creation and destruction of a hazard pointer his partitioned into a series of protection epochs; in each protection epoch,h either is associated witha hazard-protectable object, or is unassociated.

Upon creation, a hazard pointer is unassociated.

Changing the association (possibly to the same object) initiates a new protection epoch and ends the preceding one.

An object x of hazard-protectable type T isretired with a deleter of type Dwhen the member function hazard_pointer_obj_base<T, D>​::​retireis invoked on x.

Any given object x shall be retired at most once.

A retired object x is reclaimedby invoking its deleter with a pointer to x; the behavior is undefined if that invocation exits via an exception.

A hazard-protectable object x is possibly-reclaimablewith respect to an evaluation A if

The number of possibly-reclaimable objects has an unspecified bound.

[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.

— _end note_]

[Example 1:

The following example shows how hazard pointers allow updates to be carried out in the presence of concurrent readers.

The object of type hazard_pointer in print_nameprotects the object *ptr from being reclaimed by ptr->retireuntil the end of the protection epoch.

struct Name : public hazard_pointer_obj_base<Name> { }; atomic<Name*> name;void print_name() { hazard_pointer h = make_hazard_pointer(); Name* ptr = h.protect(name); } void update_name(Name* new_name) { Name* ptr = name.exchange(new_name); ptr->retire();} — _end example_]