linux定时器回调处理过程,Linux内核系统定时器TIMER实现过程分析
可见涉及到系统定时器的数据结构并不多,那么:对于一个linux系统中,定时器个数可能会很多,而且每个定时器的超时事件时间并不相同,所以如何管理和处理定时器超时事件,关系到内核性能的高低。它根据不同的定时事件,按时间间分组,将新增的timer定时器建成双向链表,然后按照一定方式存放于5组tv1~tv5变量中称为tec_base。对于对称式多理器(SMP)系统还考虑到了TIMER从一个CPU迁移到另一个CPU的情况,相应的tev_base也跟着更改。那它在系统是怎样实现的呢?现在先从一个简单的系统定时器应用例子来看看它的实现过程:
[cpp]
#include
#include
#include
structtimer_list my_timer;
staticvoidmy_function(unsignedlongdata)
{
staticinti = 0;
printk("timer’s callback function\n");
printk("timer’s data = %lu\n",data);
return;
}
staticintmy_timer_init(void)
{
printk(“timerinit…\n”);
my_timer.data = 0xff;
my_timer.function = my_function;
my_timer.expires = jiffies + 3*HZ;
init_timer(&my_timer);
add_timer(&my_timer);
return0;
}
staticvoidmy_timer_exit(void)
{
printk("timer exit…\n");
}
module_init(my_timer_init);
module_exit(my_timer_exit);
MODULE_AUTHOR("itspy");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("linux kernel timerprogramming");
上面例子,实现了一个定时器事件,将在3 HZ(秒)发生。my_imer_init函数中调用到的定时器API只有:
init_timer(&my_timer); //用于定时器初始化
add_timer(&my_timer); //增加一个新的定时器到tev_base向量表中
其中init_timer中调用了__init_timer(),这个函数才是真正初始化定时器的:
[cpp]
staticvoid__init_timer(structtimer_list*timer,
constchar*name,
structlock_class_key *key)
{
timer->entry.next= NULL;//对于新增的timer实例,其下一各总是指向NULL。
timer->base= __raw_get_cpu_var(tvec_bases);//SMP中,获得当前处理器的tev_base
//这个tev_bases是根据一定规律变化的,稍后会将到
…
}
新增的定时器初始化,就是完成了一个timer_list结构初始化过程。
add_timer() --> mod_timer() --> __mod_timer()其中:
[cpp]
staticinlineint
__mod_timer(structtimer_list *timer,unsignedlongexpires,boolpending_only)
{
structtvec_base *base, *new_base;
unsignedlong flags;
intret;
ret= 0;
BUG_ON(!timer->function);// BUG检测,确保回调函数为非空NULL
base= lock_timer_base(timer, &flags);//获取本地cpu的tev_base,这是一个临
//界资源,里边是一个for(;;)循环,如果找不到说明已经迁移到了别的CPU
if(timer_pending(timer)) {//当已挂载的timer 定时超时发生后,会被卸载摘除
detach_timer(timer,0);
ret= 1;
}else{
if(pending_only)//新增一个定时器时,pending_only 为 false
gotoout_unlock;
}
…
new_base= __get_cpu_var(tvec_bases);//获取本地cpu中的tevc_bases
if(base != new_base) {//由于之前base 可能已被迁移到其他CPU的 tev_base向量表,会造成 base != new_base
if(likely(base->running_timer != timer)) {//由于在timer正在运行时,我们不能直接更改base,位与一个叫做DEFERRABLE(可延后标志)后处理
/*See the comment in lock_timer_base() */
timer_set_base(timer,NULL);
spin_unlock(&base->lock);
base= new_base;
spin_lock(&base->lock);
timer_set_base(timer,base);
}
}
timer->expires= expires;
internal_add_timer(base,timer);//分析timer expires及建表过程
out_unlock:
spin_unlock_irqrestore(&base->lock,flags);
returnret;
}
linux定时器回调处理过程,Linux内核系统定时器TIMER实现过程分析相关推荐
- linux搭建一个的过程,Linux内核创建一个新进程的过程
此文仅用于MOOCLinux内核分析作业 task_struct数据结构 根据wiki的定义,进程是计算机中已运行程序的实体.在面向线程设计的系统(Linux 2.6及更新的版本)中,进程本身不是基本 ...
- MBR的Linux分区机制启动过程,linux系统启动流程(MBR)
总:POST---> Boot Squence ---> Bootloader ---> kernel ---> init ---> 完成启动 系统:CentOS6 1. ...
- linux 建立伪目标过程,linux之Makefile 编写、规则、伪目标、变量
什么是Makefile?首先,make是一个工具程序(Utility software),是一种控制编译或者重复编译软件的工具:make可以自动管理软件编译的内容.方式和时机从而使程序员能够把精力集中 ...
- linux 跟踪命令执行过程,Linux的strace命令跟踪线程死锁
strace命令,是Linux提供的跟踪系统调用的命令,需要sudo或root权限,可以查看进程(线程)使用的系统调用. 基本用法:sudo strace -p 进程号 如果一个线程递归获取同一个锁, ...
- linux的kerne启动过程,linux
333.6K http://www.vuse.vanderbilt.edu/~srs/linux-papers-talks/iee-2002.pdf vuse.vanderbilt.edu 全网免费 ...
- linux 内核 面试 机制,请你来说一下linux内核中的Timer 定时器机制
参考回答: 1)低精度时钟 Linux 2.6.16之前,内核只支持低精度时钟,内核定时器的工作方式: 1.系统启动后,会读取时钟源设备(RTC, HPET,PIT-),初始化当前系统时间. 2.内核 ...
- 5. linux操作系统bios启动过程需要执行哪几个操作?,Linux系统启动的大致过程
Linux系统启动的大致过程 Linux操作系统是基于UNIX操作系统发展而来的一种克隆系统,它诞生于1991 年的 [Linux桌面] 10 月5 日.下面小编准备了关于Linux系统启动的大致过程 ...
- Linux 命令的执行过程/Shell提示符/alias命令
在 Linux 系统中"一切皆文件",Linux 命令也不例外.那么,当编辑完成 Linux 命令并回车后,系统底层是怎么执行的? 1) 内核层 内核层是 UNIX/Linux 系 ...
- Linux内核学习:EXT4 文件系统在 Linux 内核系统中的读写过程
目录 1 概述 2 虚拟文件系统 与 Ext4 文件系统 2.1 sys_write( ) 代码跟踪 2.2 sys_write( ) 过程分析 2.3 sys_write( ) 的核心部分 vfs_ ...
最新文章
- 小米和西工大联手,三篇论文被Interspeech接收
- 线程池之CachedThreadPool学习
- python基础知识资料-Python学习--最完整的基础知识大全
- 微信小程序 滚动选项卡 swiper高度自适应
- 向量积判断优劣弧_判断经验论文优劣的10条诫命
- P2327 [SCOI2005]扫雷
- 如何在gradle上仅运行一个测试类
- hibernate java_Hibernate对Java 9的支持
- 不同VPC路由器通过静态路由、动态路由(OSPF)实现网络互通实战
- 后台管理项目系列-(一)--基本的项目搭建
- 零基础安卓手游辅助开发入门视频教程
- idea中使用eclipse快捷键的常用快捷键
- 常见l298n电机驱动的使用方法,简单粗暴,不讲废话。
- 【考研英语语法】名词从句的虚拟、主语从句、WH-形式的引导词引导名词从句
- win10 桌面的的文件都不见了 提示不注销保存都文件都为临时_在桌面上创建一个关机快捷方式,只需一条命令,关机速度大幅提升...
- The 2018 ACM-ICPC Asia Qingdao Regional Contest (Mirror)
- 姗姗来迟,智能音箱于华为是鸡肋还是熊掌?
- HTML 5 音频与视频标签
- STM32硬件SPI通过fm17550读取身份证UID,识别银行卡,识别TYPEA与TYPEB
- win10运行在哪里打开 win10怎么打开运行窗口快捷键
热门文章
- 用sourceTree提交代码时遇到的问题
- oracle易忘函数用法(4)
- Asp.net在线统计人数
- java中的23中设计模式
- 就业模拟试题_Net
- 织梦本地调试运行PHP不显示图片,织梦dedecms不能下载远程图片实现图片本地化解决方法...
- windows环境下tensorflow安装过程详解(亲测安装成功后测试那块)
- php5中Xdebug配置安装步骤介绍
- PHP的运行机制与原理(底层)
- php-fpm 找不到 php-cgi.sock 怎么办