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. 32extern 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*******************************************************************************/ 44void 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*******************************************************************************/ 89BOOLEAN 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*******************************************************************************/ 137UINT32 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*******************************************************************************/ 160INT32 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*******************************************************************************/ 185void 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*******************************************************************************/ 274void 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*******************************************************************************/ 329void 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*******************************************************************************/ 496void GKI_init_timer_list(TIMER_LIST_Q *timer_q) { 497 timer_q->p_first = NULL; 498 timer_q->p_last = NULL; 499} 500 501bool 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 506TIMER_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. */ 512INT32 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*******************************************************************************/ 535UINT16 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*******************************************************************************/ 592UINT32 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*******************************************************************************/ 638void 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*******************************************************************************/ 699BOOLEAN 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*******************************************************************************/ 775void 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