LinuxGod.net
Linux大神网——精选每一篇高品质的技术干货
  1. 首页
  2. 开源快讯
  3. 正文

10.5内核定时器编程TIMER_SOFTIRQ软中断,运行当前处理器CPU上到期的所有定时器

2022年12月13日 147点热度

10.5内核定时器

10.5.1内核定时器编程

TIMER_SOFTIRQ软中断linux内核定时器综述,运行当前处理器CPU上到期的所有定时器。

enum

{

HI_SOFTIRQ=0,

TIMER_SOFTIRQ,

NET_TX_SOFTIRQ,

NET_RX_SOFTIRQ,

BLOCK_SOFTIRQ,

BLOCK_IOPOLL_SOFTIRQ,

TASKLET_SOFTIRQ,

SCHED_SOFTIRQ,

HRTIMER_SOFTIRQ,

NR_SOFTIRQS

};

Linux内核所提供的用于操作定时器的数据结构和函数如下:

1.timer_list

在Linux内核中,timer_list结构体的一个实例对应一个定时器,如代码清单10.9所示。

代码清单10.9timer_list结构体

#include

struct timer_list {

/*

* All fields that change during normal runtime grouped to the

* same cacheline

*/

struct list_head entry;

unsigned long expires; // 到期时间

struct tvec_base *base;

void (*function)(unsigned long);

unsigned long data;

int slack;

#ifdef CONFIG_TIMER_STATS

int start_pid;

void *start_site;

char start_comm[16];

#endif

#ifdef CONFIG_LOCKDEP

struct lockdep_map lockdep_map;

#endif

};

function()成员被执行,而data成员则是传入function()函数的参数,expires则是定时器到期的时间(单位:jiffies)。

定义一个名为timer的定时器:

struct timer_list timer;

2.初始化定时器

init_timer是一个宏,

#define init_timer(timer)

__init_timer((timer), 0)

TIMER_INITIALIZER(_function,_expires,_data)宏用于赋值定时器结构体的function、expires、data和base成员。

#define __TIMER_INITIALIZER(_function, _expires, _data, _flags) {

.entry = { .prev = TIMER_ENTRY_STATIC },

.function = (_function),

.expires = (_expires),

.data = (_data),

.base = (void *)(__TIMER_BASE(_flags)),

.slack = -1,

__TIMER_LOCKDEP_MAP_INITIALIZER(

__FILE__ ":" __stringify(__LINE__))

}

#define TIMER_INITIALIZER(_function, _expires, _data)

__TIMER_INITIALIZER((_function), (_expires), (_data), 0)

DEFINE_TIMER(_namelinux系统下载,_function,_expires,_data)宏是定义并初始化定时器成员的“快捷方式”,这个宏定义为:

#define DEFINE_TIMER(_name, _function, _expires, _data)

struct timer_list _name =

TIMER_INITIALIZER(_function, _expires, _data)

setup_timer()也可用于初始化定时器并赋值其成员,其源代码为:

#define __setup_timer(_timer, _fn, _data, _flags)

do {

__init_timer((_timer), (_flags));

(_timer)->function = (_fn);

(_timer)->data = (_data);

} while (0)

#define setup_timer(timer, fn, data)

__setup_timer((timer), (fn), (data), 0)

3.增加定时器

void add_timer(struct timer_list * timer);

该函数用于注册内核定时器,将定时器加入到内核动态定时器链表中。

4.删除定时器

int del_timer(struct timer_list * timer);

该函数函数用于删除定时器。

del_timer_sync()是del_timer()的同步版,在删除一个定时器时需等待其被处理完,该函数的调用不能发生在中断上下文中。

5.修改定时器的expire(到期时间)

int mod_timer(struct timer_list *timer, unsigned long expires);

该函数用于修改定时器的到期时间,在新的被传入的expires到来后才会执行定时器函数。

该函数的定义在kernel/time/timer.c

/**

int mod_timer(struct timer_list *timer, unsigned long expires)

{

expires = apply_slack(timer, expires);

/*

* This is a common optimization triggered by the

* networking code - if the timer is re-modified

* to be the same thing then just return:

*/

if (timer_pending(timer) && timer->expires == expires)

return 1;

return __mod_timer(timer, expires, false, TIMER_NOT_PINNED);

}

EXPORT_SYMBOL(mod_timer);

代码清单10.10内核定时器使用模板

