COSA
An Object-Oriented Platform for Arduino Programming
Thread.cpp
Go to the documentation of this file.
1 
21 #include "Thread.hh"
22 #include "Cosa/Watchdog.hh"
23 #include "Cosa/Power.hh"
24 #include <alloca.h>
25 
26 static void thread_delay(uint32_t ms)
27 {
29 }
30 
31 static void thread_yield()
32 {
34 }
35 
36 static void thread_sleep(uint16_t s)
37 {
38  Nucleo::Thread::running()->delay(s * 1000L);
39 }
40 
41 using namespace Nucleo;
42 
45 Thread* Thread::s_running = &s_main;
46 size_t Thread::s_top = MAIN_STACK_MAX;
47 
48 void
49 Thread::init(void* stack)
50 {
51  UNUSED(stack);
52  s_main.attach(this);
53  if (setjmp(m_context)) while (1) run();
54 }
55 
56 void
57 Thread::begin(Thread* thread, size_t size)
58 {
59  if (thread != NULL) {
60  void* stack = alloca(s_top);
61  s_top += size;
62  thread->init(stack);
63  }
64  else {
68  }
69 }
70 
71 void
73 {
74  Thread* thread;
75  if (!s_delayed.is_empty()) {
76  uint32_t now = Watchdog::millis();
77  while ((thread = (Thread*) s_delayed.succ()) != (Thread*) &s_delayed) {
78  if (thread->m_expires > now) break;
79  this->attach(thread);
80  }
81  }
82  thread = (Thread*) succ();
83  if (thread != this)
84  resume(thread);
85  else
86  Power::sleep();
87 }
88 
89 void
91 {
92  if (setjmp(m_context)) return;
93  s_running = thread;
94  longjmp(thread->m_context, 1);
95 }
96 
97 void
98 Thread::enqueue(Head* queue, Thread* thread)
99 {
100  if (thread == NULL)
101  thread = (Thread*) succ();
102  queue->attach(this);
103  resume(thread);
104 }
105 
106 void
107 Thread::dequeue(Head* queue, bool flag)
108 {
109  if (UNLIKELY(queue->is_empty())) return;
110  Thread* thread = (Thread*) queue->succ();
111  if (flag) {
112  attach(thread);
113  resume(thread);
114  }
115  else {
116  succ()->attach(thread);
117  }
118 }
119 
120 void
121 Thread::delay(uint32_t ms)
122 {
123  m_expires = Watchdog::millis() + ms;
124  Thread* thread = (Thread*) s_delayed.succ();
125  while (thread != (Thread*) &s_delayed) {
126  if (thread->m_expires > m_expires) break;
127  thread = (Thread*) thread->succ();
128  }
129  enqueue((Head*) thread);
130 }
131 
132 void
134 {
135  s_main.run();
136 }
Definition: Actor.hh:26
static uint32_t millis()
Definition: Watchdog.hh:51
void dequeue(Head *queue, bool flag=true)
Definition: Thread.cpp:107
void delay(uint32_t ms)
Definition: Thread.cpp:121
#define NULL
Definition: Types.h:101
static void begin(Thread *thread=NULL, size_t size=0)
Definition: Thread.cpp:57
static Head s_delayed
Definition: Thread.hh:118
jmp_buf m_context
Definition: Thread.hh:130
void init(void *stack)
Definition: Thread.cpp:49
static void service()
Definition: Thread.cpp:133
static Thread * running()
Definition: Thread.hh:39
static void sleep(uint8_t mode=POWER_SLEEP_MODE)
Definition: Power.cpp:30
uint32_t m_expires
Definition: Thread.hh:133
static Thread s_main
Definition: Thread.hh:121
#define UNUSED(x)
Definition: ATmega328P.hh:31
static void thread_sleep(uint16_t s)
Definition: Thread.cpp:36
void resume(Thread *thread)
Definition: Thread.cpp:90
void(* sleep)(uint16_t s)
void enqueue(Head *queue, Thread *thread=NULL)
Definition: Thread.cpp:98
void yield()
Definition: Thread.hh:75
virtual void run()
Definition: Thread.cpp:72
Linkage * succ() const
Definition: Linkage.hh:51
bool is_empty() const
Definition: Linkage.hh:155
static Thread * s_running
Definition: Thread.hh:124
static void thread_delay(uint32_t ms)
Definition: Thread.cpp:26
static void thread_yield()
Definition: Thread.cpp:31
#define UNLIKELY(x)
Definition: Types.h:153
static size_t s_top
Definition: Thread.hh:127
Definition: Linkage.hh:132
void attach(Linkage *pred)
Definition: Linkage.hh:71