RCUの単純な実装
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2019/01/13 15:24 UTC 版)
「リード・コピー・アップデート」の記事における「RCUの単純な実装」の解説
RCUのおもちゃ的な実装を考えるとRCUを理解しやすいだろう。ここではそのような簡単な実装を説明する。この実装はプリエンプション不可な環境でのみ動作することに注意。 void rcu_read_lock(void) { }void rcu_read_unlock(void) { }void call_rcu(void (*callback) (void *), void *arg){// add callback/arg pair to a list}void synchronize_rcu(void){int cpu, ncpus = 0;for_each_cpu(cpu) schedule_current_task_to(cpu); for each entry in the call_rcu list entry->callback (entry->arg);} rcu_assign_pointer と rcu_dereference_pointer を無視しても大勢に影響はないが、いずれにしろ、以下のようになる。 #define rcu_assign_pointer(p, v)({ \smp_wmb(); \(p) = (v); \})#define rcu_dereference_pointer(p) ({ \ typeof(p) _value = (p); \ smp_rmb(); /* not needed on all architectures */ \ (_value); \ }) rcu_read_lock と rcu_read_unlock は全く何もしない。プリエンプション不可な古いカーネルでは、このように参照側のオーバヘッドは全く無い(メモリバリアが必要となるのは DEC Alpha だけである)。したがって rcu_read_lock がデッドロック状態になることもなく、リアルタイムプロセスがスケジューリングのデッドラインに陥ることもなく、優先順位の逆転が発生することもなく、ロックの衝突が激しく発生することもない。 synchronize_rcu の実装は、synchronize_cpu を呼び出した者を各CPUに移動させ、全CPUでコンテキストスイッチ可能となるまでブロックさせる。プリエンプション不可なのでRCU参照側クリティカルセクション内でプリエンプションは発生せず、あるCPUで(他のプロセスをスケジュールする)コンテキストスイッチが起きたときにはそれ以前のRCU参照側クリティカルセクションは完了しているはずである。全CPUでコンテキストスイッチが起きたら、既存のRCU参照側クリティカルセクションが全て完了していることを保証できる。
※この「RCUの単純な実装」の解説は、「リード・コピー・アップデート」の解説の一部です。
「RCUの単純な実装」を含む「リード・コピー・アップデート」の記事については、「リード・コピー・アップデート」の概要を参照ください。
- RCUの単純な実装のページへのリンク