roo_threads
API Documentation for roo_threads
Loading...
Searching...
No Matches
semaphore.h
Go to the documentation of this file.
1#pragma once
2
4
5#ifdef ROO_THREADS_USE_FREERTOS
6
7#include <limits>
8
9#include "freertos/FreeRTOS.h"
10#include "freertos/semphr.h"
12
13namespace roo_threads {
14/// @brief Backend namespace using FreeRTOS synchronization primitives.
15namespace freertos {
16
17// Note: it doesn't seem to make sense to make a 'lazy-initialize' version
18// of semaphores, because they take the desired initial count which is
19// usually greater than zero.
20
21template <std::ptrdiff_t LeastMaxValue =
22 std::numeric_limits<UBaseType_t>::max()>
23/// @ingroup roo_threads_api_semaphore
24/// @brief FreeRTOS backend implementation of `roo::counting_semaphore`.
25/// @copydoc roo_threads::doc::counting_semaphore
26class counting_semaphore {
27 public:
28 /// @copydoc roo_threads::doc::counting_semaphore::counting_semaphore
29 explicit counting_semaphore(std::ptrdiff_t desired) noexcept {
30 xSemaphoreCreateCountingStatic(LeastMaxValue, desired, &sem_);
31 }
32
33 counting_semaphore(const counting_semaphore&) = delete;
34
35 counting_semaphore& operator=(const counting_semaphore&) = delete;
36
37 /// @copydoc roo_threads::doc::counting_semaphore::acquire
38 void acquire() noexcept {
39 xSemaphoreTake((SemaphoreHandle_t)&sem_, portMAX_DELAY);
40 }
41
42 /// @copydoc roo_threads::doc::counting_semaphore::try_acquire
43 bool try_acquire() noexcept {
44 return xSemaphoreTake((SemaphoreHandle_t)&sem_, 0) == pdTRUE;
45 }
46
47 /// @copydoc roo_threads::doc::counting_semaphore::try_acquire_for
48 bool try_acquire_for(const roo_time::Duration& duration) noexcept {
49 return try_acquire_until(internal::CalculateDeadlineFromDuration(duration));
50 }
51
52 /// @copydoc roo_threads::doc::counting_semaphore::try_acquire_until
53 bool try_acquire_until(const roo_time::Uptime& when) noexcept {
54 while (true) {
55 roo_time::Uptime now = roo_time::Uptime::Now();
56 if (when <= now) return false;
57 roo_time::Duration delta = when - now;
58 if (xSemaphoreTake((SemaphoreHandle_t)&sem_, internal::ToTicks(delta)) ==
59 pdTRUE) {
60 return true;
61 }
62 }
63 }
64
65 /// @copydoc roo_threads::doc::counting_semaphore::release
66 void release() noexcept { xSemaphoreGive((SemaphoreHandle_t)&sem_); }
67
68 private:
69 StaticSemaphore_t sem_;
70};
71
72/// @ingroup roo_threads_api_semaphore
73/// @brief FreeRTOS backend implementation of `roo::binary_semaphore`.
74/// @copydoc roo_threads::doc::binary_semaphore
75class binary_semaphore {
76 public:
77 /// @brief Constructs a binary semaphore.
78 /// @param desired initial token count (`0` or `1`).
79 explicit binary_semaphore(std::ptrdiff_t desired) noexcept {
80 xSemaphoreCreateBinaryStatic(&sem_);
81 if (desired > 0) {
82 xSemaphoreGive((SemaphoreHandle_t)&sem_);
83 }
84 }
85
86 binary_semaphore(const binary_semaphore&) = delete;
87
88 binary_semaphore& operator=(const binary_semaphore&) = delete;
89
90 /// @copydoc roo_threads::doc::counting_semaphore::acquire
91 void acquire() noexcept {
92 xSemaphoreTake((SemaphoreHandle_t)&sem_, portMAX_DELAY);
93 }
94
95 /// @copydoc roo_threads::doc::counting_semaphore::try_acquire
96 bool try_acquire() noexcept {
97 return xSemaphoreTake((SemaphoreHandle_t)&sem_, 0) == pdTRUE;
98 }
99
100 /// @copydoc roo_threads::doc::counting_semaphore::try_acquire_for
101 bool try_acquire_for(const roo_time::Duration& duration) noexcept {
102 return try_acquire_until(internal::CalculateDeadlineFromDuration(duration));
103 }
104
105 /// @copydoc roo_threads::doc::counting_semaphore::try_acquire_until
106 bool try_acquire_until(const roo_time::Uptime& when) noexcept {
107 while (true) {
108 roo_time::Uptime now = roo_time::Uptime::Now();
109 if (when <= now) return false;
110 roo_time::Duration delta = when - now;
111 if (xSemaphoreTake((SemaphoreHandle_t)&sem_, internal::ToTicks(delta)) ==
112 pdTRUE) {
113 return true;
114 }
115 }
116 }
117
118 /// @copydoc roo_threads::doc::counting_semaphore::release
119 void release() noexcept { xSemaphoreGive((SemaphoreHandle_t)&sem_); }
120
121 private:
122 StaticSemaphore_t sem_;
123};
124
125} // namespace freertos
126} // namespace roo_threads
127
128#endif // ROO_THREADS_USE_FREERTOS
counting_semaphore< 1 > binary_semaphore
Semaphore with maximum count of one.