COSA
An Object-Oriented Platform for Arduino Programming
ProtoThread.hh
Go to the documentation of this file.
1 
21 #ifndef COSA_PROTO_THREAD_HH
22 #define COSA_PROTO_THREAD_HH
23 
24 #include "Cosa/Job.hh"
25 #include "Cosa/Event.hh"
26 
52 class ProtoThread : public Job {
53 public:
57  enum {
58  INITIATED = 0,
64  TERMINATED = 0xff,
65  } __attribute__((packed));
66 
73  Job(scheduler),
75  m_ip(0)
76  {}
77 
83  bool begin()
84  {
85  if (UNLIKELY(m_state != INITIATED)) return (false);
86  schedule(this);
87  return (true);
88  }
89 
94  void end()
95  {
97  detach();
98  }
99 
104  uint8_t state() const
105  {
106  return (m_state);
107  }
108 
114  void set_timer(uint16_t ms)
115  __attribute__((always_inline))
116  {
117  m_state = WAITING;
118  detach();
119  expire_after(ms);
120  start();
121  }
122 
127  __attribute__((always_inline))
128  {
129  detach();
130  }
131 
136  bool timer_expired() const
137  __attribute__((always_inline))
138  {
139  return (m_state == TIMEOUT);
140  }
141 
160  virtual void on_run(uint8_t type, uint16_t value) = 0;
161 
170  static uint16_t dispatch(bool flag = true);
171 
177  static void schedule(ProtoThread* thread);
178 
179 protected:
180  static Head runq;
181  uint8_t m_state;
182  void* m_ip;
183 
191  virtual void on_event(uint8_t type, uint16_t value);
192 };
193 
198 #define PROTO_THREAD_BEGIN() \
199  if (m_ip != 0) goto *m_ip
200 
205 #define PROTO_THREAD_YIELD() \
206  do { \
207  __label__ next; \
208  m_ip = &&next; \
209  return; \
210  next: ; \
211  } while (0)
212 
217 #define PROTO_THREAD_SLEEP() \
218  do { \
219  m_state = SLEEPING; \
220  detach(); \
221  PROTO_THREAD_YIELD(); \
222  } while (0)
223 
228 #define PROTO_THREAD_WAKE(thread) \
229  do { \
230  if (thread->m_state == SLEEPING) \
231  Thread::schedule(thread); \
232  } while (0)
233 
240 #define PROTO_THREAD_AWAIT(condition) \
241  do { \
242  __label__ next; \
243  next: \
244  if (!(condition)) { \
245  m_ip = &&next; \
246  return; \
247  } \
248  } while (0)
249 
255 #define PROTO_THREAD_DELAY(ms) \
256  do { \
257  set_timer(ms); \
258  PROTO_THREAD_AWAIT(timer_expired()); \
259  } while (0)
260 
265 #define PROTO_THREAD_END() \
266  do { \
267  ProtoThread::end(); \
268  return; \
269  } while (0)
270 
271 #endif
272 
uint8_t state() const
Definition: ProtoThread.hh:104
static void schedule(ProtoThread *thread)
Definition: ProtoThread.cpp:78
bool timer_expired() const
Definition: ProtoThread.hh:136
int32_t expire_after() const
Definition: Job.hh:129
Definition: Job.hh:33
void end()
Definition: ProtoThread.hh:94
void cancel_timer()
Definition: ProtoThread.hh:126
Detached. Need wakeup call.
Definition: ProtoThread.hh:63
Removed from all queues.
Definition: ProtoThread.hh:64
In timer queue.
Definition: ProtoThread.hh:60
bool begin()
Definition: ProtoThread.hh:83
In run queue.
Definition: ProtoThread.hh:59
uint8_t m_state
Definition: ProtoThread.hh:181
Dispatched and running.
Definition: ProtoThread.hh:62
static uint16_t dispatch(bool flag=true)
Definition: ProtoThread.cpp:41
bool start()
Definition: Job.hh:159
Timeout received and running.
Definition: ProtoThread.hh:61
virtual void on_event(uint8_t type, uint16_t value)
Definition: ProtoThread.cpp:27
#define UNLIKELY(x)
Definition: Types.h:153
Definition: Linkage.hh:132
static Head runq
Definition: ProtoThread.hh:180
void set_timer(uint16_t ms)
Definition: ProtoThread.hh:114
virtual void on_run(uint8_t type, uint16_t value)=0
ProtoThread(Job::Scheduler *scheduler)
Definition: ProtoThread.hh:72