1 /****************************************************************************** 2 * 3 * Copyright (C) 1999-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 #include <assert.h> 20 #include <utils/Log.h> 21 #include "gki_int.h" 22 23 /* Make sure that this has been defined in target.h */ 24 #ifndef GKI_NUM_TIMERS 25 #error NO TIMERS: Must define at least 1 timer in the system! 26 #endif 27 28 29 #define GKI_NO_NEW_TMRS_STARTED (0x7fffffffL) /* Largest signed positive timer count */ 30 31 // Used for controlling alarms from AlarmService. 32 extern void alarm_service_reschedule(void); 33 34 /******************************************************************************* 35 ** 36 ** Function gki_timers_init 37 ** 38 ** Description This internal function is called once at startup to initialize 39 ** all the timer structures. 40 ** 41 ** Returns void 42 ** 43 *******************************************************************************/ 44 void gki_timers_init(void) 45 { 46 UINT8 tt; 47 48 gki_cb.com.OSTicksTilExp = 0; /* Remaining time (of OSTimeCurTimeout) before next timer expires */ 49 gki_cb.com.OSNumOrigTicks = 0; 50 51 for (tt = 0; tt < GKI_MAX_TASKS; tt++) 52 { 53 gki_cb.com.OSWaitTmr [tt] = 0; 54 55 #if (GKI_NUM_TIMERS > 0) 56 gki_cb.com.OSTaskTmr0 [tt] = 0; 57 gki_cb.com.OSTaskTmr0R [tt] = 0; 58 #endif 59 60 #if (GKI_NUM_TIMERS > 1) 61 gki_cb.com.OSTaskTmr1 [tt] = 0; 62 gki_cb.com.OSTaskTmr1R [tt] = 0; 63 #endif 64 65 #if (GKI_NUM_TIMERS > 2) 66 gki_cb.com.OSTaskTmr2 [tt] = 0; 67 gki_cb.com.OSTaskTmr2R [tt] = 0; 68 #endif 69 70 #if (GKI_NUM_TIMERS > 3) 71 gki_cb.com.OSTaskTmr3 [tt] = 0; 72 gki_cb.com.OSTaskTmr3R [tt] = 0; 73 #endif 74 } 75 76 return; 77 } 78 79 /******************************************************************************* 80 ** 81 ** Function gki_timers_is_timer_running 82 ** 83 ** Description This internal function is called to test if any gki timer are running 84 ** 85 ** 86 ** Returns TRUE if at least one time is running in the system, FALSE else. 87 ** 88 *******************************************************************************/ 89 BOOLEAN gki_timers_is_timer_running(void) 90 { 91 UINT8 tt; 92 for (tt = 0; tt < GKI_MAX_TASKS; tt++) 93 { 94 95 #if (GKI_NUM_TIMERS > 0) 96 if(gki_cb.com.OSTaskTmr0 [tt]) 97 { 98 return TRUE; 99 } 100 #endif 101 102 #if (GKI_NUM_TIMERS > 1) 103 if(gki_cb.com.OSTaskTmr1 [tt] ) 104 { 105 return TRUE; 106 } 107 #endif 108 109 #if (GKI_NUM_TIMERS > 2) 110 if(gki_cb.com.OSTaskTmr2 [tt] ) 111 { 112 return TRUE; 113 } 114 #endif 115 116 #if (GKI_NUM_TIMERS > 3) 117 if(gki_cb.com.OSTaskTmr3 [tt] ) 118 { 119 return TRUE; 120 } 121 #endif 122 } 123 124 return FALSE; 125 126 } 127 128 /******************************************************************************* 129 ** 130 ** Function GKI_get_tick_count 131 ** 132 ** Description This function returns the current system ticks 133 ** 134 ** Returns The current number of system ticks 135 ** 136 *******************************************************************************/ 137 UINT32 GKI_get_tick_count(void) 138 { 139 return gki_cb.com.OSTicks; 140 } 141 142 143 /******************************************************************************* 144 ** 145 ** Function GKI_ready_to_sleep 146 ** 147 ** Description This function returns the number of system ticks until the 148 ** next timer will expire. It is typically called by a power 149 ** savings manager to find out how long it can have the system 150 ** sleep before it needs to service the next entry. 151 ** 152 ** Parameters: None 153 ** 154 ** Returns Number of ticks til the next timer expires 155 ** Note: the value is a signed value. This value should be 156 ** compared to x > 0, to avoid misinterpreting negative tick 157 ** values. 158 ** 159 *******************************************************************************/ 160 INT32 GKI_ready_to_sleep (void) 161 { 162 return (gki_cb.com.OSTicksTilExp); 163 } 164 165 166 /******************************************************************************* 167 ** 168 ** Function GKI_start_timer 169 ** 170 ** Description An application can call this function to start one of 171 ** it's four general purpose timers. Any of the four timers 172 ** can be 1-shot or continuous. If a timer is already running, 173 ** it will be reset to the new parameters. 174 ** 175 ** Parameters tnum - (input) timer number to be started (TIMER_0, 176 ** TIMER_1, TIMER_2, or TIMER_3) 177 ** ticks - (input) the number of system ticks til the 178 ** timer expires. 179 ** is_continuous - (input) TRUE if timer restarts automatically, 180 ** else FALSE if it is a 'one-shot'. 181 ** 182 ** Returns void 183 ** 184 *******************************************************************************/ 185 void GKI_start_timer (UINT8 tnum, INT32 ticks, BOOLEAN is_continuous) 186 { 187 INT32 reload; 188 INT32 orig_ticks; 189 UINT8 task_id = GKI_get_taskid(); 190 BOOLEAN bad_timer = FALSE; 191 192 if (ticks <= 0) 193 ticks = 1; 194 195 orig_ticks = ticks; /* save the ticks in case adjustment is necessary */ 196 197 198 /* If continuous timer, set reload, else set it to 0 */ 199 if (is_continuous) 200 reload = ticks; 201 else 202 reload = 0; 203 204 GKI_disable(); 205 206 /* Add the time since the last task timer update. 207 ** Note that this works when no timers are active since 208 ** both OSNumOrigTicks and OSTicksTilExp are 0. 209 */ 210 if (INT32_MAX - (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) > ticks) 211 { 212 ticks += gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp; 213 } 214 else 215 ticks = INT32_MAX; 216 217 switch (tnum) 218 { 219 #if (GKI_NUM_TIMERS > 0) 220 case TIMER_0: 221 gki_cb.com.OSTaskTmr0R[task_id] = reload; 222 gki_cb.com.OSTaskTmr0 [task_id] = ticks; 223 break; 224 #endif 225 226 #if (GKI_NUM_TIMERS > 1) 227 case TIMER_1: 228 gki_cb.com.OSTaskTmr1R[task_id] = reload; 229 gki_cb.com.OSTaskTmr1 [task_id] = ticks; 230 break; 231 #endif 232 233 #if (GKI_NUM_TIMERS > 2) 234 case TIMER_2: 235 gki_cb.com.OSTaskTmr2R[task_id] = reload; 236 gki_cb.com.OSTaskTmr2 [task_id] = ticks; 237 break; 238 #endif 239 240 #if (GKI_NUM_TIMERS > 3) 241 case TIMER_3: 242 gki_cb.com.OSTaskTmr3R[task_id] = reload; 243 gki_cb.com.OSTaskTmr3 [task_id] = ticks; 244 break; 245 #endif 246 default: 247 bad_timer = TRUE; /* Timer number is bad, so do not use */ 248 } 249 250 /* Update the expiration timeout if a legitimate timer */ 251 if (!bad_timer) 252 { 253 /* Only update the timeout value if it is less than any other newly started timers */ 254 gki_adjust_timer_count (orig_ticks); 255 } 256 257 GKI_enable(); 258 259 } 260 261 /******************************************************************************* 262 ** 263 ** Function GKI_stop_timer 264 ** 265 ** Description An application can call this function to stop one of 266 ** it's four general purpose timers. There is no harm in 267 ** stopping a timer that is already stopped. 268 ** 269 ** Parameters tnum - (input) timer number to be started (TIMER_0, 270 ** TIMER_1, TIMER_2, or TIMER_3) 271 ** Returns void 272 ** 273 *******************************************************************************/ 274 void GKI_stop_timer (UINT8 tnum) 275 { 276 UINT8 task_id = GKI_get_taskid(); 277 278 switch (tnum) 279 { 280 #if (GKI_NUM_TIMERS > 0) 281 case TIMER_0: 282 gki_cb.com.OSTaskTmr0R[task_id] = 0; 283 gki_cb.com.OSTaskTmr0 [task_id] = 0; 284 break; 285 #endif 286 287 #if (GKI_NUM_TIMERS > 1) 288 case TIMER_1: 289 gki_cb.com.OSTaskTmr1R[task_id] = 0; 290 gki_cb.com.OSTaskTmr1 [task_id] = 0; 291 break; 292 #endif 293 294 #if (GKI_NUM_TIMERS > 2) 295 case TIMER_2: 296 gki_cb.com.OSTaskTmr2R[task_id] = 0; 297 gki_cb.com.OSTaskTmr2 [task_id] = 0; 298 break; 299 #endif 300 301 #if (GKI_NUM_TIMERS > 3) 302 case TIMER_3: 303 gki_cb.com.OSTaskTmr3R[task_id] = 0; 304 gki_cb.com.OSTaskTmr3 [task_id] = 0; 305 break; 306 #endif 307 } 308 } 309 310 311 /******************************************************************************* 312 ** 313 ** Function GKI_timer_update 314 ** 315 ** Description This function is called by an OS to drive the GKI's timers. 316 ** It is typically called at every system tick to 317 ** update the timers for all tasks, and check for timeouts. 318 ** 319 ** Note: It has been designed to also allow for variable tick updates 320 ** so that systems with strict power savings requirements can 321 ** have the update occur at variable intervals. 322 ** 323 ** Parameters: ticks_since_last_update - (input) This is the number of TICKS that have 324 ** occurred since the last time GKI_timer_update was called. 325 ** 326 ** Returns void 327 ** 328 *******************************************************************************/ 329 void GKI_timer_update (INT32 ticks_since_last_update) 330 { 331 UINT8 task_id; 332 long next_expiration; /* Holds the next soonest expiration time after this update */ 333 334 /* Increment the number of ticks used for time stamps */ 335 gki_cb.com.OSTicks += ticks_since_last_update; 336 337 /* If any timers are running in any tasks, decrement the remaining time til 338 * the timer updates need to take place (next expiration occurs) 339 */ 340 gki_cb.com.OSTicksTilExp -= ticks_since_last_update; 341 342 /* Don't allow timer interrupt nesting */ 343 if (gki_cb.com.timer_nesting) 344 return; 345 346 gki_cb.com.timer_nesting = 1; 347 348 /* No need to update the ticks if no timeout has occurred */ 349 if (gki_cb.com.OSTicksTilExp > 0) 350 { 351 // When using alarms from AlarmService we should 352 // always have work to be done here. 353 ALOGE("%s no work to be done when expected work", __func__); 354 gki_cb.com.timer_nesting = 0; 355 return; 356 } 357 358 next_expiration = GKI_NO_NEW_TMRS_STARTED; 359 360 /* If here then gki_cb.com.OSTicksTilExp <= 0. If negative, then increase gki_cb.com.OSNumOrigTicks 361 to account for the difference so timer updates below are decremented by the full number 362 of ticks. gki_cb.com.OSNumOrigTicks is reset at the bottom of this function so changing this 363 value only affects the timer updates below 364 */ 365 gki_cb.com.OSNumOrigTicks -= gki_cb.com.OSTicksTilExp; 366 367 /* Protect this section because if a GKI_timer_stop happens between: 368 * - gki_cb.com.OSTaskTmr0[task_id] -= gki_cb.com.OSNumOrigTicks; 369 * - gki_cb.com.OSTaskTmr0[task_id] = gki_cb.com.OSTaskTmr0R[task_id]; 370 * then the timer may appear stopped while it is about to be reloaded. 371 */ 372 GKI_disable(); 373 374 /* Check for OS Task Timers */ 375 for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++) 376 { 377 if (gki_cb.com.OSWaitTmr[task_id] > 0) /* If timer is running */ 378 { 379 gki_cb.com.OSWaitTmr[task_id] -= gki_cb.com.OSNumOrigTicks; 380 if (gki_cb.com.OSWaitTmr[task_id] <= 0) 381 { 382 /* Timer Expired */ 383 gki_cb.com.OSRdyTbl[task_id] = TASK_READY; 384 } 385 } 386 387 #if (GKI_NUM_TIMERS > 0) 388 /* If any timer is running, decrement */ 389 if (gki_cb.com.OSTaskTmr0[task_id] > 0) 390 { 391 gki_cb.com.OSTaskTmr0[task_id] -= gki_cb.com.OSNumOrigTicks; 392 393 if (gki_cb.com.OSTaskTmr0[task_id] <= 0) 394 { 395 /* Reload timer and set Timer 0 Expired event mask */ 396 gki_cb.com.OSTaskTmr0[task_id] = gki_cb.com.OSTaskTmr0R[task_id]; 397 GKI_send_event (task_id, TIMER_0_EVT_MASK); 398 } 399 } 400 401 /* Check to see if this timer is the next one to expire */ 402 if (gki_cb.com.OSTaskTmr0[task_id] > 0 && gki_cb.com.OSTaskTmr0[task_id] < next_expiration) 403 next_expiration = gki_cb.com.OSTaskTmr0[task_id]; 404 #endif 405 406 #if (GKI_NUM_TIMERS > 1) 407 /* If any timer is running, decrement */ 408 if (gki_cb.com.OSTaskTmr1[task_id] > 0) 409 { 410 gki_cb.com.OSTaskTmr1[task_id] -= gki_cb.com.OSNumOrigTicks; 411 412 if (gki_cb.com.OSTaskTmr1[task_id] <= 0) 413 { 414 /* Reload timer and set Timer 1 Expired event mask */ 415 gki_cb.com.OSTaskTmr1[task_id] = gki_cb.com.OSTaskTmr1R[task_id]; 416 GKI_send_event (task_id, TIMER_1_EVT_MASK); 417 } 418 } 419 420 /* Check to see if this timer is the next one to expire */ 421 if (gki_cb.com.OSTaskTmr1[task_id] > 0 && gki_cb.com.OSTaskTmr1[task_id] < next_expiration) 422 next_expiration = gki_cb.com.OSTaskTmr1[task_id]; 423 #endif 424 425 #if (GKI_NUM_TIMERS > 2) 426 /* If any timer is running, decrement */ 427 if (gki_cb.com.OSTaskTmr2[task_id] > 0) 428 { 429 gki_cb.com.OSTaskTmr2[task_id] -= gki_cb.com.OSNumOrigTicks; 430 431 if (gki_cb.com.OSTaskTmr2[task_id] <= 0) 432 { 433 /* Reload timer and set Timer 2 Expired event mask */ 434 gki_cb.com.OSTaskTmr2[task_id] = gki_cb.com.OSTaskTmr2R[task_id]; 435 GKI_send_event (task_id, TIMER_2_EVT_MASK); 436 } 437 } 438 439 /* Check to see if this timer is the next one to expire */ 440 if (gki_cb.com.OSTaskTmr2[task_id] > 0 && gki_cb.com.OSTaskTmr2[task_id] < next_expiration) 441 next_expiration = gki_cb.com.OSTaskTmr2[task_id]; 442 #endif 443 444 #if (GKI_NUM_TIMERS > 3) 445 /* If any timer is running, decrement */ 446 if (gki_cb.com.OSTaskTmr3[task_id] > 0) 447 { 448 gki_cb.com.OSTaskTmr3[task_id] -= gki_cb.com.OSNumOrigTicks; 449 450 if (gki_cb.com.OSTaskTmr3[task_id] <= 0) 451 { 452 /* Reload timer and set Timer 3 Expired event mask */ 453 gki_cb.com.OSTaskTmr3[task_id] = gki_cb.com.OSTaskTmr3R[task_id]; 454 GKI_send_event (task_id, TIMER_3_EVT_MASK); 455 } 456 } 457 458 /* Check to see if this timer is the next one to expire */ 459 if (gki_cb.com.OSTaskTmr3[task_id] > 0 && gki_cb.com.OSTaskTmr3[task_id] < next_expiration) 460 next_expiration = gki_cb.com.OSTaskTmr3[task_id]; 461 #endif 462 463 } 464 /* Set the next timer experation value if there is one to start */ 465 if (next_expiration < GKI_NO_NEW_TMRS_STARTED) 466 { 467 gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = next_expiration; 468 } 469 else 470 { 471 gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = 0; 472 } 473 474 // Set alarm service for next alarm. 475 alarm_service_reschedule(); 476 477 GKI_enable(); 478 479 gki_cb.com.timer_nesting = 0; 480 481 return; 482 } 483 484 /******************************************************************************* 485 ** 486 ** Function GKI_init_timer_list 487 ** 488 ** Description This function is called by applications when they 489 ** want to initialize a timer list. 490 ** 491 ** Parameters p_timer_listq - (input) pointer to the timer list queue object 492 ** 493 ** Returns void 494 ** 495 *******************************************************************************/ 496 void GKI_init_timer_list(TIMER_LIST_Q *timer_q) { 497 timer_q->p_first = NULL; 498 timer_q->p_last = NULL; 499 } 500 501 bool GKI_timer_queue_is_empty(const TIMER_LIST_Q *timer_q) { 502 assert(timer_q != NULL); 503 return (timer_q->p_first == NULL); 504 } 505 506 TIMER_LIST_ENT *GKI_timer_getfirst(const TIMER_LIST_Q *timer_q) { 507 assert(timer_q != NULL); 508 return timer_q->p_first; 509 } 510 511 /* Returns the initial number of ticks for this timer entry. */ 512 INT32 GKI_timer_ticks_getinitial(const TIMER_LIST_ENT *tle) { 513 assert(tle != NULL); 514 return tle->ticks_initial; 515 } 516 517 /******************************************************************************* 518 ** 519 ** Function GKI_update_timer_list 520 ** 521 ** Description This function is called by the applications when they 522 ** want to update a timer list. This should be at every 523 ** timer list unit tick, e.g. once per sec, once per minute etc. 524 ** 525 ** Parameters p_timer_listq - (input) pointer to the timer list queue object 526 ** num_units_since_last_update - (input) number of units since the last update 527 ** (allows for variable unit update) 528 ** 529 ** NOTE: The following timer list update routines should not be used for exact time 530 ** critical purposes. The timer tasks should be used when exact timing is needed. 531 ** 532 ** Returns the number of timers that have expired 533 ** 534 *******************************************************************************/ 535 UINT16 GKI_update_timer_list (TIMER_LIST_Q *p_timer_listq, INT32 num_units_since_last_update) 536 { 537 TIMER_LIST_ENT *p_tle; 538 UINT16 num_time_out = 0; 539 INT32 rem_ticks; 540 INT32 temp_ticks; 541 542 p_tle = p_timer_listq->p_first; 543 544 /* First, get the guys who have previously timed out */ 545 /* Note that the tick value of the timers should always be '0' */ 546 while ((p_tle) && (p_tle->ticks <= 0)) 547 { 548 num_time_out++; 549 p_tle = p_tle->p_next; 550 } 551 552 /* Timer entriy tick values are relative to the preceeding entry */ 553 rem_ticks = num_units_since_last_update; 554 555 /* Now, adjust remaining timer entries */ 556 while ((p_tle != NULL) && (rem_ticks > 0)) 557 { 558 temp_ticks = p_tle->ticks; 559 p_tle->ticks -= rem_ticks; 560 561 /* See if this timer has just timed out */ 562 if (p_tle->ticks <= 0) 563 { 564 /* We set the number of ticks to '0' so that the legacy code 565 * that assumes a '0' or nonzero value will still work as coded. */ 566 p_tle->ticks = 0; 567 568 num_time_out++; 569 } 570 571 rem_ticks -= temp_ticks; /* Decrement the remaining ticks to process */ 572 p_tle = p_tle->p_next; 573 } 574 575 return (num_time_out); 576 } 577 578 /******************************************************************************* 579 ** 580 ** Function GKI_get_remaining_ticks 581 ** 582 ** Description This function is called by an application to get remaining 583 ** ticks to expire 584 ** 585 ** Parameters p_timer_listq - (input) pointer to the timer list queue object 586 ** p_target_tle - (input) pointer to a timer list queue entry 587 ** 588 ** Returns 0 if timer is not used or timer is not in the list 589 ** remaining ticks if success 590 ** 591 *******************************************************************************/ 592 UINT32 GKI_get_remaining_ticks (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT *p_target_tle) 593 { 594 TIMER_LIST_ENT *p_tle; 595 UINT32 rem_ticks = 0; 596 597 if (p_target_tle->in_use) 598 { 599 p_tle = p_timer_listq->p_first; 600 601 /* adding up all of ticks in previous entries */ 602 while ((p_tle)&&(p_tle != p_target_tle)) 603 { 604 rem_ticks += p_tle->ticks; 605 p_tle = p_tle->p_next; 606 } 607 608 /* if found target entry */ 609 if (p_tle == p_target_tle) 610 { 611 rem_ticks += p_tle->ticks; 612 } 613 else 614 { 615 return(0); 616 } 617 } 618 619 return (rem_ticks); 620 } 621 622 /******************************************************************************* 623 ** 624 ** Function GKI_add_to_timer_list 625 ** 626 ** Description This function is called by an application to add a timer 627 ** entry to a timer list. 628 ** 629 ** Note: A timer value of '0' will effectively insert an already 630 ** expired event. Negative tick values will be ignored. 631 ** 632 ** Parameters p_timer_listq - (input) pointer to the timer list queue object 633 ** p_tle - (input) pointer to a timer list queue entry 634 ** 635 ** Returns void 636 ** 637 *******************************************************************************/ 638 void GKI_add_to_timer_list (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT *p_tle) 639 { 640 /* Only process valid tick values. */ 641 if (p_tle->ticks < 0) 642 return; 643 644 p_tle->p_prev = NULL; 645 p_tle->p_next = NULL; 646 p_tle->in_use = true; 647 648 /* Insert at head. */ 649 if (p_timer_listq->p_first == NULL) 650 { 651 p_timer_listq->p_first = p_tle; 652 p_timer_listq->p_last = p_tle; 653 return; 654 } 655 656 /* Find the node before which we need to insert p_tle. */ 657 TIMER_LIST_ENT *i = p_timer_listq->p_first; 658 while (i && p_tle->ticks > i->ticks) 659 { 660 if (i->ticks > 0) 661 p_tle->ticks -= i->ticks; 662 i = i->p_next; 663 } 664 665 /* Insert at tail. */ 666 if (!i) 667 { 668 p_timer_listq->p_last->p_next = p_tle; 669 p_tle->p_prev = p_timer_listq->p_last; 670 p_timer_listq->p_last = p_tle; 671 return; 672 } 673 674 p_tle->p_prev = i->p_prev; 675 if (p_tle->p_prev) 676 p_tle->p_prev->p_next = p_tle; 677 p_tle->p_next = i; 678 i->p_prev = p_tle; 679 i->ticks -= p_tle->ticks; 680 681 if (p_timer_listq->p_first == i) 682 p_timer_listq->p_first = p_tle; 683 } 684 685 686 /******************************************************************************* 687 ** 688 ** Function GKI_remove_from_timer_list 689 ** 690 ** Description This function is called by an application to remove a timer 691 ** entry from a timer list. 692 ** 693 ** Parameters p_timer_listq - (input) pointer to the timer list queue object 694 ** p_tle - (input) pointer to a timer list queue entry 695 ** 696 ** Returns TRUE if the entry has been unlinked successfully 697 ** 698 *******************************************************************************/ 699 BOOLEAN GKI_remove_from_timer_list (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT *p_tle) 700 { 701 UINT8 tt; 702 703 /* Verify that the entry is valid */ 704 if (p_tle == NULL || p_timer_listq->p_first == NULL) 705 return FALSE; 706 707 /* Add the ticks remaining in this timer (if any) to the next guy in the list. 708 ** Note: Expired timers have a tick value of '0'. 709 */ 710 if (p_tle->p_next != NULL) 711 { 712 p_tle->p_next->ticks += p_tle->ticks; 713 } 714 715 p_tle->ticks = 0; 716 p_tle->in_use = FALSE; 717 718 /* Unlink timer from the list. 719 */ 720 if (p_timer_listq->p_first == p_tle) 721 { 722 p_timer_listq->p_first = p_tle->p_next; 723 724 if (p_timer_listq->p_first != NULL) 725 p_timer_listq->p_first->p_prev = NULL; 726 727 if (p_timer_listq->p_last == p_tle) 728 p_timer_listq->p_last = NULL; 729 } 730 else 731 { 732 if (p_timer_listq->p_last == p_tle) 733 { 734 p_timer_listq->p_last = p_tle->p_prev; 735 736 if (p_timer_listq->p_last != NULL) 737 p_timer_listq->p_last->p_next = NULL; 738 } 739 else 740 { 741 if (p_tle->p_next != NULL && p_tle->p_next->p_prev == p_tle) 742 p_tle->p_next->p_prev = p_tle->p_prev; 743 else 744 return FALSE; // Timer list broken?! 745 746 if (p_tle->p_prev != NULL && p_tle->p_prev->p_next == p_tle) 747 p_tle->p_prev->p_next = p_tle->p_next; 748 else 749 return FALSE; // Timer list broken?! 750 } 751 } 752 753 p_tle->p_next = p_tle->p_prev = NULL; 754 return TRUE; 755 } 756 757 758 /******************************************************************************* 759 ** 760 ** Function gki_adjust_timer_count 761 ** 762 ** Description This function is called whenever a new timer or GKI_wait occurs 763 ** to adjust (if necessary) the current time til the first expiration. 764 ** This only needs to make an adjustment if the new timer (in ticks) is 765 ** less than the number of ticks remaining on the current timer. 766 ** 767 ** Parameters: ticks - (input) number of system ticks of the new timer entry 768 ** 769 ** NOTE: This routine MUST be called while interrupts are disabled to 770 ** avoid updates while adjusting the timer variables. 771 ** 772 ** Returns void 773 ** 774 *******************************************************************************/ 775 void gki_adjust_timer_count (INT32 ticks) 776 { 777 if (ticks > 0) 778 { 779 /* See if the new timer expires before the current first expiration */ 780 if (gki_cb.com.OSNumOrigTicks == 0 || (ticks < gki_cb.com.OSTicksTilExp && gki_cb.com.OSTicksTilExp > 0)) 781 { 782 gki_cb.com.OSNumOrigTicks = (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) + ticks; 783 gki_cb.com.OSTicksTilExp = ticks; 784 alarm_service_reschedule(); 785 } 786 } 787 788 return; 789 } 790