Chinaunix首页 | 论坛 | 博客
  • 博客访问: 733446
  • 博文数量: 79
  • 博客积分: 2671
  • 博客等级: 少校
  • 技术积分: 1247
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-02 15:26
个人简介

宅男

文章分类

全部博文(79)

文章存档

2017年(11)

2016年(12)

2015年(6)

2012年(10)

2011年(33)

2010年(7)

分类: Android平台

2016-10-19 14:52:15

之前经常在内核看到, 
这样的函数。虽然好奇,但是一直没弄懂。老子就想sleep一段时间,你干嘛搞个range ?
今天搞一个跟精确时间很相关的问题,终于仔细看了一下代码。
hrtimer就是高精度定时器,精度是高,happy的同时也带来一个问题,那就是中断太多了,虽说中断是个好东西,但是有时候两个定时器相差几十个纳秒,
你完全没必要搞两个中断!
那么对于精度要求不高的情况,是不是可以降低硬件中断次数呀,
这个就是struct task_struct->timer_slack_ns的目的。通过timer_slack_ns来设置一个范围(range),在这个范围里面的hrtimer,我可以顺带一起处理了。
那么怎么个一起处理法?

  1. 198static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time)
  2. 199{
  3. 200    timer->node.expires = time;
  4. 201    timer->_softexpires = time;
  5. 202}
  6. 203
  7. 204static inline void hrtimer_set_expires_range(struct hrtimer *timer, ktime_t time, ktime_t delta)
  8. 205{
  9. 206    timer->_softexpires = time;
  10. 207    timer->node.expires = ktime_add_safe(time, delta);
  11. 208}
  12. 209
  13. 210static inline void hrtimer_set_expires_range_ns(struct hrtimer *timer, ktime_t time, unsigned long delta)
  14. 211{
  15. 212    timer->_softexpires = time;
  16. 213    timer->node.expires = ktime_add_safe(time, ns_to_ktime(delta));
  17. 214}
首先来看这几个函数,都是在设置expires时间,可以看到timer里两个变量一个是node.expires, 另外一个是softexpires.
在hrtimer中设置定时器的时间都是以node.expires为准,这一点从可以看出来,而且红黑树的key也是node.expires.
那么问题来了,softexpires是什么鬼,要了干嘛?
这一点要从hrtimer_interrupt的代码来看了

  1. 1325    for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
  2. 1326        struct hrtimer_clock_base *base;
  3. 1327        struct timerqueue_node *node;
  4. 1328        ktime_t basenow;
  5. 1329
  6. 1330        if (!(cpu_base->active_bases & (1 << i)))
  7. 1331            continue;
  8. 1332
  9. 1333        base = cpu_base->clock_base + i;
  10. 1334        basenow = ktime_add(now, base->offset);
  11. 1335
  12. 1336        while ((node = timerqueue_getnext(&base->active))) {
  13. 1337            struct hrtimer *timer;
  14. 1338
  15. 1339            timer = container_of(node, struct hrtimer, node);
  16. 1340
  17. 1341            /*
  18. 1342             * The immediate goal for using the softexpires is
  19. 1343             * minimizing wakeups, not running timers at the
  20. 1344             * earliest interrupt after their soft expiration.
  21. 1345             * This allows us to avoid using a Priority Search
  22. 1346             * Tree, which can answer a stabbing querry for
  23. 1347             * overlapping intervals and instead use the simple
  24. 1348             * BST we already have.
  25. 1349             * We don't add extra wakeups by delaying timers that
  26. 1350             * are right-of a not yet expired timer, because that
  27. 1351             * timer will have to trigger a wakeup anyway.
  28. 1352             */
  29. 1353            if (basenow.tv64 < hrtimer_get_softexpires_tv64(timer))
  30. 1354                break;
  31. 1355
  32. 1356            __run_hrtimer(timer, &basenow);
  33. 1357        }
  34. 1358    }
最关键的就是上面这句
if (. < ());
可以在别的hrtimer A中顺带把hrtimer B给处理了。



以上面的图为例,一个hrtime A, 其timeout时间为T+delat,但是如果在T~T+delat之间的某一点上,hrtimer B到期,
中断触发,在中断处理函数hrtimer_interrupt里面,顺带把hrtimer A也处理了。

现在android里面的cgroup将进程分为前台进程和后台进程,后台进程的默认的time_slack_ns为50ms,要小心了,对于性能相关的影响
比较大。

阅读(4091) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~