https://github.com/htfy96/seqlock
A C++11 SeqLock implementation with reader/writer support, designed for non-blocking reads
https://github.com/htfy96/seqlock
Last synced: about 1 year ago
JSON representation
A C++11 SeqLock implementation with reader/writer support, designed for non-blocking reads
- Host: GitHub
- URL: https://github.com/htfy96/seqlock
- Owner: htfy96
- License: apache-2.0
- Created: 2019-06-03T04:21:33.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2019-06-04T05:09:14.000Z (about 7 years ago)
- Last Synced: 2025-03-03T07:41:35.033Z (over 1 year ago)
- Language: C++
- Size: 18.6 KB
- Stars: 3
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# seqlock
A C++11 SeqLock implementation with reader/writer support, designed for non-blocking reads.
 [](https://circleci.com/gh/htfy96/seqlock)
## Usage
```cpp
#include "seqlock.hpp"
struct Foo {
int v1;
double v2;
long v3;
};
// Basic usage:
using namespace seqlock;
SeqLock protected_data {2, 3.0};
protected_data.write(foo_1); // thread-safe. No serialization.
Foo data = protected_data.load(); // does not block write, thread-safe
// Advanced usage:
// mainly used for large structs to avoid copy
{
auto writer = protected_data.get_writer(); // move-only
// exclusive access
auto old_value = writer.read_member(&Foo::v);
writer.write_member(&Foo::v, old_value + 2);
// writer lock will be automatically released at the exit of scope
}
std::tuple v1_and_v3 = protected_data.load_members(&Foo::v1, &Foo::v3);
```
A seqlock is a writer-first userspace lock.
Reader doesn't block writers by retrying read based on version numbers.
Use cases:
- busy writer(s)
- a small number of writers
- starvation between writers can be tolerated
- non-blocking reads
```cpp
template
class SeqLock;
```
Precondition: `is_trivial`
Config:
- `T`: protected data, must be TrivialType
- `ReadConflictPolicy`: Behavior when load() finds another thread writing the
value.
Default: `conflict_policies::Auto`.
- `WriteConflictPolicy`: Behavior when store() finds another thread writing
the value.
Default: `conflict_policies::Auto`.
- `SeqCounterT`: the sequence counter. Set this to a larger type if there are
too many writers causing it to wrap around.
Implementation based on: *Can Seqlocks Get Along with Programming Language
Memory Models?, Hans-J. Boehm HP Labs*
`conflict_policies`:
- `Pause`: use x86 instruction `pause` on conflict
- `Yield`: yield to another thread
- `RetryImmediately`: no-op
- `Auto`: use `Pause` when possible, `Yield` otherwise