RTXI  2.4
The Real-Time eXperiment Interface Documentation
rt.h
Go to the documentation of this file.
1 /*
2  The Real-Time eXperiment Interface (RTXI)
3  Copyright (C) 2011 Georgia Institute of Technology, University of Utah, Weill Cornell Medical College
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18 */
19 
20 #ifndef RT_H
21 #define RT_H
22 
23 #include <fifo.h>
24 #include <mutex.h>
25 #include <pthread.h>
26 #include <semaphore.h>
27 #include <settings.h>
28 
30 
34 namespace RT
35 {
36 
37 namespace OS
38 {
39 
40 typedef void * Task;
41 
42 int initiate(void);
43 void shutdown(void);
44 
45 int createTask(Task *,void *(*)(void *),void *,int =0);
46 void deleteTask(Task);
47 
48 int setPeriod(Task,long long);
49 void sleepTimestep(Task);
50 
51 bool isRealtime(void);
52 
60 long long getTime(void);
61 
72 double getCpuUsage(void);
73 
74 } // namespace OS
75 
82 class Event
83 {
84 
85  friend class System;
86 
87 public:
88 
89  Event(void);
90  virtual ~Event(void);
91 
97  virtual int callback(void)=0;
98 
99 private:
100 
101  void execute(void);
102  void wait(void);
103 
104  int retval;
105  sem_t signal;
106 
107 }; // class Event
108 
109 template<typename T>
110 class List
111 {
112 
113 public:
114 
115  class Node;
116 
117  class iterator
118  {
119 
120  public:
121 
122  iterator(void)
123  : current(0) {};
124  iterator(T *x)
125  : current(static_cast<Node *>(x)) {};
126  iterator(const iterator &x)
127  : current(x.current) {};
128 
129  bool operator==(const iterator &x) const
130  {
131  return current == x.current;
132  };
133  bool operator!=(const iterator &x) const
134  {
135  return current != x.current;
136  };
137 
138  T &operator*(void) const
139  {
140  return *static_cast<T *>(current);
141  };
142  T *operator->(void) const
143  {
144  return static_cast<T *>(current);
145  };
146 
148  {
149  current = current->next;
150  return *this;
151  };
153  {
154  typename RT::List<T>::iterator tmp = *this;
155  current = current->next;
156  return tmp;
157  };
159  {
160  current = current->prev;
161  return *this;
162  };
164  {
165  typename RT::List<T>::iterator tmp = *this;
166  current = current->prev;
167  return tmp;
168  };
169 
170 
171  private:
172 
173  Node *current;
174 
175  }; // class iterator
176 
178  {
179 
180  public:
181 
183  : current(0) {};
184  const_iterator(const T *x)
185  : current(static_cast<const Node *>(x)) {};
187  : current(x.current) {};
188 
189  bool operator==(const const_iterator &x) const
190  {
191  return current == x.current;
192  };
193  bool operator!=(const const_iterator &x) const
194  {
195  return current != x.current;
196  };
197 
198  const T &operator*(void) const
199  {
200  return *static_cast<const T *>(current);
201  };
202  const T *operator->(void) const
203  {
204  return static_cast<const T *>(current);
205  };
206 
208  {
209  current = current->next;
210  return *this;
211  };
213  {
214  typename RT::List<T>::const_iterator tmp = *this;
215  current = current->next;
216  return tmp;
217  };
219  {
220  current = current->prev;
221  return *this;
222  };
224  {
225  typename RT::List<T>::const_iterator tmp = *this;
226  current = current->prev;
227  return tmp;
228  };
229 
230 
231  private:
232 
233  const Node *current;
234 
235  }; // class const_iterator
236 
237  class Node
238  {
239 
240  friend class List<T>;
241  friend class List<T>::iterator;
242  friend class List<T>::const_iterator;
243 
244  public:
245 
246  Node(void)
247  : next(0), prev(0) {};
248  virtual ~Node(void) {};
249 
250  bool operator==(const Node &x) const
251  {
252  return next == x.next && prev == x.prev;
253  };
254 
255  private:
256 
257  Node *next, *prev;
258 
259  }; // class Node
260 
261  List(void)
262  : count(0), head(&tail), tail() {};
263  virtual ~List(void)
264  {
265 #ifdef DEBUG
266  if(tail.next)
267  ERROR_MSG("RT::List::~List : end of list overwritten\n");
268 #endif
269  };
270 
271  size_t size(void) const
272  {
273  return count;
274  };
275  bool empty(void) const
276  {
277  return count==0;
278  };
279 
280  iterator begin(void)
281  {
282  return iterator(static_cast<T *>(head));
283  };
284  iterator end(void)
285  {
286  return iterator(static_cast<T *>(&tail));
287  };
288 
289  const_iterator begin(void) const
290  {
291  return const_iterator(static_cast<const T *>(head));
292  };
293  const_iterator end(void) const
294  {
295  return const_iterator(static_cast<const T *>(&tail));
296  };
297 
298  void insert(iterator,T &);
299  void insertRT(iterator position,T &node)
300  {
301  Node *object = static_cast<Node *>(&node);
302 
303  object->next = &(*position);
304  object->prev = object->next->prev;
305  if(object->next == head)
306  head = object;
307  else
308  position->prev->next = object;
309  position->prev = object;
310  count++;
311  };
312 
313  void remove(T &);
314  void removeRT(T &node)
315  {
316  Node *object = static_cast<Node *>(&node);
317 
318  if(object == &tail)
319  return;
320  if(object == head)
321  head = object->next;
322  else if(object->prev)
323  object->prev->next = object->next;
324  object->next->prev = object->prev;
325  count--;
326  };
327 
328 private:
329 
330  class InsertListNodeEvent : public RT::Event
331  {
332 
333  public:
334 
335  InsertListNodeEvent(List<T> *l,iterator i,T *n)
336  : list(l), iter(i), node(n) {};
337  int callback(void)
338  {
339  list->insertRT(iter,*node);
340  return 0;
341  };
342 
343  private:
344 
345  List<T> *list;
346  typename List<T>::iterator iter;
347  T *node;
348 
349  }; // class InsertListNodeEvent;
350 
351  class RemoveListNodeEvent : public RT::Event
352  {
353 
354  public:
355 
356  RemoveListNodeEvent(List<T> *l,T *n)
357  : list(l), node(n) {};
358  int callback(void)
359  {
360  list->removeRT(*node);
361  return 0;
362  };
363 
364  private:
365 
366  List<T> *list;
367  T *node;
368 
369  }; // class RemoveListNodeEvnet;
370 
371  size_t count;
372  Node *head, tail;
373 
374 }; // class List
375 
376 class Device;
377 class Thread;
378 
383 class System
384 {
385 
386  friend class Device;
387  friend class Thread;
388 
389 public:
390 
397  static System *getInstance(void);
398 
404  long long getPeriod(void) const
405  {
406  return period;
407  };
414  int setPeriod(long long period);
415 
425  void foreachDevice(void (*callback)(Device *,void *),void *param);
435  void foreachThread(void (*callback)(Thread *,void *),void *param);
436 
446  int postEvent(Event *event,bool blocking =true);
447 
454  RT::OS::Task getTask(){ return this->task; }
455 private:
456 
457  /******************************************************************
458  * The constructors, destructor, and assignment operator are made *
459  * private to control instantiation of the class. *
460  ******************************************************************/
461 
462  System(void);
463  ~System(void);
464  System(const System &) : eventFifo(0) {};
465  System &operator=(const System &)
466  {
467  return *getInstance();
468  };
469 
470  class SetPeriodEvent : public RT::Event
471  {
472 
473  public:
474 
475  SetPeriodEvent(long long);
476  ~SetPeriodEvent(void);
477 
478  int callback(void);
479 
480  private:
481 
482  long long period;
483 
484  }; // class SetPeriodEvent
485 
486 
487  static System *instance;
488 
489  Mutex deviceMutex;
490  void insertDevice(Device *);
491  void removeDevice(Device *);
492 
493  Mutex threadMutex;
494  void insertThread(Thread *);
495  void removeThread(Thread *);
496 
497  static void *bounce(void *);
498  void execute(void);
499 
500  bool finished;
501  pthread_t thread;
502  RT::OS::Task task;
503  long long period;
504 
505  List<RT::Device> devices;
506  List<RT::Thread> threadList;
507 
508  Fifo eventFifo;
509 
510 }; // class System
511 
517 class Device : public List<Device>::Node
518 {
519 
520 public:
521 
522  Device(void);
523  virtual ~Device(void);
524 
536  /**********************************************************
537  * read & write must not be pure virtual because they can *
538  * be called during construction and destruction. *
539  **********************************************************/
540 
541  virtual void read(void) {};
542  virtual void write(void) {};
543 
544  inline bool getActive(void) const
545  {
546  return active;
547  };
548  void setActive(bool);
549 
550 private:
551 
552  bool active;
553 
554 }; // class Device
555 
561 class Thread : public List<Thread>::Node
562 {
563 
564 public:
565 
566  typedef unsigned long Priority;
567 
568  static const Priority MinimumPriority = 0;
569  static const Priority MaximumPriority = 100;
571 
573  virtual ~Thread(void);
574 
582  Priority getPriority(void) const
583  {
584  return priority;
585  };
586 
593  /**********************************************************
594  * execute must not be pure virtual because it can be *
595  * called during construction and destruction. *
596  **********************************************************/
597 
598  virtual void execute(void) {};
599 
600  inline bool getActive(void) const
601  {
602  return active;
603  };
604  void setActive(bool);
605 
606 private:
607 
608  bool active;
609  Priority priority;
610 
611 }; // class Thread
612 
613 template<typename T>
614 void List<T>::insert(iterator position,T &node)
615 {
616  InsertListNodeEvent event(this,position,&node);
618 }
619 
620 template<typename T>
621 void List<T>::remove(T &node)
622 {
623  RemoveListNodeEvent event(this,&node);
625 }
626 
627 } // namespace RT
628 
629 #endif // RT_H
RT::List::end
iterator end(void)
Definition: rt.h:284
RT::List::const_iterator::operator--
const_iterator & operator--(void)
Definition: rt.h:218
RT::Event
Definition: rt.h:82
RT::OS::createTask
int createTask(Task *, void *(*)(void *), void *, int=0)
ERROR_MSG
void ERROR_MSG(const std::string &errmsg,...)
Definition: debug.cpp:27
settings.h
RT::List::Node
Definition: rt.h:237
RT::List::const_iterator::operator->
const T * operator->(void) const
Definition: rt.h:202
RT::List::List
List(void)
Definition: rt.h:261
RT::System
Definition: rt.h:383
RT::List::insert
void insert(iterator, T &)
Definition: rt.h:614
RT::List::iterator::iterator
iterator(T *x)
Definition: rt.h:124
RT::OS::deleteTask
void deleteTask(Task)
Definition: rt_os-posix.cpp:126
RT::System::foreachDevice
void foreachDevice(void(*callback)(Device *, void *), void *param)
Definition: rt.cpp:204
RT::System::postEvent
int postEvent(Event *event, bool blocking=true)
Definition: rt.cpp:218
fifo.h
RT::List::iterator::operator++
iterator & operator++(void)
Definition: rt.h:147
RT::Device::read
virtual void read(void)
Definition: rt.h:541
RT::System::foreachThread
void foreachThread(void(*callback)(Thread *, void *), void *param)
Definition: rt.cpp:211
RT::List::const_iterator::const_iterator
const_iterator(const const_iterator &x)
Definition: rt.h:186
RT::List::const_iterator::const_iterator
const_iterator(const T *x)
Definition: rt.h:184
RT::Thread::setActive
void setActive(bool)
Definition: rt.cpp:152
RT::Device::write
virtual void write(void)
Definition: rt.h:542
RT
Realtime Oriented Classes.
Definition: rt.h:34
Event
Event Oriented Classes.
Definition: event.h:35
RT::List::const_iterator::operator--
const_iterator operator--(int)
Definition: rt.h:223
RT::Event::callback
virtual int callback(void)=0
RT::List::begin
iterator begin(void)
Definition: rt.h:280
RT::System::getPeriod
long long getPeriod(void) const
Definition: rt.h:404
RT::List::Node::operator==
bool operator==(const Node &x) const
Definition: rt.h:250
RT::List::iterator::operator==
bool operator==(const iterator &x) const
Definition: rt.h:129
RT::List::remove
void remove(T &)
Definition: rt.h:621
RT::OS::getTime
long long getTime(void)
Definition: rt_os-posix.cpp:143
RT::Thread::~Thread
virtual ~Thread(void)
Definition: rt.cpp:147
RT::Device
Definition: rt.h:517
RT::OS::isRealtime
bool isRealtime(void)
Definition: rt_os-posix.cpp:136
RT::Device::~Device
virtual ~Device(void)
Definition: rt.cpp:125
RT::System::getInstance
static System * getInstance(void)
Definition: rt.cpp:361
RT::List::iterator::iterator
iterator(void)
Definition: rt.h:122
RT::List::const_iterator::operator*
const T & operator*(void) const
Definition: rt.h:198
RT::OS::Task
void * Task
Definition: rt.h:40
RT::Device::getActive
bool getActive(void) const
Definition: rt.h:544
Mutex
Definition: mutex.h:28
RT::OS::sleepTimestep
void sleepTimestep(Task)
Definition: rt_os-posix.cpp:162
RT::List::iterator::operator*
T & operator*(void) const
Definition: rt.h:138
RT::List::begin
const_iterator begin(void) const
Definition: rt.h:289
RT::Thread::MinimumPriority
static const Priority MinimumPriority
Definition: rt.h:568
RT::Event::~Event
virtual ~Event(void)
Definition: rt.cpp:103
RT::List::iterator::operator->
T * operator->(void) const
Definition: rt.h:142
RT::System::getTask
RT::OS::Task getTask()
Definition: rt.h:454
RT::List::empty
bool empty(void) const
Definition: rt.h:275
RT::Thread::Priority
unsigned long Priority
Definition: rt.h:566
RT::List::iterator::operator!=
bool operator!=(const iterator &x) const
Definition: rt.h:133
RT::List::iterator::operator--
iterator & operator--(void)
Definition: rt.h:158
RT::OS::setPeriod
int setPeriod(Task, long long)
Definition: rt_os-posix.cpp:152
RT::List::size
size_t size(void) const
Definition: rt.h:271
RT::List::const_iterator::operator==
bool operator==(const const_iterator &x) const
Definition: rt.h:189
Fifo
Definition: fifo.h:31
RT::Device::Device
Device(void)
Definition: rt.cpp:119
RT::List::const_iterator::operator++
const_iterator & operator++(void)
Definition: rt.h:207
RT::OS::getCpuUsage
double getCpuUsage(void)
Definition: rt_os-posix.cpp:183
RT::List::const_iterator
Definition: rt.h:177
RT::List::const_iterator::operator!=
bool operator!=(const const_iterator &x) const
Definition: rt.h:193
mutex.h
RT::List::iterator::operator++
iterator operator++(int)
Definition: rt.h:152
RT::Thread
Definition: rt.h:561
RT::OS::shutdown
void shutdown(void)
Definition: rt_os-posix.cpp:71
RT::List::~List
virtual ~List(void)
Definition: rt.h:263
RT::Thread::MaximumPriority
static const Priority MaximumPriority
Definition: rt.h:569
RT::Thread::getPriority
Priority getPriority(void) const
Definition: rt.h:582
RT::Thread::getActive
bool getActive(void) const
Definition: rt.h:600
RT::List::insertRT
void insertRT(iterator position, T &node)
Definition: rt.h:299
RT::Event::Event
Event(void)
Definition: rt.cpp:98
RT::List
Definition: rt.h:110
RT::Thread::DefaultPriority
static const Priority DefaultPriority
Definition: rt.h:570
RT::OS::initiate
int initiate(void)
Definition: rt_os-posix.cpp:47
RT::System::setPeriod
int setPeriod(long long period)
Definition: rt.cpp:188
RT::List::const_iterator::operator++
const_iterator operator++(int)
Definition: rt.h:212
RT::List::iterator
Definition: rt.h:117
RT::List::end
const_iterator end(void) const
Definition: rt.h:293
RT::List::iterator::operator--
iterator operator--(int)
Definition: rt.h:163
RT::Thread::execute
virtual void execute(void)
Definition: rt.h:598
RT::List::Node::~Node
virtual ~Node(void)
Definition: rt.h:248
RT::List::iterator::iterator
iterator(const iterator &x)
Definition: rt.h:126
RT::System::Thread
friend class Thread
Definition: rt.h:387
RT::List::removeRT
void removeRT(T &node)
Definition: rt.h:314
RT::Device::setActive
void setActive(bool)
Definition: rt.cpp:130
RT::List::const_iterator::const_iterator
const_iterator(void)
Definition: rt.h:182
RT::Thread::Thread
Thread(Priority p=DefaultPriority)
Definition: rt.cpp:141
RT::System::Device
friend class Device
Definition: rt.h:386