Comms CCF
This is a simple communication layer based on COBS, CBOR and FNV-1A
Loading...
Searching...
No Matches
mutex.hpp
Go to the documentation of this file.
1
5#pragma once
6
7#include <FreeRTOS.h>
8#include <queue.h>
9#include <semphr.h>
10
11#include <assert.h>
12
13#include <optional>
14#include <utility>
15
16template<typename T>
17class Guard;
18
19template<typename T>
20class Mutex
21{
22public:
23 using Underlying = T;
24 using GuardT = Guard<T>;
25
26 template<typename... Args>
27 Mutex(Args && ... args) : value(std::forward<Args>(args)...)
28 {
29 mutex = xSemaphoreCreateMutexStatic(&buffer);
30 }
31
32 std::optional<GuardT> lock(TickType_t timeout)
33 {
34 if (xSemaphoreTake(mutex, timeout))
35 {
36 return std::optional{GuardT{this}};
37 }
38 return std::optional<GuardT>{};
39 }
40
41 GuardT lock()
42 {
43 while (!xSemaphoreTake(mutex, portMAX_DELAY)) { }
44 return GuardT{this};
45 }
46
47 bool unlock() const
48 {
49 return xSemaphoreGive(mutex) == pdTRUE;
50 }
51
52 T & unsafeGetUnderlying()
53 {
54 return value;
55 }
56
57private:
58 SemaphoreHandle_t mutex;
59 StaticSemaphore_t buffer;
60 T value;
61};
62
63template<typename T>
64class Guard
65{
66public:
67 using MutexT = Mutex<T>;
68
69 Guard(MutexT * mutex_) : mutex(mutex_) { }
70 Guard(const Guard &) = delete;
71 Guard & operator=(const Guard &) = delete;
72 Guard(Guard &&) = default;
73 Guard & operator=(Guard &&) = default;
74 ~Guard()
75 {
76 bool success = mutex->unlock();
77 assert(success);
78 }
79
80 T * operator->()
81 {
82 return &mutex->unsafeGetUnderlying();
83 }
84
85 const T * operator->() const
86 {
87 return &mutex->unsafeGetUnderlying();
88 }
89
90private:
91 MutexT * mutex;
92};
Definition mutex.hpp:65
Definition mutex.hpp:21