Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Using Spinlocks and Mutexes | Interrupts, Timing, and Concurrency
Practice
Projects
Quizzes & Challenges
Quizze
Challenges
/
C Device Drivers Basics

bookUsing Spinlocks and Mutexes

Spinlocks and mutexes are two fundamental synchronization primitives used in kernel development to protect shared data from concurrent access. A spinlock is a lightweight lock where a thread repeatedly checks if the lock is available, "spinning" in a tight loop until it can acquire the lock. This is efficient in short, non-blocking critical sections, especially in contexts where sleeping is not allowed, such as interrupt handlers. A mutex (short for "mutual exclusion") is a heavier-weight lock that can put the thread to sleep if the lock is not available, making it suitable for longer critical sections where sleeping is allowed, such as process context.

spinlock_interrupt_example.c

spinlock_interrupt_example.c

copy
12345678910111213141516171819202122232425262728293031323334353637
#include <linux/module.h> #include <linux/kernel.h> #include <linux/interrupt.h> #include <linux/spinlock.h> static spinlock_t my_lock; static int shared_data = 0; irqreturn_t my_interrupt_handler(int irq, void *dev_id) { unsigned long flags; // Acquire spinlock and save interrupt state spin_lock_irqsave(&my_lock, flags); shared_data++; spin_unlock_irqrestore(&my_lock, flags); return IRQ_HANDLED; } static int __init spinlock_example_init(void) { spin_lock_init(&my_lock); // Normally you would request an IRQ here and register my_interrupt_handler pr_info("Spinlock interrupt example loaded\n"); return 0; } static void __exit spinlock_example_exit(void) { pr_info("Spinlock interrupt example unloaded\n"); } module_init(spinlock_example_init); module_exit(spinlock_example_exit); MODULE_LICENSE("GPL");

You should use a spinlock, as shown in the code above, when you need to protect shared data in interrupt context or any context where sleeping is not allowed. Spinlocks are designed for short, quick operations and do not cause the current context to sleep, making them ideal for interrupt handlers. Mutexes, on the other hand, can sleep and are only safe to use in process context, where sleeping is permitted. If you try to use a mutex in an interrupt handler, you may cause a deadlock or crash, since mutexes may block the current context.

mutex_process_example.c

mutex_process_example.c

copy
1234567891011121314151617181920212223242526272829303132333435363738
// mutex_process_example.c #include <linux/module.h> #include <linux/kernel.h> #include <linux/mutex.h> #include <linux/fs.h> static DEFINE_MUTEX(my_mutex); static int shared_resource = 0; ssize_t my_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { ssize_t ret = 0; if (mutex_lock_interruptible(&my_mutex)) return -ERESTARTSYS; shared_resource++; mutex_unlock(&my_mutex); ret = count; return ret; } static int __init mutex_example_init(void) { pr_info("Mutex process example loaded\n"); return 0; } static void __exit mutex_example_exit(void) { pr_info("Mutex process example unloaded\n"); } module_init(mutex_example_init); module_exit(mutex_example_exit); MODULE_LICENSE("GPL");
question mark

Which synchronization primitive should be used in interrupt context: spinlock or mutex?

Select the correct answer

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 4. Kapitel 3

Fragen Sie AI

expand

Fragen Sie AI

ChatGPT

Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen

bookUsing Spinlocks and Mutexes

Swipe um das Menü anzuzeigen

Spinlocks and mutexes are two fundamental synchronization primitives used in kernel development to protect shared data from concurrent access. A spinlock is a lightweight lock where a thread repeatedly checks if the lock is available, "spinning" in a tight loop until it can acquire the lock. This is efficient in short, non-blocking critical sections, especially in contexts where sleeping is not allowed, such as interrupt handlers. A mutex (short for "mutual exclusion") is a heavier-weight lock that can put the thread to sleep if the lock is not available, making it suitable for longer critical sections where sleeping is allowed, such as process context.

spinlock_interrupt_example.c

spinlock_interrupt_example.c

copy
12345678910111213141516171819202122232425262728293031323334353637
#include <linux/module.h> #include <linux/kernel.h> #include <linux/interrupt.h> #include <linux/spinlock.h> static spinlock_t my_lock; static int shared_data = 0; irqreturn_t my_interrupt_handler(int irq, void *dev_id) { unsigned long flags; // Acquire spinlock and save interrupt state spin_lock_irqsave(&my_lock, flags); shared_data++; spin_unlock_irqrestore(&my_lock, flags); return IRQ_HANDLED; } static int __init spinlock_example_init(void) { spin_lock_init(&my_lock); // Normally you would request an IRQ here and register my_interrupt_handler pr_info("Spinlock interrupt example loaded\n"); return 0; } static void __exit spinlock_example_exit(void) { pr_info("Spinlock interrupt example unloaded\n"); } module_init(spinlock_example_init); module_exit(spinlock_example_exit); MODULE_LICENSE("GPL");

You should use a spinlock, as shown in the code above, when you need to protect shared data in interrupt context or any context where sleeping is not allowed. Spinlocks are designed for short, quick operations and do not cause the current context to sleep, making them ideal for interrupt handlers. Mutexes, on the other hand, can sleep and are only safe to use in process context, where sleeping is permitted. If you try to use a mutex in an interrupt handler, you may cause a deadlock or crash, since mutexes may block the current context.

mutex_process_example.c

mutex_process_example.c

copy
1234567891011121314151617181920212223242526272829303132333435363738
// mutex_process_example.c #include <linux/module.h> #include <linux/kernel.h> #include <linux/mutex.h> #include <linux/fs.h> static DEFINE_MUTEX(my_mutex); static int shared_resource = 0; ssize_t my_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { ssize_t ret = 0; if (mutex_lock_interruptible(&my_mutex)) return -ERESTARTSYS; shared_resource++; mutex_unlock(&my_mutex); ret = count; return ret; } static int __init mutex_example_init(void) { pr_info("Mutex process example loaded\n"); return 0; } static void __exit mutex_example_exit(void) { pr_info("Mutex process example unloaded\n"); } module_init(mutex_example_init); module_exit(mutex_example_exit); MODULE_LICENSE("GPL");
question mark

Which synchronization primitive should be used in interrupt context: spinlock or mutex?

Select the correct answer

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 4. Kapitel 3
some-alt