Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
latch.hpp
Go to the documentation of this file.
1// Copyright 2024, Toyota Motor Corporation
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_SYNCHRONIZATION_LATCH_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_SYNCHRONIZATION_LATCH_HPP_
7
8#include <atomic>
9#include <cstddef>
10#include <limits>
11
12// parasoft-begin-suppress AUTOSAR-A16_2_2-a-2 "Arene Base aggregate headers permitted by A16-2-2 Permit #1"
13#include "arene/base/compiler_support/expect.hpp"
14#include "arene/base/contracts.hpp"
15#include "arene/base/synchronization/manual_reset_event.hpp"
16// parasoft-end-suppress AUTOSAR-A16_2_2-a-2
17
18// parasoft-begin-suppress AUTOSAR-A7_1_5-a-2 "Trailing return syntax permitted by A7-1-5 Permit #1 v1.0.0"
19
20namespace arene {
21namespace base {
22
23/// @brief Backport of @c std::latch from C++20. Provides a count-down latch that stays
24/// permanently signalled when the count reaches zero. For a given instance,
25/// every call to @c count_down or @c arrive_and_wait synchronizes-with every
26/// call to @c wait or @c arrive_and_wait, and every call to @c try_wait that
27/// returns @c true.
28class latch {
29 public:
30 /// @brief Get the maximum supported count
31 /// @return The maximum count
32 static constexpr auto max() noexcept -> std::ptrdiff_t { return std::numeric_limits<std::ptrdiff_t>::max(); }
33
34 // parasoft-begin-suppress AUTOSAR-A3_1_5-a-2 "False positive: intended to be inlined"
35 /// @brief Construct a latch with the specified count. If the @c count is zero, then
36 /// the latch will be already signalled.
37 /// @param initial_count The initial count for the latch
38 /// @pre initial_count >= 0
39 constexpr explicit latch(std::ptrdiff_t initial_count)
41 ARENE_PRECONDITION(initial_count >= 0);
42 }
43 // parasoft-end-suppress AUTOSAR-A3_1_5-a-2
44
45 /// @brief Default destructor
46 ~latch() = default;
47
48 // parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
49 /// @brief Not copyable
50 latch(latch const&) = delete;
51 /// @brief Not copyable
52 auto operator=(latch const&) -> latch& = delete;
53 /// @brief Not movable
54 latch(latch&&) = delete;
55 /// @brief Not movable
56 auto operator=(latch&&) -> latch& = delete;
57 // parasoft-end-suppress CERT_C-EXP37-a-3
58
59 /// @brief Check if the latch is signalled without blocking.
60 /// @return @c true if the latch is signalled, @c false otherwise.
61 auto try_wait() const noexcept -> bool { return count_.load(std::memory_order_acquire) == 0; }
62
63 // parasoft-begin-suppress AUTOSAR-A3_1_5-a-2 "False positive: intended to be inlined"
64 /// @brief Count down the latch by @c update. If the counter reaches zero, the latch
65 /// is permanently signalled, and any threads blocked in @c wait are
66 /// unblocked.
67 /// @param update The amount by which to decrease the count
68 /// @pre <c>(update >= 0) && (update <= count_)</c>
69 /// @throw std::system_error on error
70 void count_down(std::ptrdiff_t update) {
71 ARENE_PRECONDITION((update >= 0) && (update <= count_));
72 if (count_.fetch_sub(update, std::memory_order_acq_rel) == update) {
73 event_.signal();
74 }
75 }
76 // parasoft-end-suppress AUTOSAR-A3_1_5-a-2
77
78 /// @brief Count down the latch by 1. If the counter reaches zero, the latch
79 /// is permanently signalled, and any threads blocked in @c wait are
80 /// unblocked.
81 /// @pre The latch must not be signalled.
82 /// @throw std::system_error on error
83 void count_down() { count_down(1); }
84
85 /// @brief Blocks the current thread until the latch becomes signalled.
86 /// @throw std::system_error on error
87 void wait() const {
88 if (!try_wait()) {
89 event_.wait();
90 }
91 }
92
93 /// @brief Count down the latch by @c update and blocks the current thread waiting
94 /// for the latch to be signalled.
95 /// @param update The amount by which to decrease the count
96 /// @throw std::system_error on error
97 void arrive_and_wait(std::ptrdiff_t const update) {
98 count_down(update);
99 wait();
100 }
101
102 /// @brief Count down the latch by 1 and blocks the current thread waiting
103 /// for the latch to be signalled.
104 /// @throw std::system_error on error
106
107 private:
108 /// @brief The remaining count
109 std::atomic<std::ptrdiff_t> count_;
110 /// @brief An event used for signalling
111 manual_reset_event event_;
112};
113
114} // namespace base
115} // namespace arene
116
117#endif // INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_SYNCHRONIZATION_LATCH_HPP_
Backport of std::latch from C++20. Provides a count-down latch that stays permanently signalled when ...
Definition latch.hpp:28
auto try_wait() const noexcept -> bool
Check if the latch is signalled without blocking.
Definition latch.hpp:61
void count_down()
Count down the latch by 1. If the counter reaches zero, the latch is permanently signalled,...
Definition latch.hpp:83
auto operator=(latch const &) -> latch &=delete
Not copyable.
latch(latch const &)=delete
Not copyable.
auto operator=(latch &&) -> latch &=delete
Not movable.
void arrive_and_wait()
Count down the latch by 1 and blocks the current thread waiting for the latch to be signalled.
Definition latch.hpp:105
static constexpr auto max() noexcept -> std::ptrdiff_t
Get the maximum supported count.
Definition latch.hpp:32
constexpr latch(std::ptrdiff_t initial_count)
Construct a latch with the specified count. If the count is zero, then the latch will be already sign...
Definition latch.hpp:39
~latch()=default
Default destructor.
void count_down(std::ptrdiff_t update)
Count down the latch by update. If the counter reaches zero, the latch is permanently signalled,...
Definition latch.hpp:70
void wait() const
Blocks the current thread until the latch becomes signalled.
Definition latch.hpp:87
void arrive_and_wait(std::ptrdiff_t const update)
Count down the latch by update and blocks the current thread waiting for the latch to be signalled.
Definition latch.hpp:97
latch(latch &&)=delete
Not movable.
Definition array_exceptions_disabled.cpp:11
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10