【问题标题】:Is this implementation of a spinlock correct?这种自旋锁的实现是否正确?
【发布时间】:2018-11-13 16:21:29
【问题描述】:

我是一名学习 Linux 内核、内核模块和操作系统设备驱动程序的新手。您能否帮我确认以下自旋锁的实现是否正确,如果您假设多处理器系统提供顺序一致性?

struct Lock{
        int locked;
    }

int exchange_value(int* ptr, int val){
    int was;
    wss=*ptr;
    *ptr=val;
    return was;
}
voidacquire(Lock *lock){
    local_irq_disable();
    while(1){
        if(exchange_value(&lock->locked, 1) == 0)
        break;
    }
}

void release(Lock *lock){
    exchange_value(&lock->locked, 0);
    local_irq_enable();
}

如果不正确,您能否提供一个更好的示例,以便我更好地理解它?很抱歉没有提供任何赞扬或更多解释,这是因为我不完全理解我得到的这段代码。预先感谢您的协助。

【问题讨论】:

    标签: linux operating-system implementation sequential spinlock


    【解决方案1】:

    spinlock 的这种实现是否正确? 不确定,但我不这么认为,因为您询问的是 spinock,但您编写的代码是关于内核中的 interrupt handling。在某种程度上,您可以将它们链接起来。阅读这篇关于内核中断的https://notes.shichao.io/lkd/ch8/#disabling-bottom-halves

    首先为什么要使用spinlock()机制?

    • 简单的答案是在中断处理程序中实现同步。
    • 如果锁可用,进程将获取它并在关键部分继续并解锁它,一旦完成。这类似于互斥锁。
    • 但是,如果锁不可用怎么办?有趣的区别来了。使用互斥锁,进程将休眠,直到锁可用。但是,在自旋锁的情况下,它会进入紧密循环,不断检查锁,直到可用为止。
    • 这是自旋锁的旋转部分。这是为多处理器系统设计的。

    自旋锁的 API ?

    • 首先创建struct spinlock_t的变量为struct spinlock_t my_slock;

    • my_slock初始化为spinlock_init(&my_slock);

    • 在写入时间时,通过调用spin_lock(&my_slock); 来放置自旋锁 当阅读器应用程序看到自旋锁时,它将等待。

    • 调用spin_unlock(&my_slock);完成后解锁

    这里是spinlock的使用驱动程序供大家参考。

    #include <linux/module.h>
    #include <linux/fs.h>
    #include <asm/uaccess.h>
    #include <linux/spinlock.h>
    #include <linux/delay.h>
    static int major;
    static spinlock_t slock;
    static unsigned int pwait = 10000;
    module_param(pwait, int, 0);
    /* Default delay is 10 seconds */
    /* MilliSeconds */
    static int spin_open(struct inode *inode, struct file *filp) {
            return 0;
    }
    static int spin_close(struct inode *inode, struct file *filp) {
            return 0;
    }
    static ssize_t spin_read(struct file *filp, char __user *buf,size_t sz, loff_t *fpos) {/* main is read function */
            printk("Read begins: Trying to aquire same spinlock\n");
            spin_lock( &slock ); /* applied the lock .. when reader apps seen it, it will wait */
            printk("Read : Acquired spinlock now !!\n");
            printk("Read done. Releasing the spinlock\n");
            spin_unlock( &slock );
            return 0;
    }
    static ssize_t spin_write( struct file *filp, const char __user *buf,size_t sz, loff_t *fpos )
    {
            printk("Write begins\n");
            spin_lock( &slock );
            printk("Write : Acquired a spinlock...\n");
            mdelay( pwait );
            /* Pretending to do some work */
            printk("Write done. Releasing the spinlock\n");
            spin_unlock( &slock );
            return sz;
    }
    static struct file_operations spin_fops = {
            .open = spin_open,
            .release = spin_close,
            .read = spin_read,
            .write = spin_write,
            .owner = THIS_MODULE,
    };
    static int __init start(void) {
            major = register_chrdev(0, "spin", &spin_fops);
            if ( major < 0 ) {
                    printk("Error obtaining major number\n");
                    return -1;
            }
            else {
                    printk("Successfully registered major number %d\n",major);
                    printk("create device name = spin \n");
            }
            spin_lock_init( &slock );
            return 0;
    }
    void stop(void){
            pr_info("module unregistered successfully \n");
            unregister_chrdev(major, "spin");
    }
    module_init(start);
    module_exit(stop);
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("achal singh : mail2inda@gmail.com");
    MODULE_DESCRIPTION("Syn Technique : Spin lock");
    

    假设您知道如何为您的驱动程序创建 Makefile,如何使用mknod 或任何其他方法创建设备文件并检查dmesg。最后编写一个用户应用程序并进行分析。

    我希望它能给你关于spinlock的基本概念。

    【讨论】:

    猜你喜欢
    • 2020-03-27
    • 2017-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-12
    • 1970-01-01
    • 2018-02-08
    • 1970-01-01
    相关资源
    最近更新 更多