Thread System 0.3.1
High-performance C++20 thread pool with work stealing and DAG scheduling
Loading...
Searching...
No Matches
kcenon::thread::backoff_calculator Class Reference

Calculates backoff delays for work-stealing operations. More...

#include <steal_backoff_strategy.h>

Collaboration diagram for kcenon::thread::backoff_calculator:
Collaboration graph

Public Member Functions

 backoff_calculator (steal_backoff_config config={})
 Construct a backoff calculator with given configuration.
 
auto calculate (std::size_t attempt) -> std::chrono::microseconds
 Calculate backoff delay for a given attempt number.
 
auto get_config () const -> const steal_backoff_config &
 Get the current configuration.
 
void set_config (steal_backoff_config config)
 Update the configuration.
 

Private Member Functions

auto calculate_base_delay (std::size_t attempt) const -> std::chrono::microseconds
 Calculate base delay without jitter or capping.
 
auto apply_jitter (std::chrono::microseconds delay) -> std::chrono::microseconds
 Apply random jitter to a delay.
 
auto cap_delay (std::chrono::microseconds delay) const -> std::chrono::microseconds
 Cap delay at maximum.
 

Private Attributes

steal_backoff_config config_
 
std::mt19937_64 rng_
 

Detailed Description

Calculates backoff delays for work-stealing operations.

This class provides thread-safe backoff delay calculation using various strategies. It is designed to be used by workers when steal attempts fail.

Thread Safety

Each worker should have its own backoff_calculator instance to avoid contention on the random number generator. All methods are thread-safe when used with separate instances.

Usage Example

config.initial_backoff = std::chrono::microseconds{50};
config.max_backoff = std::chrono::microseconds{1000};
backoff_calculator calculator(config);
// On steal failure
std::size_t attempt = 0;
while (!steal_successful && attempt < max_attempts) {
auto delay = calculator.calculate(attempt);
std::this_thread::sleep_for(delay);
++attempt;
}
backoff_calculator(steal_backoff_config config={})
Construct a backoff calculator with given configuration.
@ delay
Delay processing (attempt later)
@ exponential
Exponential increase: delay = initial * 2^attempt.
Configuration for backoff behavior.

Definition at line 90 of file steal_backoff_strategy.h.

Constructor & Destructor Documentation

◆ backoff_calculator()

kcenon::thread::backoff_calculator::backoff_calculator ( steal_backoff_config config = {})
inlineexplicit

Construct a backoff calculator with given configuration.

Parameters
configBackoff configuration

Definition at line 97 of file steal_backoff_strategy.h.

97 {})
98 : config_(config)
99 , rng_(std::random_device{}())
100 {
101 }
STL namespace.

Member Function Documentation

◆ apply_jitter()

auto kcenon::thread::backoff_calculator::apply_jitter ( std::chrono::microseconds delay) -> std::chrono::microseconds
inlinenodiscardprivate

Apply random jitter to a delay.

Definition at line 186 of file steal_backoff_strategy.h.

188 {
189 using rep = std::chrono::microseconds::rep;
190 rep base = delay.count();
191 rep jitter_range =
192 static_cast<rep>(static_cast<double>(base) * config_.jitter_factor);
193
194 if (jitter_range <= 0)
195 {
196 return delay;
197 }
198
199 std::uniform_int_distribution<rep> dist(-jitter_range, jitter_range);
200 rep jittered = base + dist(rng_);
201
202 // Ensure we don't go negative
203 return std::chrono::microseconds{std::max(rep{1}, jittered)};
204 }
double jitter_factor
Jitter range as fraction of delay (0.0 - 1.0)

References config_, kcenon::thread::delay, kcenon::thread::steal_backoff_config::jitter_factor, and rng_.

Referenced by calculate().

Here is the caller graph for this function:

◆ calculate()

auto kcenon::thread::backoff_calculator::calculate ( std::size_t attempt) -> std::chrono::microseconds
inlinenodiscard

Calculate backoff delay for a given attempt number.

Parameters
attemptThe attempt number (0-indexed)
Returns
Calculated backoff delay

