userver: concurrent::StripedCounter Class Reference
Loading...
Searching...
No Matches
concurrent::StripedCounter Class Referencefinal

#include <userver/concurrent/striped_counter.hpp>

Detailed Description

A contention-free sharded atomic counter, with memory consumption and read performance traded for write performance. Intended to be used for write-heavy counters, mostly in metrics.

Note
Depending on the underlying platform is implemented either via a single atomic variable, or an 'nproc'-sized array of interference-shielded rseq-based (https://www.phoronix.com/news/Restartable-Sequences-Speed) per-CPU counters. In the second case, read is approx. nproc times slower than write.

Definition at line 25 of file striped_counter.hpp.

Public Member Functions

 StripedCounter ()
 Constructs a zero-initialized counter. Might allocate up to kDestructiveInterferenceSize (64 bytes for x86_64) * number of available CPUs bytes.
 
 StripedCounter (const StripedCounter &)=delete
 
StripedCounteroperator= (const StripedCounter &)=delete
 
 StripedCounter (StripedCounter &&)=delete
 
StripedCounteroperator= (StripedCounter &&)=delete
 
void Add (std::uintptr_t value) noexcept
 The addition is done with a relaxed memory order.
 
void Subtract (std::uintptr_t value) noexcept
 The subtraction is done with a relaxed memory order.
 
std::uintptr_t Read () const noexcept
 Read the the total counter value. The counter uses the full range of std::uintptr_t, using wrap-around when necessary.
 
std::uintptr_t NonNegativeRead () const noexcept
 Read the non-negative total counter value.
 

Member Function Documentation

◆ NonNegativeRead()

std::uintptr_t concurrent::StripedCounter::NonNegativeRead ( ) const
noexcept

Read the non-negative total counter value.

Note
The read is done with std::memory_order_acquire.

This is almost exactly like Read, but for an Add-Subtract race, instead of returning a negative value, this function returns 0. Consider this a convenient shortcut to avoid seeing logically impossible negative values.

◆ Read()

std::uintptr_t concurrent::StripedCounter::Read ( ) const
noexcept

Read the the total counter value. The counter uses the full range of std::uintptr_t, using wrap-around when necessary.

Note
The read is done with std::memory_order_acquire.

Due to the underlying implementation being an array of counters, this function may return logically impossible values if Subtract is in play. For example, doing Add(1) and Subtract(1) may lead to this function returning -1 (wrapped). With Subtract, consider using NonNegativeRead instead.

◆ Subtract()

void concurrent::StripedCounter::Subtract ( std::uintptr_t value)
inlinenoexcept

The subtraction is done with a relaxed memory order.

Definition at line 43 of file striped_counter.hpp.


The documentation for this class was generated from the following file: