*参照元 [#qcc844e8]
#backlinks

*説明 [#j634fea7]
-パス: [[linux-2.6.33/kernel/spinlock.c]]

-下記、4種類のプリエンプティプション対応ロック関数を定義するためのマクロ
--__xxxx_lock()
--__xxxx_lock_irq()
--__xxxx_lock_irqsave()
--__xxxx_lock_bh()


**引数 [#oc33a864]
-op
--ロック関数の名前を指定する。
--例えば hogehoge を指定した場合、下記 4種類の関数が定義される。
---__hogehoge_lock()
---__hogehoge_lock_irq()
---__hogehoge_lock_irqsave()
---__hogehoge_lock_bh()
-locktype
--ロック関数の引数型を指定する。
--例えば hogehoge を指定した場合、定義された関数は hogehoge_t * を引数に取る。


**返り値 [#za2dd540]
-なし


**参考 [#x4bd377f]
-BUILD_LOCK_OPS() マクロで定義されている関数一覧。
--


*実装 [#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();					\
 		if (likely(do_raw_##op##_trylock(lock)))		\
 			break;						\
 		preempt_enable();					\
 									\
 		if (!(lock)->break_lock)				\
 			(lock)->break_lock = 1;				\
 		while (!raw_##op##_can_lock(lock) && (lock)->break_lock)\
 			arch_##op##_relax(&lock->raw_lock);		\
 	}								\
 	(lock)->break_lock = 0;						\
 }									\
 									\
 unsigned long __lockfunc __raw_##op##_lock_irqsave(locktype##_t *lock)	\
 {									\
 	unsigned long flags;						\
 									\
 	for (;;) {							\
 		preempt_disable();					\
 		local_irq_save(flags);					\
 		if (likely(do_raw_##op##_trylock(lock)))		\
 			break;						\
 		local_irq_restore(flags);				\
 		preempt_enable();					\
 									\
 		if (!(lock)->break_lock)				\
 			(lock)->break_lock = 1;				\
 		while (!raw_##op##_can_lock(lock) && (lock)->break_lock)\
 			arch_##op##_relax(&lock->raw_lock);		\
 	}								\
 	(lock)->break_lock = 0;						\
 	return flags;							\
 }									\
 									\
 void __lockfunc __raw_##op##_lock_irq(locktype##_t *lock)		\
 {									\
 	_raw_##op##_lock_irqsave(lock);					\
 }									\
 									\
 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);				\
 	local_bh_disable();						\
 	local_irq_restore(flags);					\
 }									\


*コメント [#r6a9ae67]


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS