RTXI  3.0.0
The Real-Time eXperiment Interface Reference Manual
fifo_evl.cpp
Go to the documentation of this file.
1 
2 
3 #include "fifo.hpp"
4 
5 #include <errno.h>
6 #include <evl/evl.h>
7 #include <poll.h>
8 #include <string.h>
9 #include <sys/eventfd.h>
10 #include <sys/poll.h>
11 #include <unistd.h>
12 
13 #include "debug.hpp"
14 
15 int FIFO_COUNT = 0;
16 
17 // First let's define an evl specific Fifo class.
18 namespace RT::OS
19 {
20 class evlFifo : public Fifo
21 {
22 public:
23  explicit evlFifo(size_t size);
24  evlFifo(const evlFifo& fifo) = delete; // copy constructor
25  evlFifo& operator=(const evlFifo& fifo) = delete; // copy assignment operator
26  evlFifo(evlFifo&&) = default; // move constructor
27  evlFifo& operator=(evlFifo&&) = default; // move assignment operator
28  ~evlFifo() override;
29 
30  int buffer_fd() const;
31  int64_t read(void* buf, size_t buf_size) override;
32  int64_t write(void* buf, size_t buf_size) override;
33  int64_t readRT(void* buf, size_t buf_size) override;
34  int64_t writeRT(void* buf, size_t buf_size) override;
35  void poll() override;
36  void close() override;
37  size_t getCapacity() override;
38 
39 private:
40  int xbuf_fd;
41  int close_event_fd;
42  size_t fifo_capacity;
43  std::array<struct pollfd, 2> xbuf_poll_fd {};
44  bool closed = false;
45 };
46 } // namespace RT::OS
47 
49  : fifo_capacity(size)
50 {
51  this->xbuf_fd = evl_create_xbuf(fifo_capacity,
52  fifo_capacity,
53  EVL_CLONE_PRIVATE | EVL_CLONE_NONBLOCK,
54  "RTXI Fifo %d",
55  FIFO_COUNT++);
56  if (this->xbuf_fd <= 0) {
57  ERROR_MSG("RT::OS::FIFO(evl) : Unable to create real-time buffer\n");
58  ERROR_MSG("evl core : {}", strerror(this->xbuf_fd));
59  return;
60  }
61  this->xbuf_poll_fd[0].fd = this->xbuf_fd;
62  this->xbuf_poll_fd[0].events = POLLIN;
63  this->close_event_fd = eventfd(0, EFD_NONBLOCK);
64  this->xbuf_poll_fd[1].fd = this->close_event_fd;
65  this->xbuf_poll_fd[1].events = POLLIN;
66 }
67 
69 {
70  ::close(this->xbuf_fd);
71 }
72 
73 int64_t RT::OS::evlFifo::read(void* buf, size_t buf_size)
74 {
75  // We need to specify to compiler that we are using read from c lib
76  return ::read(this->xbuf_fd, buf, buf_size);
77 }
78 
79 int64_t RT::OS::evlFifo::write(void* buf, size_t buf_size)
80 {
81  // we need to specify to compiler that we are using write from c lib
82  return ::write(this->xbuf_fd, buf, buf_size);
83 }
84 
85 int64_t RT::OS::evlFifo::readRT(void* buf, size_t buf_size)
86 {
87  return oob_read(this->xbuf_fd, buf, buf_size);
88 }
89 
90 int64_t RT::OS::evlFifo::writeRT(void* buf, size_t buf_size)
91 {
92  return oob_write(this->xbuf_fd, buf, buf_size);
93 }
94 
96 {
97  int errcode = ::poll(this->xbuf_poll_fd.data(), 2, -1);
98  if (errcode < 0) {
99  ERROR_MSG("RT::OS::FIFO(evl)::poll : returned with failure code {} : ",
100  errcode);
101  ERROR_MSG("{}", strerror(errcode));
102  } else if ((this->xbuf_poll_fd[1].revents & POLLIN) != 0) {
103  this->closed = true;
104  }
105 }
106 
108 {
109  return this->xbuf_fd;
110 }
111 
113 {
114  std::array<int64_t, 1> buf {};
115  buf[0] = 1;
116  ::write(this->close_event_fd, buf.data(), sizeof(int64_t));
117 }
118 
120 {
121  return this->fifo_capacity;
122 }
123 
124 int RT::OS::getFifo(std::unique_ptr<Fifo>& fifo, size_t fifo_size)
125 {
126  int init_state = 0;
127  auto tmp_fifo = std::make_unique<RT::OS::evlFifo>(fifo_size);
128  if (tmp_fifo->buffer_fd() < 0) {
129  init_state = tmp_fifo->buffer_fd();
130  ERROR_MSG("RT::OS::getFifo(EVL) : {}", strerror(errno));
131  } else {
132  fifo = std::move(tmp_fifo);
133  }
134  return init_state;
135 }
int buffer_fd() const
Definition: fifo_evl.cpp:107
int64_t writeRT(void *buf, size_t buf_size) override
Definition: fifo_evl.cpp:90
size_t getCapacity() override
Definition: fifo_evl.cpp:119
void poll() override
Definition: fifo_evl.cpp:95
int64_t readRT(void *buf, size_t buf_size) override
Definition: fifo_evl.cpp:85
evlFifo & operator=(const evlFifo &fifo)=delete
~evlFifo() override
Definition: fifo_evl.cpp:68
evlFifo(const evlFifo &fifo)=delete
void close() override
Definition: fifo_evl.cpp:112
int64_t write(void *buf, size_t buf_size) override
Definition: fifo_evl.cpp:79
evlFifo & operator=(evlFifo &&)=default
evlFifo(size_t size)
Definition: fifo_evl.cpp:48
int64_t read(void *buf, size_t buf_size) override
Definition: fifo_evl.cpp:73
evlFifo(evlFifo &&)=default
void ERROR_MSG(const std::string &errmsg, Args... args)
Definition: debug.hpp:36
int FIFO_COUNT
Definition: fifo_evl.cpp:15
Definition: fifo.cpp:31
int getFifo(std::unique_ptr< Fifo > &fifo, size_t fifo_size)
Definition: fifo.cpp:194