当前位置: 首页 > news >正文

深圳市住房建设与保障局官方网站大连网站建设酷网科技

深圳市住房建设与保障局官方网站,大连网站建设酷网科技,wordpress调用目录,能进封禁网站的手机浏览器1、前言 上一篇我们谈到了timer#xff0c;在详细分析hrtimer的实现之前#xff0c;我们先追根溯源来谈一下clockevent。先抛开clockevent这个概念#xff0c;如果硬件要支持定时功能#xff0c;那么硬件必然要能够支持产生定时时间#xff0c;通过异步中断的方式通知CPU在详细分析hrtimer的实现之前我们先追根溯源来谈一下clockevent。先抛开clockevent这个概念如果硬件要支持定时功能那么硬件必然要能够支持产生定时时间通过异步中断的方式通知CPU你当然不可能让CPU一直去轮询时钟看时间是不是快到了对吧linux对能够产生异步事件的clock进行了软件抽象clock event。那么实际上clock event和clock source是硬件时钟的一体两面clock source提供了读取cycle计算时间相关的功能而clock event则提供了产生时间事件相关的功能。 2、clock_event_device数据结构 我们看一下Linux内核是如何用clock_event_device来抽象产生系统时间事件(中断)的设备的如下 struct clock_event_device {void (*event_handler)(struct clock_event_device *);int (*set_next_event)(unsigned long evt, struct clock_event_device *);int (*set_next_ktime)(ktime_t expires, struct clock_event_device *);ktime_t next_event;u64 max_delta_ns;u64 min_delta_ns;u32 mult;u32 shift;enum clock_event_state state_use_accessors;unsigned int features;unsigned long retries;int (*set_state_periodic)(struct clock_event_device *);int (*set_state_oneshot)(struct clock_event_device *);int (*set_state_oneshot_stopped)(struct clock_event_device *);int (*set_state_shutdown)(struct clock_event_device *);int (*tick_resume)(struct clock_event_device *);void (*broadcast)(const struct cpumask *mask);void (*suspend)(struct clock_event_device *);void (*resume)(struct clock_event_device *);unsigned long min_delta_ticks;unsigned long max_delta_ticks;const char *name;int rating;int irq;int bound_on;const struct cpumask *cpumask;struct list_head list;struct module *owner; } ____cacheline_aligned; clock_event_device肯定要基于中断我们先看中断相关的成员 irq使用的中断号 features中断模式硬件支持的中断能力包括 # define CLOCK_EVT_FEAT_PERIODIC 0x000001 # define CLOCK_EVT_FEAT_ONESHOT 0x000002 # define CLOCK_EVT_FEAT_KTIME 0x000004 # define CLOCK_EVT_FEAT_C3STOP 0x000008 # define CLOCK_EVT_FEAT_DUMMY 0x000010 # define CLOCK_EVT_FEAT_DYNIRQ 0x000020 # define CLOCK_EVT_FEAT_PERCPU 0x000040 # define CLOCK_EVT_FEAT_HRTIMER 0x000080 CLOCK_EVT_FEAT_PERIODIC能够产生周期性event比如每隔1s产生1个event CLOCK_EVT_FEAT_ONESHOT        具备产生oneshot类型的event能力即单次event CLOCK_EVT_FEAT_KTIME        可以直接使用ktime产生event即到达某个ktime产生event有些硬件时钟确实有这样的能力就比如在clocksource中说的read函数返回的是time而不是counter CLOCK_EVT_FEAT_C3STOP CPU的sleep state叫做C-states有C1/C2等即CPU进入某个深度睡眠状态的时候停止了local timer的运作 CLOCK_EVT_FEAT_PERCPU        是不是percpu的clock event CLOCK_EVT_FEAT_DYNIRQ表示该定时事件设备可以设定CPU亲缘性也就是可以指定到期后触发某个特定CPU的中断 CLOCK_EVT_FEAT_HRTIMER表示该定时事件设备实际上是有高分辨率定时器模拟出来的 与feature强相关的还有state_use_accessorsclock event支持上述feature但是具体工作在哪一个状态用state_use_accessors描述 enum clock_event_state { CLOCK_EVT_STATE_DETACHED, CLOCK_EVT_STATE_SHUTDOWN, CLOCK_EVT_STATE_PERIODIC, CLOCK_EVT_STATE_ONESHOT, CLOCK_EVT_STATE_ONESHOT_STOPPED, }; 都比较好理解就不解释了。同时也可以看到工作状态通过set_state_xxx这样的接口实现。 event_handler这里的event_handler并不是中断处理函数而是在中断处理函数中调用的callback 相应的就有next_eventset_next_eventset_next_ktime相关成员和设置下一次触发时间相关 除了这些与中断相关的成员还有 cpumask指定了这个定时事件设备所服务的CPU号系统中高精度定时事件设备一般都是每个CPU核私有的。 list系统中所有的定时事件设备实例都会保存在全局链表clockevent_devices中 mult、shiftrating与clock source相同其他略过。 3、clock_event_device的注册 注册函数clockevents_config_and_register 在使用clockevents_config_and_register注册设备之前先要 准备好clock_event_device结构体数据。 void clockevents_config_and_register(struct clock_event_device *dev,u32 freq, unsigned long min_delta,unsigned long max_delta) {dev-min_delta_ticks min_delta;dev-max_delta_ticks max_delta;clockevents_config(dev, freq);clockevents_register_device(dev); } 实际调用了clockevents_config和clockevents_register_device完成设备配置和注册 clockevents_config主要用来设置对应的mult和shiftclockevents_register_device如下 void clockevents_register_device(struct clock_event_device *dev) {unsigned long flags;/* Initialize state to DETACHED */clockevent_set_state(dev, CLOCK_EVT_STATE_DETACHED);if (!dev-cpumask) {WARN_ON(num_possible_cpus() 1);dev-cpumask cpumask_of(smp_processor_id());}if (dev-cpumask cpu_all_mask) {WARN(1, %s cpumask cpu_all_mask, using cpu_possible_mask instead\n,dev-name);dev-cpumask cpu_possible_mask;}raw_spin_lock_irqsave(clockevents_lock, flags);list_add(dev-list, clockevent_devices);tick_check_new_device(dev);clockevents_notify_released();raw_spin_unlock_irqrestore(clockevents_lock, flags); } 首先修改了注册设备的状态为CLOCK_EVT_STATE_DETACHED  再次检查了设备绑定的cpumask随后list_add将设备加入全局设备链表clockevent_devices与时钟源注册类似clocksource_list tick_check_new_device用来检查当前的定时设备是否可以成为新的tick设备回想一下之前clocksource注册的时候是不是也有类似的操作判断新注册的时钟源是否可以替代现有时钟源这里的逻辑也是类似的。如果新设备更适合作为tick设备想一想系统时间是和clocksource绑定的而系统tick是和clock_event_device绑定的那么就会调用clockevents_exchange_device。 clockevents_exchange_device的实现看下一节 4、更换系统clock_event_device 当有新的定时事件设备加入内核后有可能会切换当前tick设备使用的定时事件设备 这是在函数clockevents_exchange_device中实现的 void clockevents_exchange_device(struct clock_event_device *old,struct clock_event_device *new) {/** Caller releases a clock event device. We queue it into the* released list and do a notify add later.*/if (old) {module_put(old-owner);clockevents_switch_state(old, CLOCK_EVT_STATE_DETACHED);list_del(old-list);list_add(old-list, clockevents_released);}if (new) {BUG_ON(!clockevent_state_detached(new));clockevents_shutdown(new);} }clockevents_switch_state将设备状态切换为CLOCK_EVT_STATE_DETACHED list_del将事件设备从clockevent_devices全局链表删除加入clockevents_released链表 这个函数是在本地中断关闭并且获得自旋锁的情况下调用的。功能其实很简单主要就是把被替换的老设备从原有的clockevent_devices全局链表中删除并加入clockevents_released全局链表中于此同时把新替换的设备加入clockevent_devices全局链表中当然还要更新设备的状态。新加入的设备的初始状态必须是CLOCK_EVT_STATE_DETACHED。 5、配置clock event device触发参数 int clockevents_program_event(struct clock_event_device *dev, ktime_t expires,bool force) {unsigned long long clc;int64_t delta;int rc;if (WARN_ON_ONCE(expires 0))return -ETIME;dev-next_event expires;if (clockevent_state_shutdown(dev))return 0;/* We must be in ONESHOT state here */WARN_ONCE(!clockevent_state_oneshot(dev), Current state: %d\n,clockevent_get_state(dev));/* Shortcut for clockevent devices that can deal with ktime. */if (dev-features CLOCK_EVT_FEAT_KTIME)return dev-set_next_ktime(expires, dev);delta ktime_to_ns(ktime_sub(expires, ktime_get()));if (delta 0)return force ? clockevents_program_min_delta(dev) : -ETIME;delta min(delta, (int64_t) dev-max_delta_ns);delta max(delta, (int64_t) dev-min_delta_ns);clc ((unsigned long long) delta * dev-mult) dev-shift;rc dev-set_next_event((unsigned long) clc, dev);return (rc force) ? clockevents_program_min_delta(dev) : rc; }dev指向具体的clock event deviceexpires参数是设定下一次产生event的时间点force参数控制在expires设定异常的时候例如设定在一个过去的时间点上产生event该函数 的行为一种是出错返回另外一种还是进行event的产生只是设定一个最小的delta。 1如果chip driver支持使用ktime的设定这需要硬件支持设定了CLOCK_EVT_FEAT_KTIME flag的那些clock event device才支持哦事情会比较简单直接调用set_next_ktime就搞定了。 2对于一个“正常”的clock event device需要转换成cycle这样的单位。不过在转换成cycle之前需要先将ktime格式的时间传入的expires参数就是这样的格式转换成纳秒这样的时间单位。 3delta小于0意味着用户设定的时间点已经是过去的一个时间点如果强制产生event的话那么事不宜迟要立刻产生event这需要调用clockevents_program_min_delta函数代码如下 6、总结 了解了上面的内容就可以知道内核中timer相关的底层机制了关于tick和timer的内容见后面的文章本篇主要内容参考Linux时间子系统之十六clockevent
http://www.zqtcl.cn/news/558145/

相关文章:

  • 做网站要以单位手机发博客wordpress
  • 莆田网站建设莆田seo管理系统培训
  • 有一个网站自己做链接获取朋友位置网站关键词数量减少
  • 毕设网站建设论文小程序开发模板
  • 广州网页模板建站电商平台谈双11变冷
  • 用.cc做网站官网可以吗2003系统网站建设
  • 创意网站推荐新手网站
  • 网站编程好学吗免费下载app并安装
  • 广州专业网站制作设计网站建设分几种
  • 有没有专业做艺术品的网站长沙人才市场招聘信息
  • 河池做网站通过邮箱查注册网站
  • 金融互助网站开发网上免费设计效果图
  • 网站开发 例子施工企业质量管理体系应按照我国
  • 义乌建设网站网络营销推广有哪些方法
  • 宿迁建设局网站a类证查询怎么自己搭建梯子
  • 成都网站品牌设计策划网络推广如何收费
  • html5 js全屏滑动网站源码wordpress 插件 破解
  • 做电影网站怎么批量去水印微信用什么小程序可以提取文字
  • 网站开发费用周期域名网站建设方案书模板
  • 织梦网站问题关于政务网站建设工作情况的总结
  • wordpress 拿站网站搭建后如何使用
  • 网站设计应遵循的原则wordpress免费空间
  • 建设网站的特色企业内部培训app软件
  • jsp网站缓存在哪wordpress设置静态页面
  • 百度做网站电话多少东台网页定制
  • 暖通设计网站推荐百度在西安的公司叫什么
  • 天津响应式网站设计网站建设的任务
  • 多语言网站 自助江门建设局网站
  • 宜兴做阿里巴巴网站常州外贸网站设计
  • 长沙米拓建站wordpress最底部版权