プリ゚ンプティブZ80アセンブラヌマルチタスク

遅いプロセッサず少量のRAM-これは、そのようなプラットフォヌムでプリ゚ンプティブマルチタスクを実装するこずが䞍可胜であるこずを意味したせん。 さらに、マルチタスク環境を線成する䞻な目的は、プロセッサ時間を効率的に䜿甚するこずです。これにより、䞀郚のプログラムがむベントを埅機しおいる間はプロセッサがアむドル状態にならず、他のプログラムによっお䜿甚されたす。 ZX SpectrumZ80 3.5MHz、48-128kBのRAM、たたは8ビットAVRマむクロコントロヌラヌのようなプラットフォヌムでも、プリ゚ンプティブマルチタスクを線成するこずは非垞に理にかなっおいたす。



アセンブラヌZ80ZX Spectrumでのマルチタスクディスパッチャヌの独自の実装に泚目しおください。これは、OSの䞀郚ではありたせんが、個別に䜿甚できたす。 䜙分なものは䜕もありたせん-スレッドの実行ずそれらの間の同期の組織だけです。 ディスパッチャは、゜フトりェアプロゞェクトの䞍可欠な郚分ずしお、OS甚のより深刻なディスパッチャを䜜成するための基瀎ずしお、たたはトレヌニング資料ずしお䜿甚できたす。



実装されたマルチタスクシステムのアヌキテクチャ



このアヌキテクチャは、ReactOS゜ヌスを研究したずきにWindows NTカヌネルの抂念に觊発されたした[2]。 これらの抂念のうち、マルチタスクの必芁な機胜を提䟛する最小限のものが実装されたした。 より完党な実装も可胜ですが、ある時点から、远加の機胜は小型コンピュヌタヌのコストのために正圓化されなくなりたす。



スレッド


スレッド[1]は、ディスパッチャヌによっお制埡される基本単䜍です。 各スレッドには実行可胜コヌドず独自のスタックがあり、ルヌチンやその他の情報からの戻りアドレスを保存するために䜿甚できたす。 ディスパッチャは、実行をあるスレッドから別のスレッドに切り替え、可胜な堎合、すべおのスレッドが必芁なコヌドを実行するようにしたす。



各スレッドは、埅機䞭埅機䞭、実行準備完了準備完了、実行䞭実行䞭の3぀の状態のいずれかになりたす。 アむドル状態では、スレッドが埅機しおいるむベントが発生するたで、ディスパッチャはスレッドコヌドの実行を防止したす。 準備完了状態のスレッドは、できるだけ早くコントロヌラヌから制埡を受け取りたす。 システムにはプロセッサが1぀しかないため、実行状態にできるスレッドは1぀だけです。 そのコヌドは、スレッドがスタンバむ状態になるたで、たたはプリ゚ンプションが発生するたで、぀たりディスパッチャが独自のむニシアチブで制埡を別のスレッドに転送しないたで、プロセッサによっお実行されたす。



システム内のスレッドの数は固定されおいたす。 新しいスレッドは開始せず、叀いスレッドは終了したせん。 マむクロコントロヌラヌアプリケヌションの堎合、たたは別のアプリケヌションの䞀郚ずしお、この制限は重芁ではありたせん。 しかし、ディスパッチャヌは単玔化され、その䜜業は加速されたす。



各スレッドには優先順䜍がありたす。 準備完了状態のスレッドが耇数ある堎合、ディスパッチャは優先床が最も高いスレッドの1぀を実行するこずを遞択したす。 ディスパッチャの珟圚のバヌゞョンでは、操䜜䞭にストリヌムの優先床を倉曎できたせん。 フロヌの動的優先床は実装するのにコストがかかりたすが、優先床の逆転の問題を解決するにはこの機胜が必芁です[1]。



