userver: userver/utils/cpu_relax.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
cpu_relax.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/utils/cpu_relax.hpp
4/// @brief Helper classes to yield in CPU intensive places
5
6#include <chrono>
7#include <cstddef>
8
9#include <userver/tracing/scope_time.hpp>
10
11USERVER_NAMESPACE_BEGIN
12
13namespace utils {
14
15/// Utility to easily pause ScopeTime, e.g. when yielding
17 public:
18 explicit ScopeTimePause(tracing::ScopeTime* scope);
19
20 /// Pause a ScopeTime, if any
21 void Pause();
22
23 /// Unpause the ScopeTime, if any
24 void Unpause();
25
26 private:
27 tracing::ScopeTime* scope_;
28 std::string scope_name_;
29};
30
31/// Utility to yield every N iterations in a CPU-bound task to give other tasks
32/// an opportunity to get CPU time
33class CpuRelax {
34 public:
35 /// @param every number of iterations to call yield. 0 = noop
36 /// @param scope the tracing::ScopeTime to pause when yielding, if any
37 /// @warning The `ScopeTime` must live at least as long as the `CpuRelax`
38 explicit CpuRelax(std::size_t every, tracing::ScopeTime* scope);
39
40 CpuRelax(const CpuRelax&) = delete;
41 CpuRelax(CpuRelax&&) = delete;
42
43 /// Call this method every iteration, eventually it will yield
44 void Relax();
45
46 private:
47 ScopeTimePause pause_;
48 const std::size_t every_iterations_;
49 std::size_t iterations_{0};
50};
51
52/// Utility to yield in a CPU-bound data processing task
53/// to give other tasks an opportunity to get CPU time
55 public:
56 /// @param check_time_after_bytes number of bytes to call yield
57 /// @param scope the tracing::ScopeTime to pause when yielding, if any
58 /// @warning The `ScopeTime` must live at least as long as the `CpuRelax`
59 explicit StreamingCpuRelax(std::uint64_t check_time_after_bytes,
60 tracing::ScopeTime* scope);
61
62 /// Checks time and potentially calls `engine::Yield()`
63 /// each `check_time_after_bytes` bytes
64 void Relax(std::uint64_t bytes_processed);
65
66 /// Returns the total amount of bytes processed since the creation
67 /// of `StreamingCpuRelax`
68 std::uint64_t GetBytesProcessed() const;
69
70 private:
71 ScopeTimePause pause_;
72 std::uint64_t check_time_after_bytes_;
73 std::uint64_t total_bytes_{0};
74 std::uint64_t bytes_since_last_time_check_{0};
75 std::chrono::steady_clock::time_point last_yield_time_;
76};
77
78} // namespace utils
79
80USERVER_NAMESPACE_END