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 *******************************************************************************/
gki_timers_init(void)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 *******************************************************************************/
gki_timers_is_timer_running(void)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 *******************************************************************************/
GKI_get_tick_count(void)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 *******************************************************************************/
GKI_ready_to_sleep(void)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 *******************************************************************************/
GKI_start_timer(UINT8 tnum,INT32 ticks,BOOLEAN is_continuous)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 *******************************************************************************/
GKI_stop_timer(UINT8 tnum)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 *******************************************************************************/
GKI_timer_update(INT32 ticks_since_last_update)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 *******************************************************************************/
GKI_init_timer_list(TIMER_LIST_Q * timer_q)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
GKI_timer_queue_is_empty(const TIMER_LIST_Q * timer_q)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
GKI_timer_getfirst(const TIMER_LIST_Q * timer_q)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. */
GKI_timer_ticks_getinitial(const TIMER_LIST_ENT * tle)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 *******************************************************************************/
GKI_update_timer_list(TIMER_LIST_Q * p_timer_listq,INT32 num_units_since_last_update)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 *******************************************************************************/
GKI_get_remaining_ticks(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_target_tle)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 *******************************************************************************/
GKI_add_to_timer_list(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_tle)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 *******************************************************************************/
GKI_remove_from_timer_list(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_tle)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 *******************************************************************************/
gki_adjust_timer_count(INT32 ticks)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