Mercurial > flash_v2
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 // ------------------------------------------------------------------------- |
