microfmt
Zero-allocation C++ formatting for constrained environments
Loading...
Searching...
No Matches
sync.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 Jarosław Pelczar <jarek@jpelczar.com>
2//
3// SPDX-License-Identifier: BSD-2-Clause
4
5#pragma once
6
37#include "../microfmt_config.hpp"
38#include <cstdint>
39#include <reloco/mutex.hpp>
40#include <reloco/unique_lock.hpp>
41
42namespace microfmt::log {
43
44namespace detail {
45
51 constexpr void lock() noexcept {}
52 constexpr void unlock() noexcept {}
53 [[nodiscard]] constexpr bool try_lock() noexcept { return true; }
54};
55
56} // namespace detail
57
59inline constexpr std::uint64_t wait_forever = ~std::uint64_t{0};
60
66 constexpr void lock() noexcept {}
67 constexpr void unlock() noexcept {}
68 template <typename Pred> [[nodiscard]] constexpr bool wait_for(std::uint64_t, Pred pred) noexcept {
69 return static_cast<bool>(pred());
70 }
71 constexpr void wake_all() noexcept {}
72};
73
83public:
84 void lock() noexcept { mutex_.lock(); }
85 void unlock() noexcept { mutex_.unlock(); }
86
87 template <typename Pred> [[nodiscard]] bool wait_for(std::uint64_t timeout_us, Pred pred) noexcept {
88 // The caller already owns mutex_; adopt it for the wait and hand it back.
89 reloco::unique_lock<reloco::mutex> guard(mutex_, reloco::adopt_lock);
90 bool ok = true;
91 if (timeout_us == wait_forever) {
92 ok = cv_.wait(guard, pred).has_value();
93 } else {
94 auto res = cv_.wait_for(guard, reloco::duration::from_micros(timeout_us), pred);
95 ok = res.has_value() && *res;
96 }
97 (void)guard.release();
98 return ok;
99 }
100
101 void wake_all() noexcept { cv_.notify_all(); }
102
103private:
104 reloco::mutex mutex_{};
105 reloco::condition_variable cv_{};
106};
107
114class RELOCO_POINTER space_notifier {
115public:
116 using callback = void (*)(void *) noexcept;
117
118 constexpr space_notifier() noexcept = default;
119 constexpr space_notifier(void *ctx RELOCO_LIFETIMEBOUND, callback cb) noexcept : ctx_(ctx), cb_(cb) {}
120
121 void notify() const noexcept {
122 if (cb_ != nullptr) {
123 cb_(ctx_);
124 }
125 }
126
127 [[nodiscard]] constexpr explicit operator bool() const noexcept { return cb_ != nullptr; }
128
129private:
130 void *ctx_{nullptr};
131 callback cb_{nullptr};
132};
133
134} // namespace microfmt::log
Hosted wait channel: a reloco::mutex plus reloco::condition_variable.
Definition sync.hpp:82
void wake_all() noexcept
Definition sync.hpp:101
void unlock() noexcept
Definition sync.hpp:85
bool wait_for(std::uint64_t timeout_us, Pred pred) noexcept
Definition sync.hpp:87
void lock() noexcept
Definition sync.hpp:84
Type-erased "space was freed" callback handed to the consumer side of a sink (two words,...
Definition sync.hpp:114
void notify() const noexcept
Definition sync.hpp:121
void(*)(void *) noexcept callback
Definition sync.hpp:116
constexpr space_notifier() noexcept=default
#define MICROFMT_API_CLASS
Definition compat.hpp:181
Definition default_log_sink.template.hpp:51
constexpr std::uint64_t wait_forever
timeout_us value meaning "wait without a deadline".
Definition sync.hpp:59
No-op mutex used as basic_logger's default Mutex so single-threaded usage pays zero synchronization c...
Definition sync.hpp:50
constexpr void unlock() noexcept
Definition sync.hpp:52
constexpr bool try_lock() noexcept
Definition sync.hpp:53
constexpr void lock() noexcept
Definition sync.hpp:51
Wait channel that never sleeps: wait_for just evaluates the predicate once. Use for single-threaded o...
Definition sync.hpp:65
constexpr bool wait_for(std::uint64_t, Pred pred) noexcept
Definition sync.hpp:68
constexpr void lock() noexcept
Definition sync.hpp:66
constexpr void wake_all() noexcept
Definition sync.hpp:71
constexpr void unlock() noexcept
Definition sync.hpp:67