The delay is calculated based on the configured strategy and capped at max_backoff.

Definition at line 111 of file steal_backoff_strategy.h.

112 {
113 auto delay = calculate_base_delay(attempt);
114
116 {
118 }
119
120 return cap_delay(delay);
121 }
auto apply_jitter(std::chrono::microseconds delay) -> std::chrono::microseconds
Apply random jitter to a delay.
auto cap_delay(std::chrono::microseconds delay) const -> std::chrono::microseconds
Cap delay at maximum.
auto calculate_base_delay(std::size_t attempt) const -> std::chrono::microseconds
Calculate base delay without jitter or capping.
@ adaptive_jitter
Exponential with random jitter for anti-correlation.

References kcenon::thread::adaptive_jitter, apply_jitter(), calculate_base_delay(), cap_delay(), config_, kcenon::thread::delay, and kcenon::thread::steal_backoff_config::strategy.

Here is the call graph for this function:

◆ calculate_base_delay()

auto kcenon::thread::backoff_calculator::calculate_base_delay ( std::size_t attempt) const -> std::chrono::microseconds
inlinenodiscardprivate

Calculate base delay without jitter or capping.

Definition at line 145 of file steal_backoff_strategy.h.

147 {
148 auto initial = static_cast<double>(config_.initial_backoff.count());
149 auto max_count = static_cast<double>(config_.max_backoff.count());
150
151 switch (config_.strategy)
152 {
155
157 return std::chrono::microseconds{
158 static_cast<std::int64_t>(initial * static_cast<double>(attempt + 1))};
159
162 {
163 // Calculate multiplier^attempt with overflow protection
164 double factor = 1.0;
165 for (std::size_t i = 0; i < attempt; ++i)
166 {
167 factor *= config_.multiplier;
168 // Early exit if we've exceeded max to avoid unnecessary computation
169 if (factor * initial > max_count)
170 {
171 return config_.max_backoff;
172 }
173 }
174 return std::chrono::microseconds{
175 static_cast<std::int64_t>(initial * factor)};
176 }
177
178 default:
180 }
181 }
@ linear
Linear increase: delay = initial * (attempt + 1)
@ fixed
Constant delay between steal attempts.
double multiplier
Multiplier for exponential backoff.

References kcenon::thread::adaptive_jitter, config_, kcenon::thread::exponential, kcenon::thread::fixed, kcenon::thread::steal_backoff_config::initial_backoff, kcenon::thread::linear, kcenon::thread::steal_backoff_config::max_backoff, kcenon::thread::steal_backoff_config::multiplier, and kcenon::thread::steal_backoff_config::strategy.

Referenced by calculate().

Here is the caller graph for this function:

◆ cap_delay()

auto kcenon::thread::backoff_calculator::cap_delay ( std::chrono::microseconds delay) const -> std::chrono::microseconds
inlinenodiscardprivate

Cap delay at maximum.

Definition at line 209 of file steal_backoff_strategy.h.

211 {
212 return std::min(delay, config_.max_backoff);
213 }

References config_, kcenon::thread::delay, and kcenon::thread::steal_backoff_config::max_backoff.

Referenced by calculate().

Here is the caller graph for this function:

◆ get_config()

auto kcenon::thread::backoff_calculator::get_config ( ) const -> const steal_backoff_config&
inlinenodiscard

Get the current configuration.

Returns
Reference to the backoff configuration

Definition at line 127 of file steal_backoff_strategy.h.

128 {
129 return config_;
130 }

References config_.

◆ set_config()

void kcenon::thread::backoff_calculator::set_config ( steal_backoff_config config)
inline

Update the configuration.

Parameters
configNew configuration to use

Definition at line 136 of file steal_backoff_strategy.h.

137 {
138 config_ = config;
139 }

References config_.

Member Data Documentation

◆ config_

steal_backoff_config kcenon::thread::backoff_calculator::config_
private

◆ rng_

std::mt19937_64 kcenon::thread::backoff_calculator::rng_
private

Definition at line 216 of file steal_backoff_strategy.h.

Referenced by apply_jitter().


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