Reputation: 13
I am a novice studying Linux kernel, kernel modules and device drivers for operating systems. Can you please help me confirm if the following implementation of a spinlock is correct, If you assume that the multiprocessor system provides sequential consistency?
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();
}
If it's not correct can you provide me with a better example so that i will understand it better? Sorry for not providing any commends or more explantions, it's because i don't fully understand this code that i was given. Thank you in advance for your assistance.
Upvotes: 0
Views: 784
Reputation: 11921
Is this implementation of a spinlock
correct? Not sure but I don't think so as you are asking about spinock
but code you written is about interrupt handling
in kernel. Well up to certain extent you can link them. Read this https://notes.shichao.io/lkd/ch8/#disabling-bottom-halves about interrupts in kernel.
Firstly why to use spinlock()
mechanism ?
API's for spinlock ?
First create the variable of struct spinlock_t
as struct spinlock_t my_slock;
Initialize the my_slock
as spinlock_init(&my_slock);
.
while writing time, put the spin lock by calling spin_lock(&my_slock);
when spin lock seen by reader application, it will wait.
unlock it once done by calling spin_unlock(&my_slock);
Here is the driver program for your reference about how to use 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 : [email protected]");
MODULE_DESCRIPTION("Syn Technique : Spin lock");
By assuming that you know how to create the Makefile for your driver, how to create device file using mknod
or any other method & check dmesg
. Finally write one user application & analyze.
I hope it gives you basic idea about spinlock
.
Upvotes: 1