優先度逆転を排除したセマフォ

取得しようとしたセマフォが、低優先度のタスクによって所有され高優先度のタスクが実行不能になったり、さらに中優先度のタスクが動作しているために、低優先度のタスクがセマフォ解放不能になったりする「優先度逆転」がしばしば問題になります。

チェーンブロッキングによる優先度逆転 ※画像クリックで拡大図を表示

一般的なRTOSでは、優先度継承プロトコルを使用して、この優先度逆転を回避していますが、優先度継承プロトコルの弱点は、高優先度タスクによる間接的なブロッキング(チェーンブロッキング)が避けられません。

例えば、低優先度のタスクが所有するセマフォを、中優先度のタスクが取得しようとする場合には、優先度継承プロトコルによって、低優先度のタスクの優先度は中優先度まで上昇します。

次に、高優先度のタスクが実行可能になり、中優先度のタスクが既に所有している他のセマフォを取得しようとしたとすると、今度は中優先度のタスクが高優先度にまで上昇しますが、低優先度のタスクは、依然、中優先度のままになっています。結果として、高優先度のタスクは、中優先度のタスクにブロックされることになります。

Highest Lockerセマフォでの優先度逆転排除 ※画像クリックで拡大図を表示

タスクが最高値固定セマフォを取得すると、そのセマフォの優先度ではなく、現在使われているすべての最高値固定セマフォの中での最高優先度までただちに上昇します。

前述の例では、中優先度のタスクが使用中の最高値固定セマフォを、高優先度のタスクが取得しようとすると、中優先度および低優先度の両方のタスクが、高優先度まで引き上げられ、セマフォが解放されると、タスクは元の優先度に戻りますので、チェーンブロッキングは発生しません。