设为首页 加入收藏

TOP

Zephyr学习(四)系统时钟(三)
2019-09-01 23:08:47 】 浏览:95
Tags:Zephyr 学习 系统 时钟
6 __ASSERT(timeout_in_ticks >= 0, ""); 7 8 timeout->delta_ticks_from_prev = timeout_in_ticks; 9 timeout->thread = thread; 10 timeout->wait_q = (sys_dlist_t *)wait_q; 11 12 K_DEBUG("before adding timeout %p\n", timeout); 13 14 /* If timer is submitted to expire ASAP with 15 * timeout_in_ticks (duration) as zero value, 16 * then handle timeout immedately without going 17 * through timeout queue. 18 */ 19 if (!timeout_in_ticks) { 20 _handle_one_expired_timeout(timeout); 21 return; 22 } 23 24 s32_t *delta = &timeout->delta_ticks_from_prev; 25 struct _timeout *in_q; 26 27 SYS_DLIST_FOR_EACH_CONTAINER(&_timeout_q, in_q, node) { 28 if (*delta <= in_q->delta_ticks_from_prev) { 29 in_q->delta_ticks_from_prev -= *delta; 30 sys_dlist_insert_before(&_timeout_q, &in_q->node, 31 &timeout->node); 32 goto inserted; 33 } 34 35 *delta -= in_q->delta_ticks_from_prev; 36 } 37 38 sys_dlist_append(&_timeout_q, &timeout->node); 39 40inserted: 41 K_DEBUG("after adding timeout %p\n", timeout); 42}

第19行,很明显timeout_in_ticks的值不为0。

第27~38行, 按delta_ticks_from_prev的值由小到大插入到_timeout_q超时队列里。由此可知,超时队列里存放的是与前一个线程的时间的差值,而不是绝对值。

回到_impl_k_sleep()函数,第26行,调用_Swap()函数,把线程切换出去,这在下一篇随笔再分析。

好了,有了这些基础之后,现在回到_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
首页 上一页 1 2 3 4 5 下一页 尾页 3/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇per-CPU变量 下一篇网络中的NAT模式

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目