comparison packages/kernel/current/src/common/clock.cxx @ 148:8f2f7615e727

Merge from eCos master repository on 2001-01-12-06:43:03-GMT
author jlarmour
date Fri, 12 Jan 2001 08:11:46 +0000
parents 0ae0bc38e387
children 25e238959bae
comparison
equal deleted inserted replaced
147:d397fc472bcf 148:8f2f7615e727
76 { 76 {
77 CYG_REPORT_FUNCTION(); 77 CYG_REPORT_FUNCTION();
78 78
79 counter = 0; 79 counter = 0;
80 increment = incr; 80 increment = incr;
81 #if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST)
82
83 alarm_list = NULL; // Linear list of Alarms
84
85 #elif defined(CYGIMP_KERNEL_COUNTERS_MULTI_LIST)
86
87 for(cyg_ucount32 i=0; i < CYGNUM_KERNEL_COUNTERS_MULTI_LIST_SIZE; i++) {
88 alarm_list[i] = NULL;
89 }
90
91 #else
92 #error "No CYGIMP_KERNEL_COUNTERS_x_LIST config"
93 #endif
94 81
95 } 82 }
96 83
97 // ------------------------------------------------------------------------- 84 // -------------------------------------------------------------------------
98 // Destructor for Counter object 85 // Destructor for Counter object
152 // allowed to wrap. 139 // allowed to wrap.
153 counter += increment; 140 counter += increment;
154 141
155 // now check for any expired alarms 142 // now check for any expired alarms
156 143
157 Cyg_Alarm **alarm_list_ptr; // pointer to list 144 Cyg_Alarm_List *alarm_list_ptr; // pointer to list
158 145
159 #if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST) 146 #if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST)
160 147
161 alarm_list_ptr = &alarm_list; 148 alarm_list_ptr = &alarm_list;
162 149
178 165
179 #ifdef CYGIMP_KERNEL_COUNTERS_SORT_LIST 166 #ifdef CYGIMP_KERNEL_COUNTERS_SORT_LIST
180 167
181 // With a sorted alarm list, we can simply pick alarms off the 168 // With a sorted alarm list, we can simply pick alarms off the
182 // front of the list until we find one that is in the future. 169 // front of the list until we find one that is in the future.
183 170
184 while( *alarm_list_ptr != NULL ) 171 while( !alarm_list_ptr->empty() )
185 { 172 {
186 Cyg_Alarm *alarm = *alarm_list_ptr; 173 Cyg_Alarm *alarm = alarm_list_ptr->get_head();
187 174
188 CYG_ASSERTCLASS(alarm, "Bad alarm in counter list" ); 175 CYG_ASSERTCLASS(alarm, "Bad alarm in counter list" );
189 176
190 if( alarm->trigger <= counter ) 177 if( alarm->trigger <= counter )
191 { 178 {
192 // remove alarm from list 179 // remove alarm from list
193 *alarm_list_ptr = alarm->next; 180 alarm_list_ptr->rem_head();
194 181
195 if( alarm->interval != 0 ) 182 if( alarm->interval != 0 )
196 { 183 {
197 // The alarm has a retrigger interval. 184 // The alarm has a retrigger interval.
198 // Reset the trigger time and requeue 185 // Reset the trigger time and requeue
208 alarm->alarm(alarm, alarm->data); 195 alarm->alarm(alarm, alarm->data);
209 196
210 // all done, loop 197 // all done, loop
211 } 198 }
212 else break; 199 else break;
213 } 200
201 }
214 #else 202 #else
215 203
216 // With an unsorted list, we must scan the whole list for 204 // With an unsorted list, we must scan the whole list for
217 // candidates. We move the whole list to a temporary location 205 // candidates. We move the whole list to a temporary location
218 // before doing this so that we are not disturbed by new 206 // before doing this so that we are not disturbed by new
219 // alarms being added to the list. As we consider and 207 // alarms being added to the list. As we consider and
220 // eliminate alarms we put them onto the done_list and at the 208 // eliminate alarms we put them onto the done_list and at the
221 // end we then move it back to where it belongs. 209 // end we then move it back to where it belongs.
222 210
223 Cyg_Alarm *done_list = NULL; 211 Cyg_Alarm_List done_list;
224 212
225 Cyg_Alarm *alarm_list = *alarm_list_ptr; 213 Cyg_Alarm_List alarm_list;
226 *alarm_list_ptr = NULL; 214
227 215 alarm_list.merge( *alarm_list_ptr );
228 while( alarm_list != NULL ) 216
217 while( !alarm_list.empty() )
229 { 218 {
230 Cyg_Alarm *alarm = alarm_list; 219 Cyg_Alarm *alarm = alarm_list.rem_head();
231 220
232 CYG_ASSERTCLASS(alarm, "Bad alarm in counter list" ); 221 CYG_ASSERTCLASS(alarm, "Bad alarm in counter list" );
233 222
234 // remove alarm from list
235 alarm_list = alarm->next;
236
237 if( alarm->trigger <= counter ) 223 if( alarm->trigger <= counter )
238 { 224 {
239 if( alarm->interval != 0 ) 225 if( alarm->interval != 0 )
240 { 226 {
241 // The alarm has a retrigger interval. 227 // The alarm has a retrigger interval.
254 // all done, loop 240 // all done, loop
255 } 241 }
256 else 242 else
257 { 243 {
258 // add unused alarm to done list. 244 // add unused alarm to done list.
259 alarm->next = done_list; 245 done_list.add_tail(alarm);
260 done_list = alarm;
261 } 246 }
262 } 247 }
263 248
264 // Transfer any alarms that might have been added to the 249 // Return done list to real list. If any alarms have been
265 // alarm list by alarm callbacks to the done list. This 250 // added to the alarm list while we have been scanning then
266 // happens very rarely. 251 // the done list will be added behind them.
267 while( *alarm_list_ptr != NULL ) 252
268 { 253 alarm_list_ptr->merge( done_list );
269 Cyg_Alarm *alarm = *alarm_list_ptr;
270 *alarm_list_ptr = alarm->next;
271 alarm->next = done_list;
272 done_list = alarm;
273 }
274
275 // return done list to real list
276 *alarm_list_ptr = done_list;
277 254
278 #endif 255 #endif
279 Cyg_Scheduler::unlock(); 256 Cyg_Scheduler::unlock();
280 257
281 } 258 }
282 259
283 } 260 }
284 261
332 } 309 }
333 } 310 }
334 311
335 CYG_INSTRUMENT_ALARM( ADD, this, alarm ); 312 CYG_INSTRUMENT_ALARM( ADD, this, alarm );
336 313
337 { 314 // Find the pointer to the relevant list _after_ a retrigger
338 // Find the pointer to the relevant list _after_ a retrigger 315 // alarm has been given its new trigger time.
339 // alarm has been given its new trigger time. 316
340 317 Cyg_Alarm_List *alarm_list_ptr; // pointer to list
341 Cyg_Alarm **alarm_list_ptr; // pointer to list
342 318
343 #if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST) 319 #if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST)
344 320
345 alarm_list_ptr = &alarm_list; 321 alarm_list_ptr = &alarm_list;
346 322
347 #elif defined(CYGIMP_KERNEL_COUNTERS_MULTI_LIST) 323 #elif defined(CYGIMP_KERNEL_COUNTERS_MULTI_LIST)
348 324
349 // Each alarm must go into the list that covers the tick that is 325 // Each alarm must go into the list that covers the tick that is
350 // going to happen _after_ the trigger time (or at it if trigger 326 // going to happen _after_ the trigger time (or at it if trigger
351 // happens to fall on a tick. 327 // happens to fall on a tick.
352 328
353 alarm_list_ptr = &(alarm_list[ 329 alarm_list_ptr = &(alarm_list[
354 ((alarm->trigger+increment-1)/increment) % 330 ((alarm->trigger+increment-1)/increment) %
355 CYGNUM_KERNEL_COUNTERS_MULTI_LIST_SIZE ] ); 331 CYGNUM_KERNEL_COUNTERS_MULTI_LIST_SIZE ] );
356 332
357 #else 333 #else
358 #error "No CYGIMP_KERNEL_COUNTERS_x_LIST config" 334 #error "No CYGIMP_KERNEL_COUNTERS_x_LIST config"
359 #endif 335 #endif
360 336
361 #ifdef CYGIMP_KERNEL_COUNTERS_SORT_LIST 337 #ifdef CYGIMP_KERNEL_COUNTERS_SORT_LIST
362 338
363 // Now that we have the list pointer, we can use common code for 339 // Now that we have the list pointer, we can use common code for
364 // both list oragnizations. 340 // both list oragnizations.
365 341
366 while( *alarm_list_ptr != NULL ) 342 Cyg_Alarm *list_alarm = alarm_list_ptr->get_head();
343
344 if( list_alarm != NULL )
345 do
367 { 346 {
368 Cyg_Alarm *list_alarm = *alarm_list_ptr;
369
370 CYG_ASSERTCLASS(list_alarm, "Bad alarm in counter list" ); 347 CYG_ASSERTCLASS(list_alarm, "Bad alarm in counter list" );
371 348
372 // The alarms are in ascending trigger order. When we 349 // The alarms are in ascending trigger order. When we
373 // find an alarm that is later than us, we go in front of 350 // find an alarm that is later than us, we go in front of
374 // it. 351 // it.
375 352
376 if( list_alarm->trigger > alarm->trigger ) break; 353 if( list_alarm->trigger > alarm->trigger )
377 else alarm_list_ptr = &list_alarm->next; 354 {
378 } 355 alarm_list_ptr->insert( list_alarm, alarm );
379 #endif 356 break;
380 // Insert the new alarm at *alarm_list_ptr 357 }
381 358
382 alarm->next = *alarm_list_ptr; 359 list_alarm = list_alarm->get_next();
383 *alarm_list_ptr = alarm; 360
384 361 } while( list_alarm != alarm_list_ptr->get_head() );
385 Cyg_Scheduler::unlock(); 362
386 } 363 else
364 alarm_list_ptr->add_tail( alarm );
365
366 #else
367
368 alarm_list_ptr->add_tail( alarm );
369
370 #endif
371
372 Cyg_Scheduler::unlock();
387 } 373 }
388 374
389 // ------------------------------------------------------------------------- 375 // -------------------------------------------------------------------------
390 // Remove an alarm from this counter 376 // Remove an alarm from this counter
391 377
394 CYG_REPORT_FUNCTION(); 380 CYG_REPORT_FUNCTION();
395 381
396 CYG_ASSERTCLASS( this, "Bad counter object" ); 382 CYG_ASSERTCLASS( this, "Bad counter object" );
397 CYG_ASSERTCLASS( alarm, "Bad alarm passed" ); 383 CYG_ASSERTCLASS( alarm, "Bad alarm passed" );
398 384
399 Cyg_Alarm **alarm_list_ptr; // pointer to list 385 Cyg_Alarm_List *alarm_list_ptr; // pointer to list
400 386
401 #if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST) 387 #if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST)
402 388
403 alarm_list_ptr = &alarm_list; 389 alarm_list_ptr = &alarm_list;
404 390
416 // both list organizations. 402 // both list organizations.
417 403
418 Cyg_Scheduler::lock(); 404 Cyg_Scheduler::lock();
419 405
420 CYG_INSTRUMENT_ALARM( REM, this, alarm ); 406 CYG_INSTRUMENT_ALARM( REM, this, alarm );
421 407
422 while( *alarm_list_ptr != NULL ) 408 alarm_list_ptr->remove( alarm );
423 { 409
424 Cyg_Alarm *list_alarm = *alarm_list_ptr;
425
426 CYG_ASSERTCLASS(list_alarm, "Bad alarm in counter list" );
427
428 if( list_alarm == alarm ) break;
429 else alarm_list_ptr = &list_alarm->next;
430 }
431
432 // If the alarm was found, remove it from the list.
433 if( *alarm_list_ptr != NULL )
434 {
435 *alarm_list_ptr = alarm->next;
436 alarm->enabled = false;
437 }
438
439 Cyg_Scheduler::unlock(); 410 Cyg_Scheduler::unlock();
440 } 411 }
441 412
442 //========================================================================== 413 //==========================================================================
443 // Constructor for clock object 414 // Constructor for clock object
668 data = d; 639 data = d;
669 trigger = 0; 640 trigger = 0;
670 interval = 0; 641 interval = 0;
671 enabled = false; 642 enabled = false;
672 643
673 #if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST) || defined(CYGIMP_KERNEL_COUNTERS_MULTI_LIST)
674 next = NULL;
675 #endif
676
677 } 644 }
678 645
679 Cyg_Alarm::Cyg_Alarm(){} 646 Cyg_Alarm::Cyg_Alarm(){}
680 647
681 // ------------------------------------------------------------------------- 648 // -------------------------------------------------------------------------