19 bool valid() const noexcept {
return identity_ !=
nullptr; }
28 : identity_(identity) {}
30 const void* identity_ =
nullptr;
33static_assert(std::is_trivially_copyable_v<SampleMemoryGovernorEpoch>);
59 :
stats{.capacity_bytes = capacity} {}
66inline void saturating_add(std::uint64_t& target, std::uint64_t value)
noexcept {
67 target = value > std::numeric_limits<std::uint64_t>::max() - target
68 ? std::numeric_limits<std::uint64_t>::max()
86 : state_(std::move(other.state_)),
87 category_(other.category_),
88 bytes_(std::exchange(other.bytes_, 0)) {}
91 if (
this == &other)
return *
this;
93 state_ = std::move(other.state_);
94 category_ = other.category_;
95 bytes_ = std::exchange(other.bytes_, 0);
101 explicit operator bool() const noexcept {
return state_ !=
nullptr && bytes_ != 0; }
103 std::uint64_t
bytes() const noexcept {
return bytes_; }
112 if (!state_ || bytes_ == 0) {
119 const std::scoped_lock lock(state_->mutex);
120 auto& stats = state_->stats;
122 ? stats.current_preload_bytes
123 : stats.current_page_bytes;
124 category_bytes -= std::min(category_bytes, bytes_);
125 stats.current_total_bytes -= std::min(stats.current_total_bytes, bytes_);
137 std::uint64_t
bytes) noexcept
140 std::shared_ptr<detail::SampleMemoryGovernorState> state_;
142 std::uint64_t bytes_ = 0;
159 static_cast<bool>(
lease);
169 explicit operator bool() const noexcept {
return prepared(); }
171 if (!state_)
return false;
172 const std::scoped_lock lock(state_->mutex);
173 return state_->accepting_reservations;
177 std::uint64_t bytes)
const noexcept {
180 const std::scoped_lock lock(state_->mutex);
181 auto&
stats = state_->stats;
182 if (!state_->accepting_reservations)
193 if (
stats.current_total_bytes >
stats.capacity_bytes ||
194 bytes >
stats.capacity_bytes -
stats.current_total_bytes) {
196 ?
stats.rejected_preload_count
197 :
stats.rejected_page_count;
199 ?
stats.rejected_preload_bytes
200 :
stats.rejected_page_bytes;
207 ?
stats.current_preload_bytes
208 :
stats.current_page_bytes;
210 ?
stats.peak_preload_bytes
211 :
stats.peak_page_bytes;
212 category_bytes += bytes;
213 stats.current_total_bytes += bytes;
214 category_peak = std::max(category_peak, category_bytes);
215 stats.peak_total_bytes = std::max(
stats.peak_total_bytes,
216 stats.current_total_bytes);
224 if (!state_)
return {};
225 const std::scoped_lock lock(state_->mutex);
226 return state_->stats;
230 return state_ !=
nullptr && lease.state_ == state_;
241 std::shared_ptr<detail::SampleMemoryGovernorState>
state) noexcept
242 : state_(std::move(
state)) {}
244 std::shared_ptr<detail::SampleMemoryGovernorState> state_;
249 return governor.issued(*
this);
255 std::uint32_t channels,
256 std::uint64_t frames_per_buffer,
257 std::uint32_t buffer_count = 1,
259 if (channels == 0 || frames_per_buffer == 0 || buffer_count == 0 ||
264 constexpr auto maximum = std::numeric_limits<std::uint64_t>::max();
265 std::uint64_t bytes = channels;
266 for (
const auto factor : {
268 static_cast<std::uint64_t
>(buffer_count),
271 if (factor > maximum / bytes)
return std::nullopt;
289 if (capacity_bytes == 0)
return false;
291 const std::scoped_lock lock(state_->mutex);
292 if (state_->stats.current_total_bytes != 0)
return false;
296 std::make_shared<detail::SampleMemoryGovernorState>(capacity_bytes);
298 const std::scoped_lock lock(state_->mutex);
299 if (state_->stats.current_total_bytes != 0)
return false;
300 state_->accepting_reservations =
false;
302 state_ = std::move(replacement);
311 if (!state_)
return true;
313 const std::scoped_lock lock(state_->mutex);
314 if (state_->stats.current_total_bytes != 0)
return false;
315 state_->accepting_reservations =
false;
328 std::uint64_t bytes)
noexcept {
337 std::shared_ptr<detail::SampleMemoryGovernorState> state_;
Definition sample_memory_governor.hpp:16
bool valid() const noexcept
Definition sample_memory_governor.hpp:19
friend class SampleMemoryLease
Definition sample_memory_governor.hpp:25
friend class SampleMemoryGovernorHandle
Definition sample_memory_governor.hpp:24
SampleMemoryGovernorEpoch()=default
friend bool operator==(SampleMemoryGovernorEpoch, SampleMemoryGovernorEpoch) noexcept=default
Copyable lifetime-safe reservation/stats endpoint.
Definition sample_memory_governor.hpp:165
SampleMemoryGovernorStats stats() const noexcept
Definition sample_memory_governor.hpp:223
bool prepared() const noexcept
Definition sample_memory_governor.hpp:170
SampleMemoryReserveResult reserve(SampleMemoryCategory category, std::uint64_t bytes) const noexcept
Definition sample_memory_governor.hpp:176
bool issued(const SampleMemoryLease &lease) const noexcept
Definition sample_memory_governor.hpp:229
friend class SampleMemoryGovernor
Definition sample_memory_governor.hpp:238
SampleMemoryGovernorHandle()=default
SampleMemoryGovernorEpoch epoch() const noexcept
Definition sample_memory_governor.hpp:233
SampleMemoryGovernorHandle handle() const noexcept
Definition sample_memory_governor.hpp:323
bool prepared() const noexcept
Definition sample_memory_governor.hpp:321
SampleMemoryGovernor()=default
SampleMemoryGovernor & operator=(const SampleMemoryGovernor &)=delete
SampleMemoryGovernorStats stats() const noexcept
Definition sample_memory_governor.hpp:332
SampleMemoryGovernor(const SampleMemoryGovernor &)=delete
bool prepare(std::uint64_t capacity_bytes)
Definition sample_memory_governor.hpp:288
SampleMemoryReserveResult reserve(SampleMemoryCategory category, std::uint64_t bytes) noexcept
Definition sample_memory_governor.hpp:327
bool release() noexcept
Drops the facade only when no outstanding leases remain.
Definition sample_memory_governor.hpp:310
SampleMemoryGovernor(SampleMemoryGovernor &&) noexcept=default
Move-only reservation against one shared sampler-memory cap.
Definition sample_memory_governor.hpp:79
~SampleMemoryLease()
Definition sample_memory_governor.hpp:99
SampleMemoryLease(SampleMemoryLease &&other) noexcept
Definition sample_memory_governor.hpp:85
SampleMemoryLease & operator=(SampleMemoryLease &&other) noexcept
Definition sample_memory_governor.hpp:90
SampleMemoryLease & operator=(const SampleMemoryLease &)=delete
std::uint64_t bytes() const noexcept
Definition sample_memory_governor.hpp:103
friend class SampleMemoryGovernorHandle
Definition sample_memory_governor.hpp:133
SampleMemoryCategory category() const noexcept
Definition sample_memory_governor.hpp:102
friend class SampleMemoryGovernor
Definition sample_memory_governor.hpp:132
SampleMemoryLease(const SampleMemoryLease &)=delete
SampleMemoryLease()=default
bool issued_by(const SampleMemoryGovernorHandle &governor) const noexcept
Definition sample_memory_governor.hpp:247
SampleMemoryGovernorEpoch epoch() const noexcept
Definition sample_memory_governor.hpp:105
void reset() noexcept
Definition sample_memory_governor.hpp:111
Definition impulse_response.hpp:69
void saturating_add(std::uint64_t &target, std::uint64_t value) noexcept
Definition sample_memory_governor.hpp:66
Definition analyzer_provider.hpp:12
SampleMemoryCategory
Definition sample_memory_governor.hpp:35
@ Preload
Definition sample_memory_governor.hpp:36
@ Page
Definition sample_memory_governor.hpp:37
@ NotPrepared
Definition sample_heritage_bus_dsp.hpp:21
std::optional< std::uint64_t > checked_sample_storage_bytes(std::uint32_t channels, std::uint64_t frames_per_buffer, std::uint32_t buffer_count=1, std::uint32_t bytes_per_sample=sizeof(float)) noexcept
Checked planar sample-storage formula shared by preload and page admission.
Definition sample_memory_governor.hpp:254
SampleMemoryReserveStatus
Definition sample_memory_governor.hpp:145
@ Acquired
Definition sample_memory_governor.hpp:146
@ InvalidByteCount
Definition sample_memory_governor.hpp:148
@ InvalidCategory
Definition sample_memory_governor.hpp:149
@ NotPrepared
Definition sample_memory_governor.hpp:147
@ BudgetExceeded
Definition sample_memory_governor.hpp:150
constexpr std::size_t bytes_per_sample(SampleFormat format) noexcept
Bytes per sample for format. Returns 0 for unknown values.
Definition sample_converter.hpp:61
SequencerStateChannel is the audio-safe transport for a plugin's structured NON-parameter state: the ...
Definition audio_device_manager.hpp:48
Definition sample_memory_governor.hpp:40
std::uint64_t current_total_bytes
Definition sample_memory_governor.hpp:44
std::uint64_t current_page_bytes
Definition sample_memory_governor.hpp:43
std::uint64_t peak_page_bytes
Definition sample_memory_governor.hpp:46
std::uint64_t peak_total_bytes
Definition sample_memory_governor.hpp:47
std::uint64_t peak_preload_bytes
Definition sample_memory_governor.hpp:45
std::uint64_t rejected_preload_count
Definition sample_memory_governor.hpp:48
std::uint64_t rejected_page_count
Definition sample_memory_governor.hpp:50
std::uint64_t rejected_preload_bytes
Definition sample_memory_governor.hpp:49
std::uint64_t current_preload_bytes
Definition sample_memory_governor.hpp:42
std::uint64_t rejected_page_bytes
Definition sample_memory_governor.hpp:51
std::uint64_t invalid_request_count
Definition sample_memory_governor.hpp:52
std::uint64_t capacity_bytes
Definition sample_memory_governor.hpp:41
Definition sample_memory_governor.hpp:153
SampleMemoryLease lease
Definition sample_memory_governor.hpp:155
bool acquired() const noexcept
Definition sample_memory_governor.hpp:157
SampleMemoryReserveStatus status
Definition sample_memory_governor.hpp:154
SampleMemoryGovernorState(std::uint64_t capacity) noexcept
Definition sample_memory_governor.hpp:58
bool accepting_reservations
Definition sample_memory_governor.hpp:63
std::mutex mutex
Definition sample_memory_governor.hpp:61
SampleMemoryGovernorStats stats
Definition sample_memory_governor.hpp:62