.. include:: OS Primitives: Spinlocks ======================== .. topic:: Documentation * :doc:`../why-os/locking` * Zephyr: Spinlock APIs `__ Producer/Consumer Interrupts ---------------------------- * One interrupt (say a sensor) produces some data * Another (say device-buffer-empty) consumes * |longrightarrow| Parallelism * |longrightarrow| No good! .. literalinclude:: code/do-much-in-isr.cpp :caption: :download:`code/do-much-in-isr.cpp` :language: c++ **IRQ engine internals** .. code-block:: console :caption: In ``why-shell`` > pid 833252 > irqsig 60 .. code-block:: console :caption: In another terminal $ kill -s 60 -q 2 833252 **Or, for short** .. code-block:: console :caption: In ``why-shell`` > irq 2 > #elems: 1 irq 3 > #elems: 0 Problem: Interrupt Parallelism ------------------------------ * Interrupt nesting * Awkward in total * IRQ2 and IRQ3 *are considered parallel* Bombard it: .. code-block:: console $ while true; do echo irq 2; echo irq 3; done|why-shell ./why-spinlocks-do-much-in-isr double free or corruption (fasttop) child died: signal 6, core dumped: 128 Solution: Spinlock ------------------ jjj check this * On a multiprocessor: spin until lock can be had * In schedulable context, disable interrupts on the local CPU * On a single processor: * In schedulable context: disable interrupts, be happy with the lock * In interrupt context: nothing to do - interrupts not disabled, that's enough Bombard it: .. code-block:: console $ while true; do echo irq 2; echo irq 3; done|why-shell ./why-spinlocks-do-much-in-isr-spinlock ... .. literalinclude:: code/do-much-in-isr-spinlock.cpp :caption: :download:`code/do-much-in-isr-spinlock.cpp` :language: c++