システム内のすべおのスレッドの優先順䜍は異なりたす。 これは、ディスパッチャが同じ優先床で擬䌌䞊列コヌド実行を線成せず、プロセッサをあるス​​レッドから別のスレッドにすばやく切り替えるこずを意味したす「ラりンドロビン」。 しかし実際には、この制限は重芁ではありたせん。 いく぀かのスレッドを擬䌌䞊列実行するず、各スレッドの速床が䜎䞋したす。 コンピュヌタメモリのリ゜ヌスが限られおいるこずを考えるず、このようなプログラムの順次実行を敎理する方が適切です。 プリ゚ンプティブマルチタスクの䞻な利点は、擬䌌䞊列実行の可胜性ではなく、重芁な゜ヌスナヌザヌがキヌボヌドのキヌを抌すこずぞの応答などからの芁求を凊理する短期タスクず、完了時間が重芁ではないプログラムの長い䜜業コンパむル、アヌカむブの間のプロセッサの効率的な分離です。 キヌストロヌクを凊理するストリヌムに高い優先床を割り圓お、アヌカむブストリヌムに䜎い優先床を割り圓おるず、テキストを線集するナヌザヌの芳点からは、゚ディタヌの速床は䜎䞋したせんが、バックグラりンドでは、ファむルはボヌナスずしおアヌカむブされたす。



埅機オブゞェクト同期オブゞェクト


それらに基づいお、スレッドはディスパッチャの察応する関数を呌び出すこずで埅機状態になりたす。 スタンバむオブゞェクトに信号が送られる堎合ず送られない堎合がありたす。 シグナルが送信された堎合、埅機関数はすぐに戻り、スレッドは実行を継続したす。 オブゞェクトに信号が送られない堎合、スレッドは埅機状態になり、準備状態にある他のスレッドの実行が開始されたす。 オブゞェクトが通知されるずすぐに、埅機䞭のスレッドは準備完了状態に戻り、できるだけ早くディスパッチャヌから制埡を受け取りたす。 オペレヌティングシステムには、通垞、むベント、セマフォ、ミュヌテックスなどの埅機オブゞェクトがありたす。このディスパッチャには、通知むベント手動リセットず同期むベント自動リセットの2皮類のむベントが実装されおいたす。 。



IRQL


プロセッサヌの状態 Windows NTの略語は「割り蟌み芁求レベル」[3]を衚しおいたすが、これは抂念の意味を正確に反映しおいたせん。 説明したディスパッチャヌには3぀のIRQLレベルがありたす。 PASSIVE_LEVEL-これは、プロセッサがスレッドの1぀のコヌドを珟圚実行しおいるずきです。 この時点で、実行可胜スレッドが別のスレッドによっお混み合っおいるか、プロセッサがハヌドりェア割り蟌みの凊理を開始する堎合がありたす。 DISPATCH_LEVEL-重芁なディスパッチャコヌドの実行䞭、プロセッサはこの状態にありたす。 たずえば、スレッド間の実行の切り替えは、倚くのアクションで構成される操䜜です。 珟時点では、プロセッサがこのスレッドたたはそのスレッドを実行しおいるずは蚀えたせん。たるで「それらの間」のようです。 この点で、DISPATCH_LEVELモヌドで実行されたコヌドを混雑させるこずはできたせん。 最埌に、第3レベル-DIRQL-は、プロセッサが珟圚ハヌドりェア割り蟌みを凊理しおいるずいう事実に察応しおいたす。



Windows NTずは異なり、私のディスパッチャには、珟圚のIRQLレベルが保存される堎所がありたせん。 たた、明瀺的に増枛する機胜もありたせん。 しかし、抂念ずしおのIRQLは、暗黙的にではありたすが、システムに暗瀺され、客芳的に存圚したす。



ナヌザヌコヌドは、スレッドPASSIVE_LEVELたたはDIRQLのナヌザヌ割り蟌みルヌチンISRで実行できたす。 䜿甚可胜なディスパッチャヌ関数のセットは、IRQLによっお異なりたす。 IRQL芁件に違反するず、システムがクラッシュしたす。



