Правильна ли эта реализация спин-блокировки? - PullRequest
0 голосов
/ 04 июня 2018

Я новичок в изучении ядра 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 голосов
/ 04 июня 2018

Является ли эта реализация 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.

...