I-pipe spinlocks
有时需要在实时域和Linux域之间共享spinlocks. 我们在"Hardware timer", "Interrupt controller" 和 "GPIOs" section有谈到.
但是, 注意, 这不是一剂灵丹妙药, 必须注意在保持自旋锁时不能调用任何Linux服务,或其他任何可能导致极大时间的处理, 不然,你将冒打破实时性的风险.
Xenomai提供了一些宏来将spinlock转换成一个I-pipe spinlock.
Linux code | Should be replaced with |
extern raw_spinlock_t foo |
IPIPE_DECLARE_RAW_SPINLOCK(foo) |
DEFINE_RAW_SPINLOCK(foo) |
IPIPE_DEFINE_RAW_SPINLOCK(foo) |
extern spinlock_t foo |
IPIPE_DECLARE_SPINLOCK(foo) |
DEFINE_SPINLOCK(foo) |
IPIPE_DEFINE_SPINLOCK(foo)
|
例如, 在 arch/arm/common/gic.c
static DEFINE_SPINLOCK(irq_controller_lock);
替换成:
static IPIPE_DEFINE_SPINLOCK(irq_controller_lock);
同时, 除了通常的 spin_lock, spin_unlock,spin_lock_irqsave, spin_unlock_irqrestore之外, I-pipe 核也提供了 spin_lock_irqsave_cond, spin_unlock_irqrestore_cond. 这两个宏会在I-pipe核使能的情况下被替换成spin_lock_irqsave/spin_unlock_irqrestore, 在I-pipe无效的情况下,会被替换成spin_lock/spin_unlock.
当spin_lock/spin_unlock被用于Linux代码段访问和中断服务例程共享的资源, 这就会发挥作用. 当运行I-pipe核时, 中断服务例程可能运行在实时Domain, 这时该代码段除了Xenomai Domain的中断外,不能受Linux中断影响, 所以spin_lock/spin_unlock需要改成spin_lock_irqsave_cond/spin_unlock_irqrestore_cond.
一个例子就是arch/arm/common/gic.c, "structirq_chip", "irq_hold", "irq_release" 函数会被实时上下文调用, 这里使用 "irq_controller_lock" spinlock, 所以对该spinlock的调用应该改成spin_lock_irqsave_cond/spin_unlock_irqrestore_cond.