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:
File diff suppressed because it is too large
Load Diff
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
53
4.9.11/examples/example_rwlock.c
Normal file
53
4.9.11/examples/example_rwlock.c
Normal 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");
|
||||
Reference in New Issue
Block a user