1
0
mirror of https://github.com/bashrc/LKMPG.git synced 2018-06-11 03:06:54 +02:00

Read/write locks

This commit is contained in:
Bob Mottram
2017-03-31 10:27:10 +01:00
parent de9fac26db
commit 1caec63527
4 changed files with 443 additions and 263 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -2743,6 +2743,65 @@ MODULE_DESCRIPTION("Spinlock example");
MODULE_LICENSE("GPL");
#+end_src
*** Read and write locks
Read and write locks are specialised kinds of spinlocks so that you can exclusively read from something or write to something. Like the earlier spinlocks example the one below shows an "irq safe" situation in which if other functions were triggered from irqs which might also read and write to whatever you are concerned with then they wouldn't disrupt the logic. As before it's a good idea to keep anything done within the lock as short as possible so that it doesn't hang up the system and cause users to start revolting against the tyranny of your module.
#+begin_src C file:example_rwlock.c
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
DEFINE_RWLOCK(myrwlock);
static void example_read_lock(void)
{
unsigned long flags;
read_lock_irqsave(&myrwlock, flags);
printk("Read Locked\n");
/* Read from something */
read_unlock_irqrestore(&myrwlock, flags);
printk("Read Unlocked\n");
}
static void example_write_lock(void)
{
unsigned long flags;
write_lock_irqsave(&myrwlock, flags);
printk("Write Locked\n");
/* Write to something */
write_unlock_irqrestore(&myrwlock, flags);
printk("Write Unlocked\n");
}
static int example_rwlock_init(void)
{
printk("example_rwlock started\n");
example_read_lock();
example_write_lock();
return 0;
}
static void example_rwlock_exit(void)
{
printk("example_rwlock exit\n");
}
module_init(example_rwlock_init);
module_exit(example_rwlock_exit);
MODULE_AUTHOR("Bob Mottram");
MODULE_DESCRIPTION("Read/Write locks example");
MODULE_LICENSE("GPL");
#+end_src
* Replacing Printks
** Replacing printk
In Section 1.2.1.2, I said that X and kernel module programming don't mix. That's true for developing kernel modules, but in actual use, you want to be able to send messages to whichever tty[fn:15] the command to load the module came from.

View File

@@ -24,6 +24,7 @@ obj-m += completions.o
obj-m += example_tasklet.o
obj-m += devicemodel.o
obj-m += example_spinlock.o
obj-m += example_rwlock.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

View File

@@ -0,0 +1,53 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
DEFINE_RWLOCK(myrwlock);
static void example_read_lock(void)
{
unsigned long flags;
read_lock_irqsave(&myrwlock, flags);
printk("Read Locked\n");
/* Read from something */
read_unlock_irqrestore(&myrwlock, flags);
printk("Read Unlocked\n");
}
static void example_write_lock(void)
{
unsigned long flags;
write_lock_irqsave(&myrwlock, flags);
printk("Write Locked\n");
/* Write to something */
write_unlock_irqrestore(&myrwlock, flags);
printk("Write Unlocked\n");
}
static int example_rwlock_init(void)
{
printk("example_rwlock started\n");
example_read_lock();
example_write_lock();
return 0;
}
static void example_rwlock_exit(void)
{
printk("example_rwlock exit\n");
}
module_init(example_rwlock_init);
module_exit(example_rwlock_exit);
MODULE_AUTHOR("Bob Mottram");
MODULE_DESCRIPTION("Read/Write locks example");
MODULE_LICENSE("GPL");