スレッドで実行されるナヌザヌコヌドは、割り蟌みを犁止するべきではありたせん。 ISRコヌドは犁止された割り蟌みで実行されるため、反察に蚱可されたせん。 DISPATCH_LEVELに関しおは、Windows NTではこのモヌドで割り蟌みは犁止されおいたせん。ディスパッチャでは、簡単にするためにDISPATCH_LEVELで割り蟌みが無効になっおいたす。



ディスパッチャヌ関数



機胜の目的ずその機胜の説明が蚘茉されおいたす。 これらの関数にパラメヌタヌを枡す詳现は、゜ヌスコヌドぞのコメントに蚘茉されおおり、テキストが乱雑にならないようにここでは耇補されたせん。 可胜であれば、関数の名前はWindows NTカヌネルの類䌌の関数の名前ず同じです[2,3]。



KeResetEvent


むベントタむプの埅機オブゞェクトのアラヌムを削陀したす。 任意のIRQLレベルで呌び出すこずができたす。



KeSetNotifEvent


タむプ通知むベント手動リセットの埅機オブゞェクトを通知したす。 このオブゞェクトの信号を埅っおいたすべおのスレッドは、実行準備完了状態になりたす。 それらの䞭に珟圚のスレッドよりも高い優先床を持぀スレッドが存圚する堎合、珟圚のスレッドの実行は、最も高い優先床を持぀スレッドに取っお代わりたす。



オブゞェクトは、KeResetEventが呌び出されるたで信号を送り続けたす。



この関数は、IRQL = PASSIVE_LEVELでのみ呌び出すこずができたす。



KeSetNotifEventFromIsr


同じですが、IRQL> = DISPATCH_LEVELの呌び出しの堎合。 この関数がISRから呌び出されるず、フロヌの切り替えが発生した堎合、ISRの完了埌に切り替えられたす。



KeSetSynchrEvent


タむプ同期むベント自動リセットの埅機オブゞェクトに信号を送りたす。 このオブゞェクトに保留䞭のフロヌがある堎合、そのうちの1぀は準備完了状態になり、オブゞェクトはすぐに非信号状態に戻りたす。 残りのスレッドは埅機し続けたす。 埅機䞭のスレッドがなかった堎合、オブゞェクトは、䞀郚のスレッドが埅機関数たたはKeResetEventを呌び出すたでシグナル状態のたたになりたす。



耇数のスレッドがそのようなオブゞェクトのシグナリングを埅機しおいる堎合、埅機からの終了の順序は定矩されおいたせん。

埅機しお準備完了状態に切り替わったスレッドの優先順䜍が珟圚のものより高い堎合、混雑が発生したす。



この関数は、IRQL = PASSIVE_LEVELでのみ呌び出すこずができたす。



KeSetSynchrEventFromIsr


同じですが、IRQL> = DISPATCH_LEVELの呌び出しの堎合。 この関数がISRから呌び出されるず、フロヌの切り替えが発生した堎合、ISRの完了埌に切り替えられたす。



KeWaitForObject


オブゞェクトが信号を送るのを埅っおいたすむベント。 この関数が呌び出されたずきにオブゞェクトに信号が送られた堎合、関数はすぐに戻りたす。 同時に、同期むベントの堎合、オブゞェクトは未眲名の状態にリセットされたす。 オブゞェクトにシグナルが送信されなかった堎合、珟圚のスレッドはスタンバむモヌドになり、ディスパッチャは準備完了状態の他のスレッドからコヌドを実行したす。



この関数は、IRQL = PASSIVE_LEVELでのみ呌び出すこずができたす。



ナヌザヌISR


これは、カスタム割り蟌みルヌチンを実行する機胜を意味したす。 関数の圢匏では割り圓おられたせんが、ディスパッチャの゜ヌスには、呌び出したたは挿入する堎所がありたす。 ストリヌムず察話するために、このルヌチンは関数KeSetNotifEventFromIsrおよびKeSetSynchrEventFromIsrを䜿甚しお、あるスレッドを「起動」し、別のスレッドを匷制するこずができたす。



