xenium
Public Member Functions | List of all members
xenium::seqlock< T, Policies > Struct Template Reference

An implementation of the sequence lock (also often referred to as "sequential lock"). More...

#include <seqlock.hpp>

Public Member Functions

 seqlock ()=default
 Constructs an empty object.
 
 seqlock (const T &data)
 Constructs an object of type T via copy construction.
 
template<class... Args>
 seqlock (Args &&... args)
 Constructs an object of type T using args as the parameter list for the constructor of T. More...
 
load () const
 Reads the current value. More...
 
void store (const T &value)
 Stores the given value. More...
 
template<class Func >
void update (Func func)
 Updates the stored value with the given functor. More...
 

Detailed Description

template<class T, class... Policies>
struct xenium::seqlock< T, Policies >

An implementation of the sequence lock (also often referred to as "sequential lock").

A seqlock holds an instance of T and allows efficient concurrent reads, even in case of concurrent writes. In contrast to classic read-write-locks, readers to not have to have to announce the read operation and can therefore not block a write operation. Instead, a read operation that overlaps with a write operation will have to be retried in order to obtain a consistent snapshot. However, this imposes additional limitations on the type T, which must be default constructible, trivially copyable and trivially destructible.

Note: T should not contain pointers that may get deleted due to an update of the stored instance. The seqlock can only provide a consistent snapshot of the stored T instance, but does not provide any guarantees about satellite data that T might refer to.

The current implementation uses an implicit spin lock on the sequence counter to synchronize write operations. In the future this will also be customizable.

The current implementation is not strictly conformant with the current C++ standard, simply because at the moment it is not possible to do this in a standard conform way. However, this implementation should still work on all architectures. The situation will hopefully improve with C++20 (see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1478r0.html for more details).

Supported policies:

Template Parameters
Ttype of the stored element; T must be default constructible, trivially copyable and trivially destructible.

Constructor & Destructor Documentation

◆ seqlock()

template<class T , class... Policies>
template<class... Args>
xenium::seqlock< T, Policies >::seqlock ( Args &&...  args)
inlineexplicit

Constructs an object of type T using args as the parameter list for the constructor of T.

The object is constructed as if by the expression new (p) T(std::forward<Args>(args)...), where p is an internal void* pointer to storage suitable to hold an object of type T.

Member Function Documentation

◆ load()

template<class T , class... Policies>
T xenium::seqlock< T, Policies >::load

Reads the current value.

Progress guarantees: lock-free if slots > 1; otherwise blocking

Returns
A consistent snapshot of the stored value.

◆ store()

template<class T , class... Policies>
void xenium::seqlock< T, Policies >::store ( const T &  value)

Stores the given value.

Progress guarantees: blocking

Parameters
valuethe new value to be stored.

◆ update()

template<class T , class... Policies>
template<class Func >
void xenium::seqlock< T, Policies >::update ( Func  func)

Updates the stored value with the given functor.

The functor should have the following signature void(T&) noexcept, i.e., it should take the current value by reference and perform any modifications directly on that object. Note: The functor must not throw any exceptions.

Progress guarantees: blocking

Parameters
functhe functor to update the currently stored value.