Pol  Revision:cb584c9
schedule.cpp
Go to the documentation of this file.
1 
7 #include "schedule.h"
8 
9 #include <ctime>
10 
11 #include "../clib/logfacility.h"
12 #include "../clib/passert.h"
13 #include "../clib/tracebuf.h"
14 #include "../plib/systemstate.h"
15 #include "globals/state.h"
16 #include "globals/uvars.h"
17 #include "polclock.h"
18 #include "polsig.h"
19 #include "profile.h"
20 
21 namespace Pol
22 {
23 namespace Core
24 {
25 bool SchComparer::operator()( const ScheduledTask* x, const ScheduledTask* y ) const
26 {
27  if ( x->next_run_clock_ == y->next_run_clock_ )
28  return x > y;
29  else
30  return x->next_run_clock_ > y->next_run_clock_;
31 }
32 
33 bool TaskScheduler::dirty_ = false;
34 
35 static void add_task( ScheduledTask* task )
36 {
38  gamestate.task_queue.push( task );
39 }
40 
42  : cancelled( false ), next_run_clock_( next_run_clock ), last_run_clock_( 0 )
43 {
44 }
45 
47 
49 {
50  cancelled = true;
51 }
52 
53 inline bool ScheduledTask::ready( polclock_t now_clock )
54 {
55  return ( now_clock >= next_run_clock_ );
56 }
57 inline bool ScheduledTask::late( polclock_t now_clock )
58 {
59  return ( now_clock > next_run_clock_ );
60 }
62 {
63  return ( now_clock - next_run_clock_ );
64 }
65 
67 {
68  return next_run_clock_ - now_clock;
69 }
70 
71 PeriodicTask::PeriodicTask( void ( *i_f )( void ), int initial_wait_seconds, const char* name )
72  : ScheduledTask( 0 ),
73  n_initial_clocks( initial_wait_seconds * POLCLOCKS_PER_SEC ),
74  n_clocks( initial_wait_seconds * POLCLOCKS_PER_SEC ),
75  f( i_f ),
76  name_( name )
77 {
78 }
79 
80 PeriodicTask::PeriodicTask( void ( *i_f )( void ), int initial_wait_seconds, int periodic_seconds,
81  const char* name )
82  : ScheduledTask( 0 ),
83  n_initial_clocks( initial_wait_seconds * POLCLOCKS_PER_SEC ),
84  n_clocks( periodic_seconds * POLCLOCKS_PER_SEC ),
85  f( i_f ),
86  name_( name )
87 {
88 }
89 
90 
91 void PeriodicTask::set_secs( int n_secs )
92 {
93  n_clocks = n_secs * POLCLOCKS_PER_SEC;
95 }
97 {
99  last_run_clock_ = 0;
100  add_task( this );
101 }
102 
103 /*
104 int PeriodicTask::ready(time_t now)
105 {
106 return (now >= next_run);
107 }
108 */
110 {
111  last_run_clock_ = now;
113 
114  /*
115  cout << name_ << ": last=" << last_run_clock_
116  << ", next=" << next_run_clock_
117  << ", n_clocks=" << n_clocks
118  << ", now=" << now
119  << endl;
120  */
121 
122  ( *f )();
123 }
124 
126  : ScheduledTask( run_when_clock ), handle( handle )
127 {
128  if ( handle != nullptr )
129  {
130  passert( *handle == nullptr );
131  *handle = this;
132  }
133 
134  add_task( this );
135 }
136 
138 {
139  if ( handle != nullptr )
140  *handle = nullptr;
141 }
142 
144 {
146  if ( handle != nullptr )
147  *handle = nullptr;
148  handle = nullptr;
149 }
150 void OneShotTask::execute( polclock_t /*now_clock*/ )
151 {
152  if ( !cancelled )
153  {
154  cancel();
155  on_run();
156  }
157 }
158 
159 /*void check_scheduled_tasks( void )
160 {
161 unsigned idx;
162 unsigned count;
163 time_t now;
164 
165 if (p_task_list)
166 {
167 now = poltime(nullptr);
168 count = p_task_list->count();
169 for( idx = 0; idx < count; idx++ )
170 {
171 ScheduledTask *task = (*p_task_list)[idx];
172 if (task->ready(now))
173 {
174 task->execute(now);
175 }
176 
177 if (task->cancelled)
178 {
179 p_task_list->remove( idx );
180 delete task;
181 }
182 }
183 }
184 }
185 */
186 void check_scheduled_tasks( polclock_t* clocksleft, bool* pactivity )
187 {
188  THREAD_CHECKPOINT( tasks, 101 );
190 
191  polclock_t now_clock = polclock();
192  TRACEBUF_ADDELEM( "check_scheduled_tasks now_clock", now_clock );
193  bool activity = false;
194  passert( !gamestate.task_queue.empty() );
195  THREAD_CHECKPOINT( tasks, 102 );
196  for ( ;; )
197  {
198  THREAD_CHECKPOINT( tasks, 103 );
199  ScheduledTask* task = gamestate.task_queue.top();
200  passert_paranoid( task != nullptr );
201  TRACEBUF_ADDELEM( "check_scheduled_tasks toptask->nextrun", task->next_run_clock() );
202  THREAD_CHECKPOINT( tasks, 104 );
203  if ( !task->ready( now_clock ) )
204  {
205  *clocksleft = task->clocksleft( now_clock );
206  *pactivity = activity;
207  TRACEBUF_ADDELEM( "check_scheduled_tasks clocksleft", *clocksleft );
208  return;
209  }
210 
211  THREAD_CHECKPOINT( tasks, 105 );
212  if ( !task->late( now_clock ) )
213  {
214  INC_PROFILEVAR( tasks_ontime );
215  }
216  else
217  {
218  INC_PROFILEVAR( tasks_late );
219  INC_PROFILEVAR_BY( tasks_late_ticks, task->ticks_late( now_clock ) );
220  }
221 
222  THREAD_CHECKPOINT( tasks, 106 );
223  gamestate.task_queue.pop();
224 
225  THREAD_CHECKPOINT( tasks, 107 );
226  task->execute( now_clock );
227  THREAD_CHECKPOINT( tasks, 108 );
228 
229  activity = true;
230 
231  if ( task->cancelled )
232  {
233  THREAD_CHECKPOINT( tasks, 109 );
234  delete task;
235  }
236  else
237  {
238  THREAD_CHECKPOINT( tasks, 110 );
239  gamestate.task_queue.push( task );
240  }
241  THREAD_CHECKPOINT( tasks, 111 );
242  }
243 }
244 
246 {
247  ScheduledTask* task = gamestate.task_queue.top();
248  if ( !task->ready( now ) )
249  {
250  INFO_PRINT_TRACE( 20 ) << "Task " << (long long)( reinterpret_cast<const void*>( task ) )
251  << ": " << task->clocksleft( now ) << " clocks left\n";
252  return task->clocksleft( now );
253  }
254  else
255  {
256  return 0; // it's ready now!
257  }
258 }
259 }
260 }
polclock_t last_run_clock_
Definition: schedule.h:59
virtual void cancel(void)
Definition: schedule.cpp:48
OneShotTask(OneShotTask **handle, polclock_t run_when)
Definition: schedule.cpp:125
virtual void execute(polclock_t now) POL_OVERRIDE
Definition: schedule.cpp:109
TaskQueue task_queue
Definition: uvars.h:230
friend void check_scheduled_tasks(polclock_t *clocksleft, bool *pactivity)
Definition: schedule.cpp:186
polclock_t next_run_clock_
Definition: schedule.h:58
polclock_t polclock()
Definition: polclock.cpp:72
#define THREAD_CHECKPOINT(thread, check)
Definition: polsig.h:48
#define TRACEBUF_ADDELEM(tag, value)
Definition: tracebuf.h:45
virtual void execute(polclock_t now)=0
#define INC_PROFILEVAR_BY(counter, amount)
Definition: profile.h:87
polclock_t clocksleft(polclock_t now)
Definition: schedule.cpp:66
bool operator()(const ScheduledTask *x, const ScheduledTask *y) const
Definition: schedule.cpp:25
virtual void cancel(void) POL_OVERRIDE
Definition: schedule.cpp:143
const char * name_
Definition: schedule.h:92
OneShotTask ** handle
Definition: schedule.h:109
ScheduledTask(polclock_t next_run_clock)
Definition: schedule.cpp:41
polclock_t next_run_clock() const
Definition: schedule.h:66
void set_secs(int n_secs)
Definition: schedule.cpp:91
bool ready(polclock_t now)
Definition: schedule.cpp:53
#define passert(exp)
Definition: passert.h:62
polclock_t n_clocks
Definition: schedule.h:90
polclock_t n_initial_clocks
Definition: schedule.h:89
int polclock_t
Definition: polclock.h:26
GameState gamestate
Definition: uvars.cpp:74
int polticks_t
Definition: polclock.h:27
PeriodicTask(void(*f)(void), int n_secs, const char *name)
Definition: schedule.cpp:71
friend polclock_t calc_scheduler_clocksleft(polclock_t now)
Definition: schedule.cpp:245
virtual void on_run()=0
polticks_t ticks_late(polclock_t now)
Definition: schedule.cpp:61
#define INFO_PRINT_TRACE(n)
Definition: logfacility.h:226
static bool dirty_
Definition: schedule.h:36
std::string name
Definition: osmod.cpp:943
#define passert_paranoid(exp)
Definition: passert.h:95
static void cleanse()
Definition: schedule.h:32
virtual void execute(polclock_t now) POL_OVERRIDE
Definition: schedule.cpp:150
Definition: berror.cpp:12
const polclock_t POLCLOCKS_PER_SEC
Definition: polclock.h:29
bool late(polclock_t now)
Definition: schedule.cpp:57
void(* f)(void)
Definition: schedule.h:91
static void add_task(ScheduledTask *task)
Definition: schedule.cpp:35
static void mark_dirty()
Definition: schedule.h:33
#define INC_PROFILEVAR(counter)
Definition: profile.h:85