这个螺旋锁的实现是否正确?

时间:2018-06-04 10:43:20

标签: linux operating-system implementation sequential spinlock

我是一名研究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();
}

如果不正确你能为我提供一个更好的例子,以便我能更好地理解它吗?很抱歉没有提供任何表扬或更多解释,这是因为我不完全理解我给出的这段代码。提前感谢您的协助。

1 个答案:

答案 0 :(得分:1)

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

首先,为什么要使用interrupt handling机制?

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

自旋锁的API?

  • 首先将spinlock()的变量创建为struct spinlock_t

  • struct spinlock_t my_slock;初始化为my_slock

  • 在写作时,通过调用spinlock_init(&my_slock);来设置自旋锁 当读者应用程序看到旋转锁时,它会等待。

  • 通过致电spin_lock(&my_slock);

  • 解锁

以下是有关如何使用spin_unlock(&my_slock);的参考的驱动程序。

spinlock

假设您知道如何为驱动程序创建Makefile,如何使用#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"); 或任何其他方法创建设备文件&amp;检查mknod。最后写一个用户应用程序&amp;分析

我希望它能为您提供有关dmesg的基本概念。