16
16
#define MODM_IODEVICE_WRAPPER_HPP
17
17
18
18
#include <stdint.h>
19
-
19
+ %% if with_fiber
20
+ #include <modm/processing/fiber.hpp>
21
+ %% endif
22
+ %#
20
23
#include "iodevice.hpp"
21
24
22
25
namespace modm
@@ -39,19 +42,34 @@ IOBuffer
39
42
template< class Device, IOBuffer behavior >
40
43
class IODeviceWrapper : public IODevice
41
44
{
45
+ %% if with_fiber
46
+ static constexpr fiber::id NoOwner{fiber::id(-1)};
47
+ static inline fiber::id id{NoOwner};
48
+ %% endif
42
49
public:
43
50
IODeviceWrapper() = default;
44
51
using IODevice::write;
45
52
46
53
void
47
54
write(char c) override
48
55
{
49
- bool written;
50
- do
56
+ if constexpr (behavior == IOBuffer::BlockIfFull)
57
+ %% if with_fiber
51
58
{
52
- written = Device::write (uint8_t (c));
59
+ // lock this device to one fiber until a newline is received
60
+ const auto me = modm::this_fiber::get_id();
61
+ modm::this_fiber::poll([&]{ return id == NoOwner or id == me; });
62
+ id = me;
63
+
64
+ modm::this_fiber::poll([&]{ return Device::write(uint8_t(c)); });
65
+
66
+ if (c == '\n') id = NoOwner;
67
+ modm::this_fiber::yield();
53
68
}
54
- while (behavior == IOBuffer::BlockIfFull and not written);
69
+ %% else
70
+ while (not Device::write(uint8_t(c))) ;
71
+ %% endif
72
+ else Device::write(uint8_t(c));
55
73
}
56
74
57
75
void
@@ -71,6 +89,10 @@ class IODeviceWrapper : public IODevice
71
89
template< class Device, IOBuffer behavior >
72
90
class IODeviceObjectWrapper : public IODevice
73
91
{
92
+ %% if with_fiber
93
+ static constexpr fiber::id NoOwner{fiber::id(-1)};
94
+ fiber::id id{NoOwner};
95
+ %% endif
74
96
Device &device;
75
97
public:
76
98
IODeviceObjectWrapper(Device& device) : device{device} {}
@@ -79,12 +101,23 @@ class IODeviceObjectWrapper : public IODevice
79
101
void
80
102
write(char c) override
81
103
{
82
- bool written;
83
- do
104
+ if constexpr (behavior == IOBuffer::BlockIfFull)
105
+ %% if with_fiber
84
106
{
85
- written = device.write (uint8_t (c));
107
+ // lock this device to one fiber until a newline is received
108
+ const auto me = modm::this_fiber::get_id();
109
+ modm::this_fiber::poll([&]{ return id == NoOwner or id == me; });
110
+ id = me;
111
+
112
+ modm::this_fiber::poll([&]{ return device.write(uint8_t(c)); });
113
+
114
+ if (c == '\n') id = NoOwner;
115
+ modm::this_fiber::yield();
86
116
}
87
- while (behavior == IOBuffer::BlockIfFull and not written);
117
+ %% else
118
+ while (not device.write(uint8_t(c))) ;
119
+ %% endif
120
+ else device.write(uint8_t(c));
88
121
}
89
122
90
123
void
0 commit comments