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 #include <android-base/logging.h>
19 #include <android-base/stringprintf.h>
20
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 /* Largest signed positive timer count */
29 #define GKI_NO_NEW_TMRS_STARTED (0x7fffffffL)
30 /* Marks an unused timer list entry (initial value) */
31 #define GKI_UNUSED_LIST_ENTRY (0x80000000L)
32 #define GKI_MAX_INT32 (0x7fffffffL)
33
34 using android::base::StringPrintf;
35
36 /*******************************************************************************
37 **
38 ** Function gki_timers_init
39 **
40 ** Description This internal function is called once at startup to
41 ** initialize all the timer structures.
42 **
43 ** Returns void
44 **
45 *******************************************************************************/
gki_timers_init(void)46 void gki_timers_init(void) {
47 uint8_t tt;
48
49 gki_cb.com.OSTicksTilExp =
50 0; /* Remaining time (of OSTimeCurTimeout) before next timer expires */
51 gki_cb.com.OSNumOrigTicks = 0;
52 #if (GKI_DELAY_STOP_SYS_TICK > 0)
53 gki_cb.com.OSTicksTilStop = 0; /* clear inactivity delay timer */
54 #endif
55
56 for (tt = 0; tt < GKI_MAX_TASKS; tt++) {
57 gki_cb.com.OSWaitTmr[tt] = 0;
58
59 #if (GKI_NUM_TIMERS > 0)
60 gki_cb.com.OSTaskTmr0[tt] = 0;
61 gki_cb.com.OSTaskTmr0R[tt] = 0;
62 #endif
63
64 #if (GKI_NUM_TIMERS > 1)
65 gki_cb.com.OSTaskTmr1[tt] = 0;
66 gki_cb.com.OSTaskTmr1R[tt] = 0;
67 #endif
68
69 #if (GKI_NUM_TIMERS > 2)
70 gki_cb.com.OSTaskTmr2[tt] = 0;
71 gki_cb.com.OSTaskTmr2R[tt] = 0;
72 #endif
73
74 #if (GKI_NUM_TIMERS > 3)
75 gki_cb.com.OSTaskTmr3[tt] = 0;
76 gki_cb.com.OSTaskTmr3R[tt] = 0;
77 #endif
78 }
79
80 for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
81 gki_cb.com.timer_queues[tt] = nullptr;
82 }
83
84 gki_cb.com.p_tick_cb = nullptr;
85 gki_cb.com.system_tick_running = false;
86
87 return;
88 }
89
90 /*******************************************************************************
91 **
92 ** Function gki_timers_is_timer_running
93 **
94 ** Description This internal function is called to test if any gki timer
95 ** are running
96 **
97 **
98 ** Returns TRUE if at least one time is running in the system, FALSE
99 ** else.
100 **
101 *******************************************************************************/
gki_timers_is_timer_running(void)102 bool gki_timers_is_timer_running(void) {
103 uint8_t tt;
104 for (tt = 0; tt < GKI_MAX_TASKS; tt++) {
105 #if (GKI_NUM_TIMERS > 0)
106 if (gki_cb.com.OSTaskTmr0[tt]) {
107 return true;
108 }
109 #endif
110
111 #if (GKI_NUM_TIMERS > 1)
112 if (gki_cb.com.OSTaskTmr1[tt]) {
113 return true;
114 }
115 #endif
116
117 #if (GKI_NUM_TIMERS > 2)
118 if (gki_cb.com.OSTaskTmr2[tt]) {
119 return true;
120 }
121 #endif
122
123 #if (GKI_NUM_TIMERS > 3)
124 if (gki_cb.com.OSTaskTmr3[tt]) {
125 return true;
126 }
127 #endif
128 }
129
130 return false;
131 }
132
133 /*******************************************************************************
134 **
135 ** Function GKI_get_tick_count
136 **
137 ** Description This function returns the current system ticks
138 **
139 ** Returns The current number of system ticks
140 **
141 *******************************************************************************/
GKI_get_tick_count(void)142 uint32_t GKI_get_tick_count(void) { return gki_cb.com.OSTicks; }
143
144 /*******************************************************************************
145 **
146 ** Function GKI_ready_to_sleep
147 **
148 ** Description This function returns the number of system ticks until the
149 ** next timer will expire. It is typically called by a power
150 ** savings manager to find out how long it can have the system
151 ** sleep before it needs to service the next entry.
152 **
153 ** Parameters: None
154 **
155 ** Returns Number of ticks til the next timer expires
156 ** Note: The value is a signed value. This value should be
157 ** compared to x > 0, to avoid misinterpreting negative
158 ** tick values.
159 **
160 *******************************************************************************/
GKI_ready_to_sleep(void)161 int32_t GKI_ready_to_sleep(void) { return (gki_cb.com.OSTicksTilExp); }
162
163 /*******************************************************************************
164 **
165 ** Function GKI_start_timer
166 **
167 ** Description An application can call this function to start one of
168 ** it's four general purpose timers. Any of the four timers
169 ** can be 1-shot or continuous. If a timer is already running,
170 ** it will be reset to the new parameters.
171 **
172 ** Parameters tnum - (input) timer number to be started
173 ** (TIMER_0, TIMER_1, TIMER_2, or
174 ** TIMER_3)
175 ** ticks - (input) the number of system ticks til the
176 ** timer expires.
177 ** is_continuous - (input) TRUE if timer restarts
178 ** automatically, else FALSE if it is
179 ** a 'one-shot'.
180 **
181 ** Returns void
182 **
183 *******************************************************************************/
GKI_start_timer(uint8_t tnum,int32_t ticks,bool is_continuous)184 void GKI_start_timer(uint8_t tnum, int32_t ticks, bool is_continuous) {
185 int32_t reload;
186 int32_t orig_ticks;
187 uint8_t task_id = GKI_get_taskid();
188 bool bad_timer = false;
189
190 if (task_id >= GKI_MAX_TASKS) {
191 LOG(ERROR) << StringPrintf("%s: invalid task_id:0x%02x. start timer failed",
192 __func__, task_id);
193 return;
194 }
195
196 if (ticks <= 0) ticks = 1;
197
198 orig_ticks = ticks; /* save the ticks in case adjustment is necessary */
199
200 /* If continuous timer, set reload, else set it to 0 */
201 if (is_continuous)
202 reload = ticks;
203 else
204 reload = 0;
205
206 GKI_disable();
207
208 if (gki_timers_is_timer_running() == false) {
209 #if (GKI_DELAY_STOP_SYS_TICK > 0)
210 /* if inactivity delay timer is not running, start system tick */
211 if (gki_cb.com.OSTicksTilStop == 0) {
212 #endif
213 if (gki_cb.com.p_tick_cb) {
214 /* start system tick */
215 gki_cb.com.system_tick_running = true;
216 (gki_cb.com.p_tick_cb)(true);
217 }
218 #if (GKI_DELAY_STOP_SYS_TICK > 0)
219 } else {
220 /* clear inactivity delay timer */
221 gki_cb.com.OSTicksTilStop = 0;
222 }
223 #endif
224 }
225 /* Add the time since the last task timer update.
226 ** Note that this works when no timers are active since
227 ** both OSNumOrigTicks and OSTicksTilExp are 0.
228 */
229 if (GKI_MAX_INT32 - (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) >
230 ticks) {
231 ticks += gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp;
232 } else
233 ticks = GKI_MAX_INT32;
234
235 switch (tnum) {
236 #if (GKI_NUM_TIMERS > 0)
237 case TIMER_0:
238 gki_cb.com.OSTaskTmr0R[task_id] = reload;
239 gki_cb.com.OSTaskTmr0[task_id] = ticks;
240 break;
241 #endif
242
243 #if (GKI_NUM_TIMERS > 1)
244 case TIMER_1:
245 gki_cb.com.OSTaskTmr1R[task_id] = reload;
246 gki_cb.com.OSTaskTmr1[task_id] = ticks;
247 break;
248 #endif
249
250 #if (GKI_NUM_TIMERS > 2)
251 case TIMER_2:
252 gki_cb.com.OSTaskTmr2R[task_id] = reload;
253 gki_cb.com.OSTaskTmr2[task_id] = ticks;
254 break;
255 #endif
256
257 #if (GKI_NUM_TIMERS > 3)
258 case TIMER_3:
259 gki_cb.com.OSTaskTmr3R[task_id] = reload;
260 gki_cb.com.OSTaskTmr3[task_id] = ticks;
261 break;
262 #endif
263 default:
264 bad_timer = true; /* Timer number is bad, so do not use */
265 }
266
267 /* Update the expiration timeout if a legitimate timer */
268 if (!bad_timer) {
269 /* Only update the timeout value if it is less than any other newly started
270 * timers */
271 gki_adjust_timer_count(orig_ticks);
272 }
273
274 GKI_enable();
275 }
276
277 /*******************************************************************************
278 **
279 ** Function GKI_stop_timer
280 **
281 ** Description An application can call this function to stop one of
282 ** it's four general purpose timers. There is no harm in
283 ** stopping a timer that is already stopped.
284 **
285 ** Parameters tnum - (input) timer number to be started (TIMER_0,
286 ** TIMER_1, TIMER_2, or TIMER_3)
287 ** Returns void
288 **
289 *******************************************************************************/
GKI_stop_timer(uint8_t tnum)290 void GKI_stop_timer(uint8_t tnum) {
291 uint8_t task_id = GKI_get_taskid();
292
293 GKI_disable();
294 if (task_id < GKI_MAX_TASKS) {
295 switch (tnum) {
296 #if (GKI_NUM_TIMERS > 0)
297 case TIMER_0:
298 gki_cb.com.OSTaskTmr0R[task_id] = 0;
299 gki_cb.com.OSTaskTmr0[task_id] = 0;
300 break;
301 #endif
302
303 #if (GKI_NUM_TIMERS > 1)
304 case TIMER_1:
305 gki_cb.com.OSTaskTmr1R[task_id] = 0;
306 gki_cb.com.OSTaskTmr1[task_id] = 0;
307 break;
308 #endif
309
310 #if (GKI_NUM_TIMERS > 2)
311 case TIMER_2:
312 gki_cb.com.OSTaskTmr2R[task_id] = 0;
313 gki_cb.com.OSTaskTmr2[task_id] = 0;
314 break;
315 #endif
316
317 #if (GKI_NUM_TIMERS > 3)
318 case TIMER_3:
319 gki_cb.com.OSTaskTmr3R[task_id] = 0;
320 gki_cb.com.OSTaskTmr3[task_id] = 0;
321 break;
322 #endif
323 }
324 }
325
326 if (gki_timers_is_timer_running() == false) {
327 if (gki_cb.com.p_tick_cb) {
328 #if (GKI_DELAY_STOP_SYS_TICK > 0)
329 /* if inactivity delay timer is not running */
330 if ((gki_cb.com.system_tick_running) &&
331 (gki_cb.com.OSTicksTilStop == 0)) {
332 /* set inactivity delay timer */
333 /* when timer expires, system tick will be stopped */
334 gki_cb.com.OSTicksTilStop = GKI_DELAY_STOP_SYS_TICK;
335 }
336 #else
337 gki_cb.com.system_tick_running = false;
338 (gki_cb.com.p_tick_cb)(false); /* stop system tick */
339 #endif
340 }
341 }
342
343 GKI_enable();
344 }
345
346 /*******************************************************************************
347 **
348 ** Function GKI_timer_update
349 **
350 ** Description This function is called by an OS to drive the GKI's timers.
351 ** It is typically called at every system tick to
352 ** update the timers for all tasks, and check for timeouts.
353 **
354 ** Note: It has been designed to also allow for variable tick
355 ** updates so that systems with strict power savings
356 ** requirements can have the update occur at variable
357 ** intervals.
358 **
359 ** Parameters: ticks_since_last_update - (input) This is the number of
360 ** TICKS that have occurred since the last time
361 ** GKI_timer_update was called.
362 **
363 ** Returns void
364 **
365 *******************************************************************************/
GKI_timer_update(int32_t ticks_since_last_update)366 void GKI_timer_update(int32_t ticks_since_last_update) {
367 uint8_t task_id;
368 long next_expiration; /* Holds the next soonest expiration time after this
369 update */
370
371 /* Increment the number of ticks used for time stamps */
372 gki_cb.com.OSTicks += ticks_since_last_update;
373
374 /* If any timers are running in any tasks, decrement the remaining time til
375 * the timer updates need to take place (next expiration occurs)
376 */
377 gki_cb.com.OSTicksTilExp -= ticks_since_last_update;
378
379 /* Don't allow timer interrupt nesting */
380 if (gki_cb.com.timer_nesting) return;
381
382 gki_cb.com.timer_nesting = 1;
383
384 #if (GKI_DELAY_STOP_SYS_TICK > 0)
385 /* if inactivity delay timer is set and expired */
386 if (gki_cb.com.OSTicksTilStop) {
387 if (gki_cb.com.OSTicksTilStop <= (uint32_t)ticks_since_last_update) {
388 if (gki_cb.com.p_tick_cb) {
389 gki_cb.com.system_tick_running = false;
390 (gki_cb.com.p_tick_cb)(false); /* stop system tick */
391 }
392 gki_cb.com.OSTicksTilStop = 0; /* clear inactivity delay timer */
393 gki_cb.com.timer_nesting = 0;
394 return;
395 } else
396 gki_cb.com.OSTicksTilStop -= ticks_since_last_update;
397 }
398 #endif
399
400 /* No need to update the ticks if no timeout has occurred */
401 if (gki_cb.com.OSTicksTilExp > 0) {
402 gki_cb.com.timer_nesting = 0;
403 return;
404 }
405
406 GKI_disable();
407
408 next_expiration = GKI_NO_NEW_TMRS_STARTED;
409
410 /* If here then gki_cb.com.OSTicksTilExp <= 0. If negative, then increase
411 gki_cb.com.OSNumOrigTicks
412 to account for the difference so timer updates below are decremented by the
413 full number
414 of ticks. gki_cb.com.OSNumOrigTicks is reset at the bottom of this function
415 so changing this
416 value only affects the timer updates below
417 */
418 gki_cb.com.OSNumOrigTicks -= gki_cb.com.OSTicksTilExp;
419
420 /* Check for OS Task Timers */
421 for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++) {
422 if (gki_cb.com.OSRdyTbl[task_id] == TASK_DEAD) {
423 // task is shutdown do not try to service timers
424 continue;
425 }
426
427 if (gki_cb.com.OSWaitTmr[task_id] > 0) /* If timer is running */
428 {
429 gki_cb.com.OSWaitTmr[task_id] -= gki_cb.com.OSNumOrigTicks;
430 if (gki_cb.com.OSWaitTmr[task_id] <= 0) {
431 /* Timer Expired */
432 gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
433 }
434 }
435
436 #if (GKI_NUM_TIMERS > 0)
437 /* If any timer is running, decrement */
438 if (gki_cb.com.OSTaskTmr0[task_id] > 0) {
439 gki_cb.com.OSTaskTmr0[task_id] -= gki_cb.com.OSNumOrigTicks;
440
441 if (gki_cb.com.OSTaskTmr0[task_id] <= 0) {
442 /* Set Timer 0 Expired event mask and reload timer */
443 #if (GKI_TIMER_UPDATES_FROM_ISR == TRUE)
444 GKI_isend_event(task_id, TIMER_0_EVT_MASK);
445 #else
446 GKI_send_event(task_id, TIMER_0_EVT_MASK);
447 #endif
448 gki_cb.com.OSTaskTmr0[task_id] = gki_cb.com.OSTaskTmr0R[task_id];
449 }
450 }
451
452 /* Check to see if this timer is the next one to expire */
453 if (gki_cb.com.OSTaskTmr0[task_id] > 0 &&
454 gki_cb.com.OSTaskTmr0[task_id] < next_expiration)
455 next_expiration = gki_cb.com.OSTaskTmr0[task_id];
456 #endif
457
458 #if (GKI_NUM_TIMERS > 1)
459 /* If any timer is running, decrement */
460 if (gki_cb.com.OSTaskTmr1[task_id] > 0) {
461 gki_cb.com.OSTaskTmr1[task_id] -= gki_cb.com.OSNumOrigTicks;
462
463 if (gki_cb.com.OSTaskTmr1[task_id] <= 0) {
464 /* Set Timer 1 Expired event mask and reload timer */
465 #if (GKI_TIMER_UPDATES_FROM_ISR == TRUE)
466 GKI_isend_event(task_id, TIMER_1_EVT_MASK);
467 #else
468 GKI_send_event(task_id, TIMER_1_EVT_MASK);
469 #endif
470 gki_cb.com.OSTaskTmr1[task_id] = gki_cb.com.OSTaskTmr1R[task_id];
471 }
472 }
473
474 /* Check to see if this timer is the next one to expire */
475 if (gki_cb.com.OSTaskTmr1[task_id] > 0 &&
476 gki_cb.com.OSTaskTmr1[task_id] < next_expiration)
477 next_expiration = gki_cb.com.OSTaskTmr1[task_id];
478 #endif
479
480 #if (GKI_NUM_TIMERS > 2)
481 /* If any timer is running, decrement */
482 if (gki_cb.com.OSTaskTmr2[task_id] > 0) {
483 gki_cb.com.OSTaskTmr2[task_id] -= gki_cb.com.OSNumOrigTicks;
484
485 if (gki_cb.com.OSTaskTmr2[task_id] <= 0) {
486 /* Set Timer 2 Expired event mask and reload timer */
487 #if (GKI_TIMER_UPDATES_FROM_ISR == TRUE)
488 GKI_isend_event(task_id, TIMER_2_EVT_MASK);
489 #else
490 GKI_send_event(task_id, TIMER_2_EVT_MASK);
491 #endif
492 gki_cb.com.OSTaskTmr2[task_id] = gki_cb.com.OSTaskTmr2R[task_id];
493 }
494 }
495
496 /* Check to see if this timer is the next one to expire */
497 if (gki_cb.com.OSTaskTmr2[task_id] > 0 &&
498 gki_cb.com.OSTaskTmr2[task_id] < next_expiration)
499 next_expiration = gki_cb.com.OSTaskTmr2[task_id];
500 #endif
501
502 #if (GKI_NUM_TIMERS > 3)
503 /* If any timer is running, decrement */
504 if (gki_cb.com.OSTaskTmr3[task_id] > 0) {
505 gki_cb.com.OSTaskTmr3[task_id] -= gki_cb.com.OSNumOrigTicks;
506
507 if (gki_cb.com.OSTaskTmr3[task_id] <= 0) {
508 /* Set Timer 3 Expired event mask and reload timer */
509 #if (GKI_TIMER_UPDATES_FROM_ISR == TRUE)
510 GKI_isend_event(task_id, TIMER_3_EVT_MASK);
511 #else
512 GKI_send_event(task_id, TIMER_3_EVT_MASK);
513 #endif
514 gki_cb.com.OSTaskTmr3[task_id] = gki_cb.com.OSTaskTmr3R[task_id];
515 }
516 }
517
518 /* Check to see if this timer is the next one to expire */
519 if (gki_cb.com.OSTaskTmr3[task_id] > 0 &&
520 gki_cb.com.OSTaskTmr3[task_id] < next_expiration)
521 next_expiration = gki_cb.com.OSTaskTmr3[task_id];
522 #endif
523 }
524
525 /* Set the next timer experation value if there is one to start */
526 if (next_expiration < GKI_NO_NEW_TMRS_STARTED) {
527 gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = next_expiration;
528 } else {
529 gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = 0;
530 }
531
532 gki_cb.com.timer_nesting = 0;
533
534 GKI_enable();
535
536 return;
537 }
538
539 /*******************************************************************************
540 **
541 ** Function GKI_timer_queue_empty
542 **
543 ** Description This function is called by applications to see whether the
544 ** timer queue is empty
545 **
546 ** Parameters
547 **
548 ** Returns bool
549 **
550 *******************************************************************************/
GKI_timer_queue_empty(void)551 bool GKI_timer_queue_empty(void) {
552 uint8_t tt;
553
554 for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
555 if (gki_cb.com.timer_queues[tt]) return false;
556 }
557
558 return true;
559 }
560
561 /*******************************************************************************
562 **
563 ** Function GKI_timer_queue_register_callback
564 **
565 ** Description This function is called by applications to register system
566 ** tick start/stop callback for time queues
567 **
568 **
569 ** Parameters p_callback - (input) pointer to the system tick callback
570 **
571 ** Returns bool
572 **
573 *******************************************************************************/
GKI_timer_queue_register_callback(SYSTEM_TICK_CBACK * p_callback)574 void GKI_timer_queue_register_callback(SYSTEM_TICK_CBACK* p_callback) {
575 gki_cb.com.p_tick_cb = p_callback;
576
577 return;
578 }
579
580 /*******************************************************************************
581 **
582 ** Function GKI_init_timer_list
583 **
584 ** Description This function is called by applications when they
585 ** want to initialize a timer list.
586 **
587 ** Parameters p_timer_listq - (input) pointer to the timer list queue
588 ** object
589 **
590 ** Returns void
591 **
592 *******************************************************************************/
GKI_init_timer_list(TIMER_LIST_Q * p_timer_listq)593 void GKI_init_timer_list(TIMER_LIST_Q* p_timer_listq) {
594 p_timer_listq->p_first = nullptr;
595 p_timer_listq->p_last = nullptr;
596 p_timer_listq->last_ticks = 0;
597
598 return;
599 }
600
601 /*******************************************************************************
602 **
603 ** Function GKI_init_timer_list_entry
604 **
605 ** Description This function is called by the applications when they
606 ** want to initialize a timer list entry. This must be
607 ** done prior to first use of the entry.
608 **
609 ** Parameters p_tle - (input) pointer to a timer list queue entry
610 **
611 ** Returns void
612 **
613 *******************************************************************************/
GKI_init_timer_list_entry(TIMER_LIST_ENT * p_tle)614 void GKI_init_timer_list_entry(TIMER_LIST_ENT* p_tle) {
615 p_tle->p_next = nullptr;
616 p_tle->p_prev = nullptr;
617 p_tle->ticks = GKI_UNUSED_LIST_ENTRY;
618 p_tle->in_use = false;
619 }
620
621 /*******************************************************************************
622 **
623 ** Function GKI_update_timer_list
624 **
625 ** Description This function is called by the applications when they
626 ** want to update a timer list. This should be at every
627 ** timer list unit tick, e.g. once per sec, once per minute
628 ** etc.
629 **
630 ** Parameters p_timer_listq - (input) pointer to the timer list queue
631 ** object
632 ** num_units_since_last_update - (input) number of units since
633 ** the last update (allows for variable unit update)
634 **
635 ** NOTE: The following timer list update routines should not be used for exact
636 ** time critical purposes. The timer tasks should be used when exact
637 ** timing is needed.
638 **
639 ** Returns the number of timers that have expired
640 **
641 *******************************************************************************/
GKI_update_timer_list(TIMER_LIST_Q * p_timer_listq,int32_t num_units_since_last_update)642 uint16_t GKI_update_timer_list(TIMER_LIST_Q* p_timer_listq,
643 int32_t num_units_since_last_update) {
644 TIMER_LIST_ENT* p_tle;
645 uint16_t num_time_out = 0;
646 int32_t rem_ticks;
647 int32_t temp_ticks;
648
649 p_tle = p_timer_listq->p_first;
650
651 /* First, get the guys who have previously timed out */
652 /* Note that the tick value of the timers should always be '0' */
653 while ((p_tle) && (p_tle->ticks <= 0)) {
654 num_time_out++;
655 p_tle = p_tle->p_next;
656 }
657
658 /* Timer entriy tick values are relative to the preceeding entry */
659 rem_ticks = num_units_since_last_update;
660
661 /* Now, adjust remaining timer entries */
662 while ((p_tle != nullptr) && (rem_ticks > 0)) {
663 temp_ticks = p_tle->ticks;
664 p_tle->ticks -= rem_ticks;
665
666 /* See if this timer has just timed out */
667 if (p_tle->ticks <= 0) {
668 /* We set the number of ticks to '0' so that the legacy code
669 * that assumes a '0' or nonzero value will still work as coded. */
670 p_tle->ticks = 0;
671
672 num_time_out++;
673 }
674
675 rem_ticks -= temp_ticks; /* Decrement the remaining ticks to process */
676 p_tle = p_tle->p_next;
677 }
678
679 if (p_timer_listq->last_ticks > 0) {
680 p_timer_listq->last_ticks -= num_units_since_last_update;
681
682 /* If the last timer has expired set last_ticks to 0 so that other list
683 * update
684 * functions will calculate correctly
685 */
686 if (p_timer_listq->last_ticks < 0) p_timer_listq->last_ticks = 0;
687 }
688
689 return (num_time_out);
690 }
691
GKI_timer_list_empty(TIMER_LIST_Q * p_timer_listq)692 bool GKI_timer_list_empty(TIMER_LIST_Q* p_timer_listq) {
693 return p_timer_listq->p_first == nullptr;
694 }
695
GKI_timer_list_first(TIMER_LIST_Q * p_timer_listq)696 TIMER_LIST_ENT* GKI_timer_list_first(TIMER_LIST_Q* p_timer_listq) {
697 return p_timer_listq->p_first;
698 }
699
700 /*******************************************************************************
701 **
702 ** Function GKI_get_remaining_ticks
703 **
704 ** Description This function is called by an application to get remaining
705 ** ticks to expire
706 **
707 ** Parameters p_timer_listq - (input) pointer to the timer list queue
708 ** object
709 ** p_target_tle - (input) pointer to a timer list queue entry
710 **
711 ** Returns 0 if timer is not used or timer is not in the list
712 ** remaining ticks if success
713 **
714 *******************************************************************************/
GKI_get_remaining_ticks(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_target_tle)715 uint32_t GKI_get_remaining_ticks(TIMER_LIST_Q* p_timer_listq,
716 TIMER_LIST_ENT* p_target_tle) {
717 TIMER_LIST_ENT* p_tle;
718 uint32_t rem_ticks = 0;
719
720 if (p_target_tle->in_use) {
721 p_tle = p_timer_listq->p_first;
722
723 /* adding up all of ticks in previous entries */
724 while ((p_tle) && (p_tle != p_target_tle)) {
725 rem_ticks += p_tle->ticks;
726 p_tle = p_tle->p_next;
727 }
728
729 /* if found target entry */
730 if (p_tle == p_target_tle) {
731 rem_ticks += p_tle->ticks;
732 } else {
733 LOG(ERROR) << StringPrintf(
734 "GKI_get_remaining_ticks: No timer entry in the list");
735 return (0);
736 }
737 } else {
738 LOG(ERROR) << StringPrintf(
739 "GKI_get_remaining_ticks: timer entry is not active");
740 }
741
742 return (rem_ticks);
743 }
744
745 /*******************************************************************************
746 **
747 ** Function GKI_add_to_timer_list
748 **
749 ** Description This function is called by an application to add a timer
750 ** entry to a timer list.
751 **
752 ** Note: A timer value of '0' will effectively insert an
753 ** already expired event. Negative tick values will be
754 ** ignored.
755 **
756 ** Parameters p_timer_listq - (input) pointer to the timer list queue
757 ** object
758 ** p_tle - (input) pointer to a timer list queue entry
759 **
760 ** Returns void
761 **
762 *******************************************************************************/
GKI_add_to_timer_list(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_tle)763 void GKI_add_to_timer_list(TIMER_LIST_Q* p_timer_listq, TIMER_LIST_ENT* p_tle) {
764 uint32_t nr_ticks_total;
765 uint8_t tt;
766 TIMER_LIST_ENT* p_temp;
767 if (p_tle == nullptr || p_timer_listq == nullptr) {
768 LOG(VERBOSE) << StringPrintf(
769 "%s: invalid argument %p, %p****************************<<", __func__,
770 p_timer_listq, p_tle);
771 return;
772 }
773
774 /* Only process valid tick values */
775 if (p_tle->ticks >= 0) {
776 /* If this entry is the last in the list */
777 if (p_tle->ticks >= p_timer_listq->last_ticks) {
778 /* If this entry is the only entry in the list */
779 if (p_timer_listq->p_first == nullptr)
780 p_timer_listq->p_first = p_tle;
781 else {
782 /* Insert the entry onto the end of the list */
783 if (p_timer_listq->p_last != nullptr)
784 p_timer_listq->p_last->p_next = p_tle;
785
786 p_tle->p_prev = p_timer_listq->p_last;
787 }
788
789 p_tle->p_next = nullptr;
790 p_timer_listq->p_last = p_tle;
791 nr_ticks_total = p_tle->ticks;
792 p_tle->ticks -= p_timer_listq->last_ticks;
793
794 p_timer_listq->last_ticks = nr_ticks_total;
795 } else /* This entry needs to be inserted before the last entry */
796 {
797 /* Find the entry that the new one needs to be inserted in front of */
798 p_temp = p_timer_listq->p_first;
799 while (p_tle->ticks > p_temp->ticks) {
800 /* Update the tick value if looking at an unexpired entry */
801 if (p_temp->ticks > 0) p_tle->ticks -= p_temp->ticks;
802
803 p_temp = p_temp->p_next;
804 }
805
806 /* The new entry is the first in the list */
807 if (p_temp == p_timer_listq->p_first) {
808 p_tle->p_next = p_timer_listq->p_first;
809 p_timer_listq->p_first->p_prev = p_tle;
810 p_timer_listq->p_first = p_tle;
811 } else {
812 p_temp->p_prev->p_next = p_tle;
813 p_tle->p_prev = p_temp->p_prev;
814 p_temp->p_prev = p_tle;
815 p_tle->p_next = p_temp;
816 }
817 p_temp->ticks -= p_tle->ticks;
818 }
819
820 p_tle->in_use = true;
821
822 /* if we already add this timer queue to the array */
823 for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
824 if (gki_cb.com.timer_queues[tt] == p_timer_listq) return;
825 }
826 /* add this timer queue to the array */
827 for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
828 if (gki_cb.com.timer_queues[tt] == nullptr) break;
829 }
830 if (tt < GKI_MAX_TIMER_QUEUES) {
831 gki_cb.com.timer_queues[tt] = p_timer_listq;
832 }
833 }
834
835 return;
836 }
837
838 /*******************************************************************************
839 **
840 ** Function GKI_remove_from_timer_list
841 **
842 ** Description This function is called by an application to remove a timer
843 ** entry from a timer list.
844 **
845 ** Parameters p_timer_listq - (input) pointer to the timer list queue
846 ** object
847 ** p_tle - (input) pointer to a timer list queue entry
848 **
849 ** Returns void
850 **
851 *******************************************************************************/
GKI_remove_from_timer_list(TIMER_LIST_Q * p_timer_listq,TIMER_LIST_ENT * p_tle)852 void GKI_remove_from_timer_list(TIMER_LIST_Q* p_timer_listq,
853 TIMER_LIST_ENT* p_tle) {
854 uint8_t tt;
855
856 /* Verify that the entry is valid */
857 if (p_tle == nullptr || p_tle->in_use == false ||
858 p_timer_listq->p_first == nullptr) {
859 return;
860 }
861
862 /* Add the ticks remaining in this timer (if any) to the next guy in the list.
863 ** Note: Expired timers have a tick value of '0'.
864 */
865 if (p_tle->p_next != nullptr) {
866 p_tle->p_next->ticks += p_tle->ticks;
867 } else {
868 p_timer_listq->last_ticks -= p_tle->ticks;
869 }
870
871 /* Unlink timer from the list. */
872 if (p_timer_listq->p_first == p_tle) {
873 p_timer_listq->p_first = p_tle->p_next;
874
875 if (p_timer_listq->p_first != nullptr)
876 p_timer_listq->p_first->p_prev = nullptr;
877
878 if (p_timer_listq->p_last == p_tle) p_timer_listq->p_last = nullptr;
879 } else {
880 if (p_timer_listq->p_last == p_tle) {
881 p_timer_listq->p_last = p_tle->p_prev;
882
883 if (p_timer_listq->p_last != nullptr)
884 p_timer_listq->p_last->p_next = nullptr;
885 } else {
886 if (p_tle->p_next != nullptr && p_tle->p_next->p_prev == p_tle)
887 p_tle->p_next->p_prev = p_tle->p_prev;
888 else {
889 /* Error case - chain messed up ?? */
890 return;
891 }
892
893 if (p_tle->p_prev != nullptr && p_tle->p_prev->p_next == p_tle)
894 p_tle->p_prev->p_next = p_tle->p_next;
895 else {
896 /* Error case - chain messed up ?? */
897 return;
898 }
899 }
900 }
901
902 p_tle->p_next = p_tle->p_prev = nullptr;
903 p_tle->ticks = GKI_UNUSED_LIST_ENTRY;
904 p_tle->in_use = false;
905
906 /* if timer queue is empty */
907 if (p_timer_listq->p_first == nullptr && p_timer_listq->p_last == nullptr) {
908 for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++) {
909 if (gki_cb.com.timer_queues[tt] == p_timer_listq) {
910 gki_cb.com.timer_queues[tt] = nullptr;
911 break;
912 }
913 }
914 /* Recovering from unexpected state.
915 e.g. when TIMER_LIST_ENT is cleared before stop */
916 if (p_timer_listq->last_ticks) p_timer_listq->last_ticks = 0;
917 }
918
919 return;
920 }
921
922 /*******************************************************************************
923 **
924 ** Function gki_adjust_timer_count
925 **
926 ** Description This function is called whenever a new timer or GKI_wait
927 ** occurs to adjust (if necessary) the current time til the
928 ** first expiration. This only needs to make an adjustment if
929 ** the new timer (in ticks) is less than the number of ticks
930 ** remaining on the current timer.
931 **
932 ** Parameters: ticks - (input) number of system ticks of the new timer
933 ** entry
934 **
935 ** NOTE: This routine MUST be called while interrupts are
936 ** disabled to avoid updates while adjusting the timer
937 ** variables.
938 **
939 ** Returns void
940 **
941 *******************************************************************************/
gki_adjust_timer_count(int32_t ticks)942 void gki_adjust_timer_count(int32_t ticks) {
943 if (ticks > 0) {
944 /* See if the new timer expires before the current first expiration */
945 if (gki_cb.com.OSNumOrigTicks == 0 ||
946 (ticks < gki_cb.com.OSTicksTilExp && gki_cb.com.OSTicksTilExp > 0)) {
947 gki_cb.com.OSNumOrigTicks =
948 (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) + ticks;
949 gki_cb.com.OSTicksTilExp = ticks;
950 }
951 }
952
953 return;
954 }
955