COSA
An Object-Oriented Platform for Arduino Programming
RTT_Scheduler.cpp
Go to the documentation of this file.
1 
21 #include "Cosa/RTT.hh"
22 #include "Cosa/RTT_Config.hh"
23 
24 bool
26 {
27  // Check that the job is not already started
28  if (job->is_started()) return (false);
29 
30  // Check if the job should be run directly
31  uint32_t now = RTT::micros();
32  int32_t diff = job->expire_at() - now;
33  if (diff < US_DIRECT_EXPIRE) {
34  job->on_expired();
35  return (true);
36  }
37 
38  // Check if the job should use the timer match register
39  if (diff < US_TIMER_EXPIRE) {
40  synchronized {
41  if ((s_job == NULL)
42  || ((int32_t) (job->expire_at() - s_job->expire_at()) < 0)) {
43  uint16_t cnt = TCNTn + (diff / US_PER_TIMER_CYCLE);
44  if (cnt > TIMER_MAX) cnt -= TIMER_MAX;
45  OCRnB = cnt;
46  TIMSKn |= _BV(OCIE0B);
47  TIFRn |= _BV(OCF0B);
48  s_job = job;
49  m_queue.succ()->attach(job);
50  return (true);
51  }
52  }
53  }
54 
55  // Insert into the job scheduler queue
56  synchronized {
57  Linkage* succ = &m_queue;
58  Linkage* curr;
59  while ((curr = succ->pred()) != &m_queue) {
60  int32_t diff = ((Job*) curr)->expire_at() - job->expire_at();
61  if (diff < 0) break;
62  succ = curr;
63  }
64  succ->attach(job);
65  }
66  return (true);
67 }
68 
69 void
71 {
72  // Check if there are no jobs
73  if (m_queue.is_empty()) return;
74 
75  // Run all jobs that have expired
76  Job* job = (Job*) m_queue.succ();
77  while ((Linkage*) job != &m_queue) {
78  // Check if the job should be run
79  uint32_t now = RTT::micros();
80  int32_t diff = job->expire_at() - now;
81  if (diff < US_DIRECT_EXPIRE) {
82  Job* succ = (Job*) job->succ();
83  ((Link*) job)->detach();
84  job->on_expired();
85  job = succ;
86  continue;
87  }
88 
89  // Check if the job should use the timer
90  if (diff < US_TIMER_EXPIRE) {
91  // Check that the job will expire before current match
92  if ((s_job == NULL)
93  || ((int32_t) (job->expire_at() - s_job->expire_at()) < 0)) {
94  uint16_t cnt = TCNTn + (diff / US_PER_TIMER_CYCLE);
95  if (cnt > TIMER_MAX) cnt -= TIMER_MAX;
96  OCRnB = cnt;
97  TIMSKn |= _BV(OCIE0B);
98  TIFRn |= _BV(OCF0B);
99  s_job = job;
100  }
101  }
102 
103  // No more jobs to run
104  return;
105  }
106 }
107 
108 uint32_t
110 {
111  return (RTT::micros());
112 }
#define TIMER_MAX
Definition: RTT_Config.hh:27
virtual uint32_t time()
#define NULL
Definition: Types.h:101
Definition: Job.hh:33
#define US_DIRECT_EXPIRE
Definition: RTT_Config.hh:31
static uint32_t micros()
Definition: RTT.cpp:103
virtual bool start(Job *job)
#define US_PER_TIMER_CYCLE
Definition: RTT_Config.hh:28
bool is_started() const
Definition: Job.hh:149
void detach()
Definition: Linkage.hh:100
virtual void on_expired()
Definition: Job.hh:185
virtual void dispatch()
Linkage * succ() const
Definition: Linkage.hh:51
bool is_empty() const
Definition: Linkage.hh:155
static void job(RTT::Scheduler *scheduler)
Definition: RTT.hh:169
Linkage * pred() const
Definition: Linkage.hh:60
Head m_queue
Definition: Job.hh:84
#define US_TIMER_EXPIRE
Definition: RTT_Config.hh:32
void expire_at(uint32_t time)
Definition: Job.hh:102
void attach(Linkage *pred)
Definition: Linkage.hh:71