/* 定时器处理函数 */static void xxx_do_timer(unsigned long arg){}{

/* 设备结构体指针作为定时器处理函数参数 */

将定时器加入到内核动态定时器链表中

}

/* xxx驱动中的某函数 */

xxx_func2(…)

{

}

此外,Linux内核支持tickless(无滴答)和NO_HZ模式后,内核也包含对hrtimer(高精度定时器)的支持,可以支持到微秒级别的精度。

内核也定义了hrtimer结构体,

/**

timerqueue node, which also manages node.expires,

the absolute expiry time in the hrtimers internal

representation. The time is related to the clock on

which the timer is based. Is setup by adding

slack to the _softexpires value. For non range timers

identical to _softexpires.

The time which was given as expiry time when the timer

was armed.

timer expiry callback function

pointer to the timer base (per cpu and per clock)

state information (See bit values above)

started the timer

timer statistics field to store the site where the timer

was started

started the timer

struct hrtimer {

struct timerqueue_nodenode;

ktime_t_softexpires;

enum hrtimer_restart(*function)(struct hrtimer *);

struct hrtimer_clock_base*base;

unsigned longstate;

#ifdef CONFIG_TIMER_STATS

intstart_pid;

void*start_site;

charstart_comm[16];

#endif

};

hrtimer_set_expires()、hrtimer_start_expires()、hrtimer_forward_now()、hrtimer_restart()等类似的API来完成hrtimer的设置、时间推移以及到期回调。

代码清单10.11内核高精度定时器(hrtimer)使用模板

struct imx_pcm_runtime_data {

......

struct hrtimer hrt; // 内核高精度定时器

......

};

static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)iprtd->poll_time_ns));//把hrtimer的时间前移了iprtd->poll_time_ns纳秒HRTIMER_RESTART;

static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)

{SNDRV_PCM_TRIGGER_START:iprtd->poll_time_ns),

}

static int snd_imx_open(struct snd_pcm_substream *substream)

{

......

hrtimer_init(&iprtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); /* 初始化高精度定时器 */

iprtd->hrt.function = snd_hrtimer_callback; /* 指定回调函数 */

return 0;

}

static int snd_imx_close(struct snd_pcm_substream *substream)

{

}

10.5.2内核中延迟的工作delayed_work

对于周期性的任务,除定时器外,在Linux内核中还可利用一套封装得很好的快捷机制,这套快捷机制就是延迟工作delayed_work,其本质利用工作队列和定时器实现。

delayed_work结构体的定义:

struct delayed_work {

};

通过如下函数调度一个delayed_work在指定的延时后执行:

/**

static inline boolschedule_delayed_work(struct delayed_work *dwork,

unsigned longdelay)

{

return queue_delayed_work(system_wq, dwork, delay);

}

当指定的delay到来时,struct delayed_work结构体中的work成员work_func_t类型成员func()会被执行。

work_func_t类型定义为:

typedef void (*work_func_t)(struct work_struct *work); // 函数指针类型

其中linux内核定时器综述,delay参数的单位是jiffieslinux find,一种常见的用法如下:

schedule_delayed_work(&work, msecs_to_jiffies(poll_interval));

msecs_to_jiffies()用于将毫秒转化为jiffies。

如果要周期性地执行任务,通常会在delayed_work的工作函数中再次调用schedule_delayed_work(),周而复始。

用来取消delayed_work的函数:

extern bool cancel_delayed_work(struct delayed_work *dwork);

extern bool cancel_delayed_work_sync(struct delayed_work *dwork);

这两个函数定义在kernel/workqueue.c

/**

bool cancel_delayed_work(struct delayed_work *dwork)

{

unsigned long flags;

int ret;

do {

ret = try_to_grab_pending(&dwork->work, true, &flags);

} while (unlikely(ret == -EAGAIN));

if (unlikely(ret < 0))

return false;

set_work_pool_and_clear_pending(&dwork->work,

get_work_pool_id(&dwork->work));

local_irq_restore(flags);

return ret;

}

EXPORT_SYMBOL(cancel_delayed_work);

/**

bool cancel_delayed_work_sync(struct delayed_work *dwork)

{

return __cancel_work_timer(&dwork->work, true);

}

EXPORT_SYMBOL(cancel_delayed_work_sync);

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: linux定时器 work 定时器 软中断
最后更新:2022年12月13日

Linux大神网

每日更新,欢迎收藏♥ 不积跬步无以至千里,加油,共勉。

点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论

Linux大神网

每日更新,欢迎收藏♥
不积跬步无以至千里,加油,共勉。

最新 热点 随机
最新 热点 随机
阿里云>社区>主题地图S>查看存储推荐 Linux的内核放在了哪里?/boot的启动目录一览 Linux中修改文件权限的命令、创建者所在组、所有人 linux到底难不难学呢?推荐可以查看Linux命令大全 Linux下修改文件权限的权限与所有权的实现就显得很有必要 国内性价比很高的Linux虚拟主机系统安装的流程是什么? 1.Linux磁盘分区和目录Linux发行版本之间的差别很少? 基于命令修改文件的权限命令-ld 学习Linux最简单、最实用的环境就是虚拟机环境(上) 计算机是如何启动的?、内核操作系统的启动流程 一个免费软件时间跟进的小白鼠是什么鬼?专题 如何在Linux上安装虚拟机的结果大多都是怎么安装的 Linux启动过程中的几个部分内核的引导(图) 指令中各个make-C~/linuxM=`pwd编译 虚拟机安装Ubuntu操作系统-Ubuntu空间20G镜像下载 启动第一步--加载BIOS当你打开计算机电源(组图) 个人笔记本安装Ubuntu20.04LTS下载地址 腾讯云服务器上也搭建一套环境,安装成功自动启动 go语言被称作互联网时代的c语言,用来开发嵌入式linux的理由 Linux5.12的推送请求不断涌入新开放的合并窗口预计4月底看到它的稳定版本
Linux5.12的推送请求不断涌入新开放的合并窗口预计4月底看到它的稳定版本Linux自主访问控制机制模块详细分析:网络安全标准资料go语言被称作互联网时代的c语言,用来开发嵌入式linux的理由【指南】Linux中网络接口卡的10种方法使用腾讯云服务器上也搭建一套环境,安装成功自动启动Linux线程的操作、多线程的同步和互斥的基本单位个人笔记本安装Ubuntu20.04LTS下载地址RedHatLinux-安装MySQL入门到精通启动第一步--加载BIOS当你打开计算机电源(组图)内核为什么需要内核线程Linux内核可以看作一个服务进程?虚拟机安装Ubuntu操作系统-Ubuntu空间20G镜像下载再传到linux2.配置数据库的环境和路径3.登陆数据库修改指令中各个make-C~/linuxM=`pwd编译Linux内核页表管理中那些鲜为人知的作用是什么?(图)Linux启动过程中的几个部分内核的引导(图)Linux常用应用工具软件安装管理——RedHatEnterprise存储库如何在Linux上安装虚拟机的结果大多都是怎么安装的如需最新mainline内核版本下载并安装新版本删除旧内核一个免费软件时间跟进的小白鼠是什么鬼?专题关于Linux系统版本命令的一些看法及解决办法的通知
学习Linux的8个简单教程,开始你的Linux之旅 你没有装系统,你装了系统就可以用了 TP-LINK全能无线网卡驱动分享 linux中添加ftp用户,并设置相应的权限,怎么上传目录? u盘无密码移动版livepersistencepersistence制作u盘有密码 --version安装git版本太老-yinstallgit 《深入linux设备驱动程序内核机制》(1)_社会万象_光明网(图) Windows中可以安装linux子系统,效率秒杀虚拟机,轻松使用生信软件 Linux计算机上摆弄那些软件的软件,你知道吗? Linux中的显示管理器是桌面环境的一部分吗?(组图) 10.5内核定时器编程TIMER_SOFTIRQ软中断,运行当前处理器CPU上到期的所有定时器 完后,目录可以自动生成,如何生成可参考右边的帮助 更为丰富多彩快手直播伴侣app是一款爱看什么视频就能将视頻 GBK乱码的样子有哪些?乱码是怎么回事? 【写在前面】C/C++内存的价值是什么都不知道 VR物联网智能家居实训套件你能get的技能精致并不是 CentOS8虚拟机的网络设置对话框的解决方法和解决办法 SteelEyeLifeKeeper集群软件关键特性企业数据中心 AMDCPU微码更新可能会执行每个线程的微码更新 Linux下程序的存放目录和安装目录
标签聚合
命令模式 linux服务器 sudo unix 虚拟机 软件 linux系统 文件目录 shell 电脑
书籍
课程
技术群
技术干货大合集↓
  • 2023年1月 / 150篇
  • 2022年12月 / 187篇
  • 2022年11月 / 76篇

COPYRIGHT © 2023 linuxgod.net ALL RIGHTS RESERVED.