*参照元 [#qcc844e8] #backlinks *説明 [#j634fea7] -パス: [[linux-2.6.33/kernel/spinlock.c]] -下記、4種類のプリエンプション対応ロック関数を一度に定義するためのマクロ --__raw_xxxx_lock() --__raw_xxxx_lock_irq() --__raw_xxxx_lock_irqsave() --__raw_xxxx_lock_bh() **引数 [#oc33a864] -op --ロック関数の名前を指定する。 --例えば hogehoge を指定した場合、下記 4種類の関数が定義される。 ---__raw_hogehoge_lock() ---__raw_hogehoge_lock_irq() ---__raw_hogehoge_lock_irqsave() ---__raw_hogehoge_lock_bh() -locktype --ロック関数の引数型を指定する。 --例えば hogehoge を指定した場合、定義された関数は hogehoge_t * を引数に取る。 **返り値 [#za2dd540] -なし **参考 [#x4bd377f] -BUILD_LOCK_OPS() マクロで定義されている関数一覧。 --[[linux-2.6.33/__raw_spin_lock()]] --[[linux-2.6.33/__raw_spin_lock_irq()]] --[[linux-2.6.33/__raw_spin_lock_irqsave()]] --[[linux-2.6.33/__raw_spin_lock_bh()]] --[[linux-2.6.33/__raw_read_lock()]] --[[linux-2.6.33/__raw_read_lock_irq()]] --[[linux-2.6.33/__raw_read_lock_irqsave()]] --[[linux-2.6.33/__raw_read_lock_bh()]] --[[linux-2.6.33/__raw_write_lock()]] --[[linux-2.6.33/__raw_write_lock_irq()]] --[[linux-2.6.33/__raw_write_lock_irqsave()]] --[[linux-2.6.33/__raw_write_lock_bh()]] -spinlock.c における定義箇所 BUILD_LOCK_OPS(spin, raw_spinlock); BUILD_LOCK_OPS(read, rwlock); BUILD_LOCK_OPS(write, rwlock); *実装 [#p4c34b71] /* * We build the __lock_function inlines here. They are too large for * inlining all over the place, but here is only one user per function * which embedds them into the calling _lock_function below. * * This could be a long-held lock. We both prepare to spin for a long * time (making _this_ CPU preemptable if possible), and we also signal * towards that other CPU that it should break the lock ASAP. */ **__raw_xxxx_lock() の定義 [#edd2438f] #define BUILD_LOCK_OPS(op, locktype) \ void __lockfunc __raw_##op##_lock(locktype##_t *lock) \ { \ for (;;) { \ preempt_disable(); \ - --[[linux-2.6.33/preempt_disable()]] if (likely(do_raw_##op##_trylock(lock))) \ break; \ - --[[linux-2.6.33/do_raw_spin_trylock()]] --[[linux-2.6.33/do_raw_read_trylock()]] --[[linux-2.6.33/do_raw_write_trylock()]] preempt_enable(); \ \ - --[[linux-2.6.33/preempt_enable()]] if (!(lock)->break_lock) \ (lock)->break_lock = 1; \ while (!raw_##op##_can_lock(lock) && (lock)->break_lock)\ - --[[linux-2.6.33/raw_spin_can_lock()]] --[[linux-2.6.33/raw_read_can_lock()]] --[[linux-2.6.33/raw_write_can_lock()]] arch_##op##_relax(&lock->raw_lock); \ - --[[linux-2.6.33/arch_spin_relax()]] --[[linux-2.6.33/arch_read_relax()]] --[[linux-2.6.33/arch_write_relax()]] } \ (lock)->break_lock = 0; \ } \ \ **(続き)__raw_xxxx_lock_irqsave() の定義 [#n17ec608] **__raw_xxxx_lock_irqsave() の定義 [#n17ec608] unsigned long __lockfunc __raw_##op##_lock_irqsave(locktype##_t *lock) \ { \ unsigned long flags; \ \ for (;;) { \ preempt_disable(); \ - --[[linux-2.6.33/preempt_disable()]] local_irq_save(flags); \ - --[[linux-2.6.33/local_irq_save()]] if (likely(do_raw_##op##_trylock(lock))) \ break; \ - --[[linux-2.6.33/likely()]] --[[linux-2.6.33/do_raw_spin_trylock()]] --[[linux-2.6.33/do_raw_read_trylock()]] --[[linux-2.6.33/do_raw_write_trylock()]] local_irq_restore(flags); \ - --[[linux-2.6.33/local_irq_restore()]] preempt_enable(); \ \ - --[[linux-2.6.33/preempt_enable()]] if (!(lock)->break_lock) \ (lock)->break_lock = 1; \ while (!raw_##op##_can_lock(lock) && (lock)->break_lock)\ - --[[linux-2.6.33/raw_spin_can_lock()]] --[[linux-2.6.33/raw_read_can_lock()]] --[[linux-2.6.33/raw_write_can_lock()]] arch_##op##_relax(&lock->raw_lock); \ - --[[linux-2.6.33/arch_spin_relax()]] --[[linux-2.6.33/arch_read_relax()]] --[[linux-2.6.33/arch_write_relax()]] } \ (lock)->break_lock = 0; \ return flags; \ } \ \ **(続き)__raw_xxxx_lock_irq() の定義 [#bcf2b59f] **__raw_xxxx_lock_irq() の定義 [#bcf2b59f] void __lockfunc __raw_##op##_lock_irq(locktype##_t *lock) \ { \ _raw_##op##_lock_irqsave(lock); \ - --[[linux-2.6.33/_raw_spin_lock_irqsave()]] --[[linux-2.6.33/_raw_read_lock_irqsave()]] --[[linux-2.6.33/_raw_write_lock_irqsave()]] } \ \ **(続き)__raw_xxxx_lock_bh() の定義 [#m07fc514] **__raw_xxxx_lock_bh() の定義 [#m07fc514] void __lockfunc __raw_##op##_lock_bh(locktype##_t *lock) \ { \ unsigned long flags; \ \ /* */ \ /* Careful: we must exclude softirqs too, hence the */ \ /* irq-disabling. We use the generic preemption-aware */ \ /* function: */ \ /**/ \ flags = _raw_##op##_lock_irqsave(lock); \ - --[[linux-2.6.33/_raw_spin_lock_irqsave()]] --[[linux-2.6.33/_raw_read_lock_irqsave()]] --[[linux-2.6.33/_raw_write_lock_irqsave()]] local_bh_disable(); \ - --[[linux-2.6.33/local_bh_disable()]] local_irq_restore(flags); \ - --[[linux-2.6.33/local_irq_restore()]] } \ *コメント [#r6a9ae67]