- 追加された行はこの色です。
- 削除された行はこの色です。
*参照元 [#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.
*/
#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; \
} \
\
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; \
} \
\
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()]]
} \
\
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]