可见涉及到系统定时器的数据结构并不多,那么:对于一个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实现过程分析相关推荐

  1. linux搭建一个的过程,Linux内核创建一个新进程的过程

    此文仅用于MOOCLinux内核分析作业 task_struct数据结构 根据wiki的定义,进程是计算机中已运行程序的实体.在面向线程设计的系统(Linux 2.6及更新的版本)中,进程本身不是基本 ...

  2. MBR的Linux分区机制启动过程,linux系统启动流程(MBR)

    总:POST---> Boot Squence ---> Bootloader ---> kernel ---> init ---> 完成启动 系统:CentOS6 1. ...

  3. linux 建立伪目标过程,linux之Makefile 编写、规则、伪目标、变量

    什么是Makefile?首先,make是一个工具程序(Utility software),是一种控制编译或者重复编译软件的工具:make可以自动管理软件编译的内容.方式和时机从而使程序员能够把精力集中 ...

  4. linux 跟踪命令执行过程,Linux的strace命令跟踪线程死锁

    strace命令,是Linux提供的跟踪系统调用的命令,需要sudo或root权限,可以查看进程(线程)使用的系统调用. 基本用法:sudo strace -p 进程号 如果一个线程递归获取同一个锁, ...

  5. linux的kerne启动过程,linux

    333.6K http://www.vuse.vanderbilt.edu/~srs/linux-papers-talks/iee-2002.pdf vuse.vanderbilt.edu 全网免费 ...

  6. linux 内核 面试 机制,请你来说一下linux内核中的Timer 定时器机制

    参考回答: 1)低精度时钟 Linux 2.6.16之前,内核只支持低精度时钟,内核定时器的工作方式: 1.系统启动后,会读取时钟源设备(RTC, HPET,PIT-),初始化当前系统时间. 2.内核 ...

  7. 5. linux操作系统bios启动过程需要执行哪几个操作?,Linux系统启动的大致过程

    Linux系统启动的大致过程 Linux操作系统是基于UNIX操作系统发展而来的一种克隆系统,它诞生于1991 年的 [Linux桌面] 10 月5 日.下面小编准备了关于Linux系统启动的大致过程 ...

  8. Linux 命令的执行过程/Shell提示符/alias命令

    在 Linux 系统中"一切皆文件",Linux 命令也不例外.那么,当编辑完成 Linux 命令并回车后,系统底层是怎么执行的? 1) 内核层 内核层是 UNIX/Linux 系 ...

  9. Linux内核学习:EXT4 文件系统在 Linux 内核系统中的读写过程

    目录 1 概述 2 虚拟文件系统 与 Ext4 文件系统 2.1 sys_write( ) 代码跟踪 2.2 sys_write( ) 过程分析 2.3 sys_write( ) 的核心部分 vfs_ ...

最新文章

  1. 小米和西工大联手,三篇论文被Interspeech接收
  2. 线程池之CachedThreadPool学习
  3. python基础知识资料-Python学习--最完整的基础知识大全
  4. 微信小程序 滚动选项卡 swiper高度自适应
  5. 向量积判断优劣弧_判断经验论文优劣的10条诫命
  6. P2327 [SCOI2005]扫雷
  7. 如何在gradle上仅运行一个测试类
  8. hibernate java_Hibernate对Java 9的支持
  9. 不同VPC路由器通过静态路由、动态路由(OSPF)实现网络互通实战
  10. 后台管理项目系列-(一)--基本的项目搭建
  11. 零基础安卓手游辅助开发入门视频教程
  12. idea中使用eclipse快捷键的常用快捷键
  13. 常见l298n电机驱动的使用方法,简单粗暴,不讲废话。
  14. 【考研英语语法】名词从句的虚拟、主语从句、WH-形式的引导词引导名词从句
  15. win10 桌面的的文件都不见了 提示不注销保存都文件都为临时_在桌面上创建一个关机快捷方式,只需一条命令,关机速度大幅提升...
  16. The 2018 ACM-ICPC Asia Qingdao Regional Contest (Mirror)
  17. 姗姗来迟,智能音箱于华为是鸡肋还是熊掌?
  18. HTML 5 音频与视频标签
  19. STM32硬件SPI通过fm17550读取身份证UID,识别银行卡,识别TYPEA与TYPEB
  20. win10运行在哪里打开 win10怎么打开运行窗口快捷键

热门文章

  1. 用sourceTree提交代码时遇到的问题
  2. oracle易忘函数用法(4)
  3. Asp.net在线统计人数
  4. java中的23中设计模式
  5. 就业模拟试题_Net
  6. 织梦本地调试运行PHP不显示图片,织梦dedecms不能下载远程图片实现图片本地化解决方法...
  7. windows环境下tensorflow安装过程详解(亲测安装成功后测试那块)
  8. php5中Xdebug配置安装步骤介绍
  9. PHP的运行机制与原理(底层)
  10. php-fpm 找不到 php-cgi.sock 怎么办