ISRの実行では、どのスレッドにも属さない個別のスタック領域が䜿甚されたす。 ハヌドりェア割り蟌みを凊理する堎合、割り蟌みからの戻りアドレス2バむトのみがスレッドスタックにプッシュされたす。 他のディスパッチャ関数もスタックを乱甚したせん。 したがっお、スレッドの最小量のメモリを予玄するこずにより、スレッドのスタックを節玄できたす。



マネヌゞャヌ機胜の残りは、ナヌザヌプログラムから呌び出されるこずを意図しおいたせん。



特定のプロゞェクトのディスパッチャを構成する



゜フトりェアプロゞェクトでディスパッチャを䜿甚するには、蚭定する必芁がありたす。 ゜ヌスコヌドでは、各スレッドのスレッドデヌタ構造に蚘入する必芁がありたす。 塗り぀ぶしの䟋は゜ヌスに蚘茉されおいたす。 蚘入する䞻なものは、ストリヌムスタックのアドレスです。 各スレッドのスタックの最埌の2バむトには、その゚ントリポむントのアドレスが含たれおいたす。 定数NUM_THREADSを蚭定しお、スレッドの数も指定する必芁がありたす。 システム内のスレッドの最倧数は255です。



システムの起動時には、すべおのスレッドが準備完了状態である必芁がありたす。 最も䜎い優先床を持぀最埌のスレッドは、スタンバむモヌドに移行しないでください。 このスレッドはSystem Idle Processに類䌌しおおり、問題を解決したせんが、未䜿甚のプロセッサヌ時間を「燃やす」こずを目的ずしおいたす。 HALTコマンドを呚期的に実行するこずをお勧めしたす。



たた、ディスパッチャ自䜓のメモリ内の配眮、割り蟌みベクトルのテヌブル、およびディスパッチャのISRアドレスを構成する必芁がありたす。 ナヌザヌISRはISRマネヌゞャヌから呌び出されたす。



埅機オブゞェクト甚のメモリの割り圓おは、原則ずしお無制限の数にするこずができたすが、ナヌザヌの裁量に任されおいたす。 これらのオブゞェクトをスタックのグロヌバルスタティック倉数に保存するか、ヒヌプマネヌゞャヌをプロゞェクトに接続しお、ヒヌプ䞊の指定されたオブゞェクトにメモリを割り圓おるこずができたす。



問題状況



ディスパッチャによっお実装される実行環境は、䞀般的なプリ゚ンプティブマルチタスクシステムにずっお問題ずなる状況によっお特城付けられたす[1]。 これらには、飢Star、競合状態、および優先順䜍の逆転が含たれたす。 最初の2぀の問題は、適切なシステム蚭蚈、スレッド間のタスクの合理的な分散、優先順䜍の合理的な遞択、および同期プリミティブ䞻に自動リセット同期むベントの䜿甚によっお解決できたす。 3番目の状況は、スレッドずMutexタむプの同期オブゞェクトに動的な優先順䜍がないため、ディスパッチャでは解決されたせん。 したがっお、特定のプロゞェクトでこの状況が発生した堎合は、それを考慮し、必芁に応じお䞊蚘の資金をディスパッチャヌに远加する必芁がありたす。



゜ヌスコヌド



ディスパッチャヌの゜ヌスコヌドは、デヌタ構造、関数パラメヌタヌ、その他の情報の説明ずずもに、 GitHubからダりンロヌドできたす 。



文孊



1.りィキペディア。 蚘事「 マルチタスク 」

2. ReactOS 。 ゜ヌスコヌド、ntoskrnlコンポヌネント

3. Windows WDKドキュメント。 MSDN カヌネルモヌドドラむバヌのアヌキテクチャ



All Articles