Linux内核 read_seqretry()

函数:read_seqretry()

函数read_seqretry():读者在访问完被顺序锁s1保护的共享资源后需要调用该函数来检查,在读访问期间是否有写者访问了该共享资源,该检查是通过判断当前顺序锁sl的顺序号与初始顺序号start是否相等实现的。如果不相等,则读访问期间有写者访问了共享资源,读者就需要重新进行读操作,否则,读者成功完成了读操作。

文件包含:

#include <linux/seqlock.h>

函数定义:

在内核源码中的位置:linux-3.19.3/include/linux/seqlock.h

函数定义格式:

static inline unsigned read_seqretry(const seqlock_t *sl, unsigned start)

输入参数说明:

  • sl:指向顺序锁结构体的指针。关于顺序锁结构体seqlock _t的定义及顺序锁的概念参考酷客教程中宏seqlock_init()的分析。

  • start:表示顺序锁的初始顺序号。

返回参数说明:

  • 函数read_seqretry()返回一个无符号整型值,该值一般为1或者0,如果返回1,则读者需要重新进行读操作,返回0,则读者成功完成了读操作。

实例解析:

编写测试文件:read_seqretry.c

头文件及全局变量声明如下:

#include <linux/seqlock.h>
#include <linux/init.h>
#include <linux/module.h>

MODULE_LICENSE("GPL");
static int __init read_seqretry_init(void);
static void __exit read_seqretry_exit(void);
seqlock_t seqlock ;

模块初始化函数:

int __init read_seqretry_init(void)
{
    int ret;
    seqlock_init( &seqlock );                      //初始化顺序锁

    /*一下两行输出顺序锁中自旋锁字段值和顺序锁当前的顺序号*/
    printk("after seqlock_init, sequence: %d\n\n", seqlock.seqcount.sequence);

    write_seqlock( &seqlock );                     //写者申请顺序锁
    printk("after write_seqlock, sequence: %d\n\n", seqlock.seqcount.sequence);

    write_sequnlock( &seqlock );                   //写者释放顺序锁
    printk("after write_sequnlock, sequence: %d\n\n", seqlock.seqcount.sequence);

    do{
        ret = read_seqbegin( &seqlock );
        printk("ret = %d\n", ret );
    }while( read_seqretry(&seqlock, ret) );        //读操作代码块
    return 0;
}

模块退出函数:

void __exit read_seqretry_exit(void)
{
    printk("exit! \n");
}

模块初始化及退出函数调用:

module_init(read_seqretry_init);
module_exit(read_seqretry_exit);

实例运行结果及分析:

首先编译模块,执行命令insmod read_seqretry.ko插入模块,然后执行命令dmesg -c,会出现如图所示的结果。

Linux内核 read_seqretry()

结果分析:

测试程序中调用了宏seqlock_init()和函数write_seqlock()、函数write_sequnlock(),其功能参考酷客教程中关于它们的分析。

读者使用顺序锁的模式一般为:

do{
    ret = read_seqbegin( &seqlock );
    printk("ret = %d\n", ret );
    // 在这里执行读操作…
}while( read_seqretry(&seqlock, ret) );

读者从ret_seqbegin()返回后,得到顺序锁的当前顺序号,并开始执行对共享资源的读操作。如果期间有写者修改了共享资源,则read_seqretry()将返回真,从而使读者重新执行读操作以确保数据的一致性。

在测试程序中读操作代码块缺省,即没有共享资源会被写者获取,因此read_seqretry()返回假,即读者执行一次读操作即成功。另外,对于单处理器体系结构的机器,在执行程序代码中的do…while循环体时,不会出现其他写者修改共享资源的情况,read_seqretry()返回假,读者执行一次读操作即成功。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!