Linux内核API init_timer_on_stack_key

init_timer_on_stack_key函数功能描述:函数init_timer_on_stack_key( )用于初始化struct timer_list变量,将此结构体变量存储的定时器插入到系统内核定时器模块中,并确定由哪个CPU处理及定时器类型。

如果内核中有CONFIG_DEBUG_OBJECTS_TIMERS的定义,则函数init_timer_on_stack_key( )调用函数debug_object_init_on_stack( )和函数do_init_timer( )实现对struct timer_list类型变量的初始化,否则就调用函数init_timer_key( )实现对struct timer_list类型变量的初始化。

init_timer_on_stack_key文件包含

#include<linux/timer.h>

init_timer_on_stack_key函数定义

在内核源码中的位置:linux-3.19.3/include/linux/timer.h, linux-3.19.3/kernel/time/timer.c

函数定义格式:

#ifdef CONFIG_DEBUG_OBJECTS_TIMERS
    extern void init_timer_on_stack_key(struct timer_list *timer, unsigned int flags, const char *name, struct lock_class_key *key);
#else
    static inline void init_timer_on_stack_key(struct timer_list *timer, unsigned int flags, const char *name, struct lock_class_key *key)
{
    init_timer_key(timer, flags, name, key);
}
#endif

void init_timer_on_stack_key(struct timer_list *timer,   u n s i g n e d  i n t  f l a g s,const char *name, struct lock_class_key *key)
{
    debug_object_init_on_stack(timer, &timer_debug_descr);
    do_init_timer(timer, flags, name, key);
}

init_timer_on_stack_key输入参数说明

  • 第一个参数是struct timer_list类型的变量,此变量用于存放动态定时器,其定义及详细解释参考add_timer( )分析文档的输入参数说明部分。
  • 第二个参数是unsigned int类型变量,指定定时器类型,定时器类型参考函数init_timer_deferrable( )的说明。
  • 第三个参数是char型的指针,代表初始化的定时器的名称,在此测试程序中没有实际意义。
  • 第四个参数是struct lock_class_key类型的变量,用于设定定时器的自旋锁的类型,在此测试程序中传入的是NULL,用于设定自旋锁为打开状态。

init_timer_on_stack_key返回参数说明

此函数的返回值是void类型的变量,即函数不返回任何结果。

init_timer_on_stack_key实例解析

编写测试文件:init_timer_on_stack_key.c

头文件引用及全局变量声明:

#include <linux/module.h>
#include<linux/timer.h>
MODULE_LICENSE("GPL");
struct timer_list my_timer;      //定义一个静态全局变量

定时器到期处理函数:

// 自定义一个定时器函数,此函数在此只有输出的功能
void my_timer_function(unsigned long data)
{
    printk("In the my_timer_function\n");
    printk("the jiffies is :%ld\n", jiffies);     //显示当前节拍数
    struct timer_list *mytimer = (struct timer_list *)data;
    printk("the expries of my_timer is :%ld\n", mytimer->expires);
                                                  // 显示expires字段的值
    printk("the base of my_timer is:%u\n", (unsigned int)mytimer->base);
                                                  // 显示base字段的值
}

定时器初始化、模块加载函数定义:

int __init init_timer_on_stack_key_init(void)
{
    printk("my_timer will be created.\n");
    printk("the jiffies is :%ld\n", jiffies);     //显示当前节拍数
    init_timer_on_stack_key(&my_timer, TIMER_DEFERRABLE, "my_timer", NULL);
                                                  // 调用init_timer初始化变量

    // HZ=250;初始化字段expires,使其值在当前节拍的基础上增加250个节拍
    my_timer.expires = jiffies + 1*HZ;
    my_timer.data = &my_timer;             //初始化字段data,其值指向变量的地址
    my_timer.function = my_timer_function; //初始化字段function,其值是自定义的定时器函数
    add_timer(&my_timer); //调用函数add_timer( )将变量插入合适的动态定时器队列,激活定时器
    printk("my_timer init.\n");
    return 0;
}

模块退出函数定义:

void __exit init_timer_on_stack_key_exit(void)
{
    printk("Goodbye init_timer_on_stack_key\n");
    del_timer(&my_timer);  //删除定时器变量
}

模块加载及退出函数调用:

module_init(init_timer_on_stack_key_init);
module_exit(init_timer_on_stack_key_exit);

实例运行结果及分析:

执行命令insmod init_timer_on_stack_key.ko插入模块,然后输入命令dmesg -c查看内核输出信息,出现如图所示结果。

Linux内核API init_timer_on_stack_key

结果分析:

由运行结果可知函数init_timer_on_stack_key( )能够完成定时器变量的初始化。

赞(0)
未经允许不得转载:极客笔记 » Linux内核API init_timer_on_stack_key
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址