第27~38行, 按delta_ticks_from_prev的值由小到大插入到_timeout_q超时队列里。由此可知,超时队列里存放的是与前一个线程的时间的差值,而不是绝对值。
好了,有了这些基础之后,现在回到_nano_sys_clock_tick_announce()函数,第12行,调用handle_timeouts()函数,定义在zephyr-zephyr-v1.13.0\kernel\ sys_clock.c:
1 static inline void handle_timeouts(s32_t ticks)
2 {
3 sys_dlist_t expired;
4 unsigned int key;
5
6 /* init before locking interrupts */
7 sys_dlist_init(&expired);
8
9 key = irq_lock();
10
11 sys_dnode_t *next = sys_dlist_peek_head(&_timeout_q);
12 struct _timeout *timeout = (struct _timeout *)next;
13
14 K_DEBUG("head: %p, delta: %d\n",
15 timeout, timeout ? timeout->delta_ticks_from_prev : -2112);
16
17 if (!next) {
18 irq_unlock(key);
19 return;
20 }
21
22 /*
23 * Dequeue all expired timeouts from _timeout_q, relieving irq lock
24 * pressure between each of them, allowing handling of higher priority
25 * interrupts. We know that no new timeout will be prepended in front
26 * of a timeout which delta is 0, since timeouts of 0 ticks are
27 * prohibited.
28 */
29
30 while (next) {
31
32 /*
33 * In the case where ticks number is greater than the first
34 * timeout delta of the list, the lag produced by this initial
35 * difference must also be applied to others timeouts in list
36 * until it was entirely consumed.
37 */
38
39 s32_t tmp = timeout->delta_ticks_from_prev;
40
41 if (timeout->delta_ticks_from_prev < ticks) {
42 timeout->delta_ticks_from_prev = 0;
43 } else {
44 timeout->delta_ticks_from_prev -= ticks;
45 }
46
47 ticks -= tmp;
48
49 next = sys_dlist_peek_next(&_timeout_q, next);
50
51 if (timeout->delta_ticks_from_prev == 0) {
52 sys_dnode_t *node = &timeout->node;
53
54 sys_dlist_remove(node);
55
56 /*
57 * Reverse the order that that were queued in the
58 * timeout_q: timeouts expiring on the same ticks are
59 * queued in the reverse order, time-wise, that they are
60 * added to shorten the amount of time with interrupts
61 * locked while walking the timeout_q. By reversing the
62 * order _again_ when building the expired queue, they
63 * end up being proce