優先度逆転とは、優先度の高いタスクに必要なリソースを優先度の低いタスクが保持しているために、優先度の高いトランザクションが遅延する状況を指します。 優先度逆転を軽減するため、Android では、トランザクション優先度継承、ノード優先度継承、リアルタイム優先度継承という 3 種類の優先度継承を使用して、さまざまな優先度でスレッドを実行できます。
このページでは、これらのさまざまな形式の優先度継承について説明します。
トランザクション優先度継承
同期バインダ呼び出しを行う場合、優先度の高いスレッドは、優先度の低いスレッドが応答を送信するまで、優先度の低いスレッドによってブロックされる可能性があります。たとえば、nice 値が -19 のスレッドは、デフォルトの nice 値が 0 のスレッドによってブロックされる可能性があります。
トランザクション優先度継承は、トランザクションを処理するバインダ スレッドの優先度を呼び出し元の優先度に合わせて一時的に変更することで、この問題を解決します。 トランザクションが完了すると、バインダ ドライバはバインダ スレッドの優先度を元の値に戻します。
ノード優先度継承
レイテンシが短いことが求められる状況などでは、非同期トランザクションの優先度が重要になります。
ノード優先度継承を使用すると、ノード上のすべてのトランザクションが実行される最小優先度を構成できます。 ノード優先度継承が構成されると、ノード上のすべてのトランザクションはこの最小優先度で実行されます。
ノード優先度継承のルールは次のとおりです。
トランザクションが同期している場合、優先度は
max(min_node_priority, caller_priority);になります。トランザクションが非同期の場合、優先度は
max(default_priority (nice 0), min_node_priority);になります。
ノード優先度継承を構成する
ノード優先度継承を構成するには、BBinder::setMinSchedulerPolicy を使用します。
リアルタイム優先度継承
Android では、SCHED_FIFO などのリアルタイム スケジューリング ポリシーを使用して、レイテンシが重要なスレッドが時間内に処理を完了するようにします。また、Android のレイテンシが重要な処理の一部は、複数のプロセスに分割されます。
リアルタイム優先度継承は、次の点を除いて nice 値と同じように機能します。
- リアルタイム優先度継承はデフォルトで無効になっています。
- リアルタイム優先度の値が大きいほど、優先度が高くなります。
リアルタイム優先度継承を有効にする
リアルタイム優先度継承は、BBinder::setInheritRt(true) 呼び出しを使用して、個々のノードに対して有効にする必要があります。