22 #include <condition_variable> 43 int64_t
read(
void* buf,
size_t data_size)
override;
44 int64_t
write(
void* buf,
size_t data_size)
override;
45 int64_t
readRT(
void* buf,
size_t data_size)
override;
46 int64_t
writeRT(
void* buf,
size_t data_size)
override;
48 void close()
override;
53 const uint64_t fifo_capacity;
54 std::mutex mutex_rt2ui;
55 std::mutex mutex_ui2rt;
60 uint64_t ui_available_read_bytes;
61 uint64_t ui_available_write_bytes;
62 uint64_t rt_available_read_bytes;
63 uint64_t rt_available_write_bytes;
66 std::mutex ui_read_mut;
67 std::condition_variable available_read_cond;
68 bool rt_closed =
false;
76 rt_to_ui =
new char[this->fifo_capacity];
77 ui_to_rt =
new char[this->fifo_capacity];
88 if (rt_wptr == ui_rptr) {
91 std::unique_lock<std::mutex> lock(mutex_rt2ui);
93 if (ui_available_read_bytes < data_size) {
96 if (fifo_capacity - ui_rptr < data_size) {
97 uint64_t m = fifo_capacity - ui_rptr;
98 memcpy(buf, rt_to_ui + ui_rptr, m);
99 memcpy(
reinterpret_cast<char*
>(buf) + m, rt_to_ui, data_size - m);
101 memcpy(buf, rt_to_ui + ui_rptr, data_size);
103 ui_rptr = (ui_rptr + data_size) % this->fifo_capacity;
104 ui_available_read_bytes = (fifo_capacity + ui_rptr - rt_wptr) % fifo_capacity;
105 return static_cast<int64_t
>(data_size);
110 if (data_size > fifo_capacity - rt_available_read_bytes) {
111 ERROR_MSG(
"FIFO::write : Fifo full, data lost\n");
115 if (data_size > fifo_capacity - ui_wptr) {
116 uint64_t m = fifo_capacity - ui_wptr;
117 memcpy(ui_to_rt + ui_wptr, buf, m);
118 memcpy(ui_to_rt,
reinterpret_cast<const char*
>(buf) + m, data_size - m);
120 memcpy(ui_to_rt + ui_wptr, buf, data_size);
122 ui_wptr = (ui_wptr + data_size) % fifo_capacity;
123 rt_available_read_bytes = (fifo_capacity + rt_rptr - ui_wptr) % fifo_capacity;
124 return static_cast<int64_t
>(data_size);
129 if (ui_wptr == rt_rptr) {
132 std::unique_lock<std::mutex> lock(mutex_rt2ui);
134 if (rt_available_read_bytes < data_size) {
137 if (fifo_capacity - rt_rptr < data_size) {
138 uint64_t m = fifo_capacity - rt_rptr;
139 memcpy(buf, ui_to_rt + rt_rptr, m);
140 memcpy(
reinterpret_cast<char*
>(buf) + m, ui_to_rt, data_size - m);
142 memcpy(buf, ui_to_rt + rt_rptr, data_size);
144 rt_rptr = (rt_rptr + data_size) % this->fifo_capacity;
145 rt_available_read_bytes = (fifo_capacity + rt_rptr - ui_wptr) % fifo_capacity;
146 return static_cast<int64_t
>(data_size);
151 if (data_size > fifo_capacity - ui_available_read_bytes) {
152 ERROR_MSG(
"FIFO::write : Fifo full, data lost\n");
156 if (data_size > fifo_capacity - rt_wptr) {
157 uint64_t m = fifo_capacity - rt_wptr;
158 memcpy(rt_to_ui + rt_wptr, buf, m);
159 memcpy(rt_to_ui,
reinterpret_cast<const char*
>(buf) + m, data_size - m);
161 memcpy(rt_to_ui + rt_wptr, buf, data_size);
163 rt_wptr = (rt_wptr + data_size) % fifo_capacity;
164 ui_available_read_bytes = (fifo_capacity + ui_rptr - rt_wptr) % fifo_capacity;
165 this->available_read_cond.notify_one();
166 return static_cast<int64_t
>(data_size);
171 std::unique_lock<std::mutex> lk(this->ui_read_mut);
172 if (ui_available_read_bytes == 0) {
173 this->available_read_cond.wait(
174 lk, [
this]() {
return ui_available_read_bytes != 0 || rt_closed; });
178 void RT::OS::xbuffFifo::flush_buff()
180 this->rt_closed =
true;
181 this->available_read_cond.notify_all();
191 return this->fifo_capacity;
196 auto tmp_fifo = std::make_unique<RT::OS::xbuffFifo>(fifo_size);
197 fifo = std::move(tmp_fifo);
int64_t readRT(void *buf, size_t data_size) override
xbuffFifo & operator=(const xbuffFifo &fifo)=delete
xbuffFifo & operator=(xbuffFifo &&)=default
size_t getCapacity() override
int64_t writeRT(void *buf, size_t data_size) override
int64_t read(void *buf, size_t data_size) override
xbuffFifo(xbuffFifo &&)=default
int64_t write(void *buf, size_t data_size) override
xbuffFifo(const xbuffFifo &fifo)=delete
void ERROR_MSG(const std::string &errmsg, Args... args)
int getFifo(std::unique_ptr< Fifo > &fifo, size_t fifo_size)