(19)【発行国】日本国特許庁(JP)
(12)【公報種別】特許公報(B2)
(11)【特許番号】
(24)【登録日】2022-12-20
(45)【発行日】2022-12-28
(54)【発明の名称】情報処理装置および実行制御プログラム
(51)【国際特許分類】
G06F 9/48 20060101AFI20221221BHJP
【FI】
G06F9/48 300C
(21)【出願番号】P 2019062116
(22)【出願日】2019-03-28
【審査請求日】2021-12-08
(73)【特許権者】
【識別番号】000005223
【氏名又は名称】富士通株式会社
(74)【代理人】
【識別番号】110002918
【氏名又は名称】弁理士法人扶桑国際特許事務所
(72)【発明者】
【氏名】前田 宗則
【審査官】坂東 博司
(56)【参考文献】
【文献】特開2000-293385(JP,A)
【文献】特開2015-143998(JP,A)
【文献】特開2015-056109(JP,A)
【文献】特開2011-118679(JP,A)
【文献】特開2013-140593(JP,A)
【文献】米国特許出願公開第2013/0179891(US,A1)
(58)【調査した分野】(Int.Cl.,DB名)
G06F 9/48
(57)【特許請求の範囲】
【請求項1】
新たに発生したタスクが登録される第1のキューと、タスクに割り当てられているスレッドのうち、実行可能状態のスレッドが登録される第2のキューとを記憶する記憶部と、
第1のスレッドによる第1のタスクの実行が終了したとき、前記第1のキューの先頭に登録された第2のタスクと、前記第2のキューの先頭に登録された第2のスレッドとの間の実行優先度を判定し、
前記第2のスレッドを先に実行すべきと判定された場合、前記第2のスレッドを前記第2のキューから取り出し、前記第2のスレッドによって前記第2のスレッドが割り当てられたタスクを実行し、
前記第2のタスクを先に実行すべきと判定された場合、前記第2のタスクを前記第1のキューから取り出し、前記第1のスレッドによって前記第2のタスクを実行する、処理部と、
を有する情報処理装置。
【請求項2】
前記処理部は、さらに、
新規タスクが発生すると、前記新規タスクを前記第1のキューの末尾に登録するとともに、カウント値を取得するたびにカウント値が更新されるカウンタから、カウント値を取得して前記新規タスクに付加し、
前記実行可能状態のスレッドを前記第2のキューの末尾に登録する際に、前記カウンタからカウント値を取得して前記実行可能状態のスレッドに付加し、
前記実行優先度の判定では、前記第2のタスクに付加されたカウント値と前記第2のスレッドに付加されたカウント値との比較結果に基づいて前記実行優先度を判定する、
請求項1記載の情報処理装置。
【請求項3】
前記処理部は、イールドによって前記第1のスレッドによる前記第1のタスクの実行が途中で休止したとき、前記第1のスレッドを前記第2のキューの末尾に登録するとともに、前記カウンタからカウント値を取得して前記第1のスレッドに付加する、
請求項2記載の情報処理装置。
【請求項4】
前記処理部は、
待ち合わせの発生によって前記第1のスレッドによる前記第1のタスクの実行が途中で休止したとき、前記第1のスレッドをサスペンドさせて待ち合わせ状態に遷移させ、
前記第1のスレッドが待ち合わせ状態から復帰したとき、前記第1のスレッドを前記第2のキューの末尾に登録するとともに、前記カウンタからカウント値を取得して前記第1のスレッドに付加する、
請求項2記載の情報処理装置。
【請求項5】
前記処理部は、
前記第1のスレッドによる前記第1のタスクの実行が途中で休止したとき、前記実行優先度を判定し、
前記第2のスレッドを先に実行すべきと判定された場合、前記第2のスレッドを前記第2のキューから取り出し、前記第2のスレッドによって前記第2のスレッドが割り当てられたタスクを実行し、
前記第2のタスクを先に実行すべきと判定された場合、タスクに割り当てられていない第3のスレッドを前記第2のタスクに割り当て、前記第3のスレッドによって前記第2のタスクを実行する、
請求項1乃至4のいずれか1項に記載の情報処理装置。
【請求項6】
前記記憶部は、タスクに割り当てられていない未割り当てスレッドが登録される第3のキューをさらに記憶し、
前記処理部は、前記実行優先度の判定によって前記第2のスレッドを先に実行すべきと判定された場合、前記第1のスレッドを前記未割り当てスレッドとして前記第3のキューに登録する、
請求項1乃至4のいずれか1項に記載の情報処理装置。
【請求項7】
コンピュータに、
第1のスレッドによる第1のタスクの実行が終了したとき、新たに発生したタスクが登録される第1のキューの先頭に登録された第2のタスクと、タスクに割り当てられているスレッドのうち実行可能状態のスレッドが登録される第2のキューの先頭に登録された第2のスレッドとの間の実行優先度を判定し、
前記第2のスレッドを先に実行すべきと判定された場合、前記第2のスレッドを前記第2のキューから取り出し、前記第2のスレッドによって前記第2のスレッドが割り当てられたタスクを実行し、
前記第2のタスクを先に実行すべきと判定された場合、前記第2のタスクを前記第1のキューから取り出し、前記第1のスレッドによって前記第2のタスクを実行する、
処理を実行させる実行制御プログラム。
【発明の詳細な説明】
【技術分野】
【0001】
本発明は、情報処理装置および実行制御プログラムに関する。
【背景技術】
【0002】
コンピュータにおいて並列処理を実現するための仕組みとして、マルチスレッド方式がある。マルチスレッド方式では、複数のスレッドを用いて複数のタスクが実行される。スレッドは、プロセッサの使用単位であり、通常はスレッドごとにメモリ領域などのハードウェアリソースが割り当てられる。タスクは、処理の単位であり、タスクにスレッドが割り当てられることにより、スレッドによってタスクが実行される。
【0003】
スレッドやタスクの実行制御に関しては、次のような提案がある。例えば、1つのスレッドによって複数のタスクを実行するようにしたデータベース管理システムが提案されている。このシステムでは、あるスレッドがタスクを実行し、その結果として、スレッド間非共有の新たなコンテキストを作成し、そのスレッドが新たなタスクを作成し、生成したコンテキストを用いて新たなタスクを生成する。
【0004】
また、次のような情報処理装置も提案されている。この情報処理装置は、タスクを分割して得られたサブタスクを、それらの優先度に応じて複数のサブタスクキューに登録する。そして、情報処理装置は、同時実行されるサブタスク数が所定の閾値を超える場合は、優先度の高いサブタスクキューからサブタスクを取得してスレッドを作成し、サブタスクを実行させる。
【先行技術文献】
【特許文献】
【0005】
【文献】特開2016-48577号公報
【文献】特開2017-90961号公報
【発明の概要】
【発明が解決しようとする課題】
【0006】
ところで、マルチスレッド方式では、適正な順序でタスクが実行されることが望まれる。そのための方法として、例えば、タスクキューや、スレッド実行のための実行キューが用いられる。一例として、新規のタスクが発生すると、そのタスクがタスクキューの末尾に追加される。また、タスクキューの先頭タスクが取り出され、そのタスクに対してスレッドが割り当てられ、そのスレッドが実行キューの末尾に追加される。そして、実行キューの先頭スレッドが取り出され、そのスレッドによって対応するタスクが実行される。
【0007】
単純な方法として、1つのタスクに1つのスレッドを割り当てる方法が考えられる。しかし、この方法では、1つのタスクの実行が終了するたびにスレッドの切り替えが発生するので、スレッドの切り替え回数が多くなるという問題がある。スレッドの切り替えの際にはコンテキストスイッチの発生によって大きなオーバヘッドが発生するので、切り替え回数が多くなるとタスクの処理性能が低下してしまう。
【0008】
1つの側面では、スレッドの切り替え回数を抑制可能な情報処理装置および実行制御プログラムを提供することを目的とする。
【課題を解決するための手段】
【0009】
1つの案では、記憶部と処理部とを有する情報処理装置が提供される。この情報処理装置において、記憶部は、新たに発生したタスクが登録される第1のキューと、タスクに割り当てられているスレッドのうち、実行可能状態のスレッドが登録される第2のキューとを記憶する。処理部は、第1のスレッドによる第1のタスクの実行が終了したとき、第1のキューの先頭に登録された第2のタスクと、第2のキューの先頭に登録された第2のスレッドとの間の実行優先度を判定し、第2のスレッドを先に実行すべきと判定された場合、第2のスレッドを第2のキューから取り出し、第2のスレッドによって第2のスレッドが割り当てられたタスクを実行し、第2のタスクを先に実行すべきと判定された場合、第2のタスクを第1のキューから取り出し、第1のスレッドによって第2のタスクを実行する。
【0010】
また、1つの案では、上記の情報処理装置と同様の処理をコンピュータに実行させる実行制御プログラムが提供される。
【発明の効果】
【0011】
1つの側面では、スレッドの切り替え回数を抑制できる。
【図面の簡単な説明】
【0012】
【
図1】第1の実施の形態に係る情報処理装置の構成例および処理例を示す図である。
【
図2】第2の実施の形態に係るストレージシステムの構成例を示す図である。
【
図3】ストレージ制御装置のハードウェア構成例を示す図である。
【
図4】ストレージ制御装置が備える処理機能の構成例を示すブロック図である。
【
図5】タスクおよびスレッドの管理について説明するための図である。
【
図6】タスク実行制御の比較例を説明するための図である。
【
図7】チケット番号の付加について説明するための図である。
【
図10】スレッドの実行制御を示す第3の図である。
【
図12】比較例によるタスクの実行制御例を示す図である。
【
図13】第2の実施の形態によるタスクの実行制御例を示す図(その1)である。
【
図14】第2の実施の形態によるタスクの実行制御例を示す図(その2)である。
【
図15】タスク投入処理の手順を示すフローチャートの例である。
【
図16】スレッドのスケジューリング処理の手順を示すフローチャートの例(その1)である。
【
図17】スレッドのスケジューリング処理の手順を示すフローチャートの例(その2)である。
【
図18】スレッドのスケジューリング処理の手順を示すフローチャートの例(その3)である。
【
図19】スレッドによるタスク実行処理の手順を示すフローチャートの例である。
【
図20】関数実行処理の手順を示すフローチャートの例である。
【
図21】スレッドスケジューラによるスレッドの復帰判定処理の手順を示すフローチャートの例である。
【発明を実施するための形態】
【0013】
以下、本発明の実施の形態について図面を参照して説明する。
〔第1の実施の形態〕
図1は、第1の実施の形態に係る情報処理装置の構成例および処理例を示す図である。
図1に示す情報処理装置10は、記憶部11と処理部12を有する。記憶部11は、例えば、RAM(Random Access Memory)などの記憶装置によって実現される。処理部12は、例えばプロセッサであり、その場合、処理部12の処理は、プロセッサがプログラムを実行することで実現される。
【0014】
記憶部11は、第1のキュー21と第2のキュー22を記憶する。第1のキュー21には、新たに発生したタスクが登録される。
図1の例では、第1のキュー21にはタスクA11,A12が登録されている。第2のキュー22には、タスクに割り当てられているスレッドのうち、実行可能状態のスレッドが登録される。例えば、待ち合わせ状態から復帰したスレッドや、イールド(yield)によって実行が中断されて後回しになったスレッドが、第2のキュー22に登録される。
図1の例では、第2のキュー22には、タスクA2に割り当てられているスレッドB2と、タスクA3に割り当てられているスレッドB3が登録されている。
【0015】
処理部12は、スレッドによるタスクの実行を制御する。例えば、
図1に示すように、タスクA1にスレッドB1が割り当てられ、スレッドB1によってタスクA1が実行されているとする。この状態から、スレッドB1によるタスクA1の実行が終了すると(ステップS1)、処理部12は次のような手順で、次に実行するスレッドやタスクを決定する。
【0016】
処理部12は、第1のキュー21の先頭に登録されたタスクA11と、第2のキュー22の先頭に登録されたスレッドB2との間の実行優先度を判定する(ステップS2)。例えば、第1のキュー21内の各タスク、および第2のキュー22内の各スレッドに、実行順を示す実行順情報が付加される。この場合、処理部12は、タスクA11に付加された実行順情報とスレッドB2に付加された実行順情報とを比較することで、実行優先度を判定できる。
【0017】
処理部12は、実行優先度の判定により、スレッドB2を先に実行すべきと判定した場合、スレッドB2を第2のキュー22から取り出し、スレッドB2によって、スレッドB2が割り当てられたタスクA2を実行する(ステップS3a)。この場合、実行するスレッドがスレッドB1からスレッドB2に切り替えられるので、コンテキストスイッチが発生する。なお、切り替え前のスレッドB1は、例えば、タスクに割り当てられていない未割り当てスレッドに遷移させて、再利用可能にしておくことができる。
【0018】
一方、処理部12は、実行優先度の判定により、タスクA11を先に実行すべきと判定した場合、タスクA11を第1のキュー21から取り出し、タスクA1の実行を終了したスレッドB1によって、タスクA11を実行する(ステップS3b)。この場合、同じスレッドB1によってタスクA1,A11が連続的に実行されるので、実行するスレッドは切り替えられず、コンテキストスイッチも発生しない。
【0019】
以上説明した情報処理装置10によれば、ステップS3bのように1つのスレッドによって複数のタスクを連続的に実行できるようになる。これにより、スレッドの切り替え回数を抑制できる。
【0020】
例えば、情報処理装置10は、新たに発生して第1のキュー21に登録されるタスクについては、その実行段階でスレッドを割り当てる。これにより、実行待ち状態のスレッドの発生数を抑制でき、その結果として、実行するスレッドの切り替えが発生する確率を低減できる。ただし、情報処理装置10は、待ち合わせ状態からの復帰やイールドなどにより、スレッドが割り当て済みのタスク(すなわち、第2のキュー22に登録されるスレッドに割り当てられたタスク)を再実行しなければならない場合がある。このため、1つのスレッドですべてのタスクを実行することはできない。すなわち、実行するスレッドの切り替えを完全に発生させないようにすることはできない。
【0021】
そこで、情報処理装置10は、実行優先度を判定基準として用いて、スレッドが未割り当てのタスクを既存のスレッドで実行するか、または、スレッドを切り替えてスレッドが割り当て済みのタスクを実行するかを判定する。これにより、タスクの実行順を適正化するというポリシーの下で、実行するスレッドの切り替え回数を抑制できるようになる。
【0022】
スレッドの切り替え回数が抑制されることで、その切り替えに伴うコンテキストスイッチの発生回数も抑制され、コンテキストスイッチの発生によるオーバヘッドが小さくなる。その結果、タスクの処理性能を向上させることができる。
【0023】
〔第2の実施の形態〕
次に、
図1に示した情報処理装置10の例としてストレージ制御装置が適用されたストレージシステムについて説明する。
【0024】
図2は、第2の実施の形態に係るストレージシステムの構成例を示す図である。
図2に示すように、第2の実施の形態に係るストレージシステムは、ホストサーバ50と、ストレージ制御装置100,200と、ストレージ300とを有する。なお、ストレージ制御装置100,200は、
図1に示した情報処理装置10の一例である。
【0025】
ホストサーバ50は、例えば、業務処理などの各種の処理を実行するサーバコンピュータである。
ストレージ制御装置100,200は、ホストサーバ50から受け付けたI/O(Input/Output)要求を処理する。例えば、ホストサーバ50からのアクセス対象となる1以上の論理ボリュームが、ストレージ300の記憶領域を用いて作成される。ストレージ制御装置100,200は、ホストサーバ50から論理ボリュームに対するI/O要求を受け付け、論理ボリュームに対するI/O処理を制御する。このようなストレージ制御装置100,200は、例えば、汎用のサーバコンピュータとして実現される。この場合、ストレージ制御装置100,200は、ストレージ制御用のアプリケーションプログラムを実行することで、ストレージ制御を実行する。
【0026】
ストレージ300には、1台以上の不揮発性記憶装置が搭載されている。例えば、ストレージ300には、不揮発性記憶装置としてSSD(Solid State Drive)が搭載されている。
【0027】
なお、ホストサーバ50とストレージ制御装置100,200とは、例えば、FC(Fibre Channel)やiSCSI(Internet Small Computer System Interface)などを利用して接続される。ストレージ制御装置100,200は、例えば、FC、iSCSI、LAN(Local Area Network)などを利用して接続される。ストレージ制御装置100,200が互いに接続されていることで、例えば、データの分散配置や、データの二重化(一方から他方へのデータコピー)などが実現可能になる。ストレージ制御装置100,200とストレージ300とは、例えば、FC、iSCSI、SATA(Serial Advanced Technology Attachment)などを利用してそれぞれ接続される。
【0028】
図3は、ストレージ制御装置のハードウェア構成例を示す図である。なお、
図3ではストレージ制御装置100のハードウェア構成について例示するが、ストレージ制御装置200についてもストレージ制御装置100と同様のハードウェア構成によって実現される。
【0029】
ストレージ制御装置100は、CPU(Central Processing Unit)101、RAM102、SSD103、読み取り装置104、ホストインタフェース(I/F)105、ドライブインタフェース(I/F)106および通信インタフェース(I/F)107を備える。
【0030】
CPU101は、RAM102からプログラムを読み出して処理する処理装置である。CPU101は、複数のコア(プロセッサコア)を備えるマルチコアCPUである。
RAM102は、ストレージ制御装置100の主記憶装置として使用される。RAM102には、CPU101に実行させるOS(Operating System)プログラムやアプリケーションプログラムの少なくとも一部が一時的に格納される。また、RAM102には、CPU101による処理に必要な各種データが格納される。
【0031】
SSD103は、ストレージ制御装置100の補助記憶装置として使用される。SSD103には、OSプログラム、アプリケーションプログラムおよび各種データが格納される。なお、補助記憶装置としては、HDD(Hard Disk Drive)などの他の種類の不揮発性記憶装置を使用することもできる。
【0032】
読み取り装置104には、可搬型記録媒体104aが脱着される。読み取り装置104は、可搬型記録媒体104aに記録されたデータを読み取ってCPU101に送信する。可搬型記録媒体104aとしては、光ディスク、光磁気ディスク、半導体メモリなどがある。
【0033】
ホストインタフェース105は、ホストサーバ50と通信するためのインタフェース装置である。ドライブインタフェース106は、ストレージ300に含まれる不揮発性記憶装置と通信するためのインタフェース装置である。通信インタフェース107は、他方のストレージ制御装置200と通信するためのインタフェース装置である。
【0034】
図4は、ストレージ制御装置が備える処理機能の構成例を示すブロック図である。なお、
図4ではストレージ制御装置100の構成について例示するが、ストレージ制御装置200もストレージ制御装置100と同様の処理機能を備えている。
【0035】
ストレージ制御装置100は、I/O制御部110、スレッドプール121、スレッドスケジューラ122、チケットカウンタ123および記憶部130を備える。記憶部130には、タスクキュー131、アイドルスレッドキュー132、カレントスレッドポインタ133、実行キュー(Run Queue)134および待ち合わせ管理データ135が記憶される。
【0036】
なお、I/O制御部110、スレッドプール121、スレッドスケジューラ122、チケットカウンタ123の処理は、例えば、CPU101が所定のプログラムを実行することで実現される。記憶部130は、例えば、RAM102の記憶領域によって実現される。
【0037】
I/O制御部110は、ホストサーバ50からのI/O要求に応じた論理ボリュームに対するI/O処理を制御する。I/O制御部110は、例えば、上位接続部111、キャッシュ管理部112、重複排除部113およびI/O処理部114を備える。
【0038】
上位接続部111は、ホストサーバ50からI/O要求(書き込み要求または読み出し要求)を受け付ける。キャッシュ管理部112は、上位接続部111が受け付けたI/O要求に応じたI/O処理を、RAM102に確保されたキャッシュ領域を用いて制御する。重複排除部113は、I/O要求に応じてストレージ300に格納されるデータの重複を排除するための制御を行う。I/O処理部114は、重複が排除されたデータをストレージ300に書き込む。このとき、例えば、RAID(Redundant Arrays of Inexpensive Disks)によって書き込みが制御される。また、I/O処理部114は、ストレージ300からデータを読み出す。
【0039】
スレッドプール121、スレッドスケジューラ122およびチケットカウンタ123は、スレッドを用いたタスクの実行を制御するための機能である。スレッドは、マルチタスクを実現するためのCPU101の使用単位である。各スレッドには、RAM102上のメモリ領域などの個別のリソースが割り当てられる。タスクは、処理の単位であり、例えば関数や引数によって定義される。本実施の形態において、タスクは主として、I/O制御部110の各部で発生する単位処理である。タスクにスレッドが割り当てられることで、タスクの処理内容が実行される。スレッドは、タスクを実行する論理的な処理主体(論理プロセッサ)ということもできる。
【0040】
スレッドプール121は、スレッドのリソースを管理する。スレッドプール121は少なくとも、アイドルスレッドキュー132を用いて、タスクに割り当てられていない未使用のスレッドを管理する。また、スレッドプール121は、タスクキュー131を用いて、発生したタスクを管理する。スレッドによるタスクの実行により新たなタスクが発生すると、そのタスクがスレッドプール121に投入される。スレッドプール121は、投入されたタスクをタスクキュー131の末尾に追加する。
【0041】
スレッドスケジューラ122は、スレッドの実行を制御する。スレッドスケジューラ122は、実行キュー134を用いて、タスクに割り当て済みのスレッドの実行順を制御する。実行キュー134には、タスクに割り当て済みのスレッドのうち、実行可能な(実行準備ができた)スレッドが登録される。また、スレッドスケジューラ122は、実行キュー134に登録されたスレッドに対応するタスクより先に実行すべきタスクがタスクキュー131に登録されている場合、このタスクを先に実行するように制御する。
【0042】
なお、スレッドスケジューラ122は、カレントスレッドポインタ133を用いて、現在実行中のスレッドを管理する。また、スレッドスケジューラ122は、待ち合わせ管理データ135を用いて、待ち合わせ状態のスレッドを管理する。
【0043】
チケットカウンタ123は、チケット番号をカウントして、スレッドプール121およびスレッドスケジューラ122に発行する。チケット番号としては、順序を示すようにユニークな値が発行される。本実施の形態ではチケット番号として、カウントアップ動作により昇順の値が発行される。チケット番号は、タスクが適正な順で実行されるように、タスクキュー131に追加されるタスクと、実行キュー134に追加されるスレッドとに付加される。
【0044】
なお、CPU101がマルチプロセッサである場合、スレッドプール121、スレッドスケジューラ122およびチケットカウンタ123はプロセッサごとに個別に存在する。また、CPU101がマルチコアCPUである場合、スレッドプール121、スレッドスケジューラ122およびチケットカウンタ123はプロセッサコアごとに個別に存在する。
【0045】
図5は、タスクおよびスレッドの管理について説明するための図である。
まず、タスクキュー131は、スレッドプール121に投入されたタスクを、その投入順に管理するためのキューである。
図5の例では、タスクキュー131には先頭から順に、タスクTSK1,TSK2,TSK3が登録されている。これは、スレッドプール121に対してタスクTSK1,TSK2,TSK3が順番に投入されたことを示す。
【0046】
一方、スレッドは、アイドルスレッドキュー132、カレントスレッドポインタ133および実行キュー134によって管理される。また、スレッドは、アイドルスレッドとワーカスレッドの2種類に大別される。アイドルスレッドは、タスクに割り当てられていない未使用のスレッドである。ワーカスレッドは、タスクに割り当てられている使用中のスレッドである。これらのうちアイドルスレッドは、アイドルスレッドキュー132を用いて管理される。
【0047】
前述のように、各スレッドには個別のリソースが割り当てられる。スレッドは、メモリ領域などのリソースの獲得や初期化といった生成のためのコストが大きい。このため、スレッドプール121によってあらかじめ有限個のスレッドが生成されて、それらの各スレッドに対応するリソースが確保される。
【0048】
アイドルスレッドキュー132は、アイドルキューを管理するためのキューである。タスクが投入される前の初期状態では、上記のように生成されたすべてのスレッドはアイドルスレッドであり、それらのアイドルスレッドがアイドルスレッドキュー132に登録される。そして、タスクへの割り当てが要求されると、スレッドプール121は、アイドルスレッドキュー132の先頭からアイドルスレッドを取り出し、このアイドルスレッドをタスクに割り当てる。これにより、アイドルスレッドはワーカスレッドに遷移する。また、ワーカスレッドが不要になると、スレッドプール121はそのワーカスレッドをアイドルスレッドキュー132の末尾に追加する。これにより、ワーカスレッドはアイドルスレッドに遷移する。
【0049】
なお、
図5の例では、アイドルスレッドキュー132には、アイドルスレッドとしてスレッドTHR1,THR2,THR3が登録されている。
カレントスレッドポインタ133は、ワーカスレッドのうち、現在実行中である「カレントスレッド」を指し示す。
図5の例では、スレッドTHR4がカレントスレッドであり、スレッドTHR4によってタスクが実行されている。
【0050】
実行キュー134は、実行待ちのワーカスレッドを、実行待ちになった順に管理するためのキューである。実行待ちのワーカスレッドとは、実行が可能な状態のタスクに割り当てられているスレッドであり、例えば、イールドが発生したスレッドや、待ち合わせ状態から復帰したスレッドがある。
図5の例では、実行キュー134には、先頭から順にスレッドTHR5,THR6,THR7,THR8が登録されている。これは、実行キュー134に対してスレッドTHR5,THR6,THR7,THR8が順番に追加されたことを示す。
【0051】
スレッドスケジューラ122は、実行キュー134の先頭から取り出したスレッド、または、タスクキュー131の先頭から取り出したタスクに割り当てたスレッドを、カレントスレッドポインタ133に接続させてカレントスレッドにし、このスレッドを実行する。また、スレッドスケジューラ122は、タスクの終了によってカレントスレッドが不要になった場合、カレントスレッドをスレッドプール121に返却する。
【0052】
なお、マルチスレッド制御の方法には、例えば、プリエンプティブ型とノンプリエンプティブ型(協調型)とがある。プリエンプティブ型では、スレッドの実行開始後、例えば一定時間内に割り込みによって制御がスレッドからスレッドスケジューラ122に移る。これにより、割り込みによって実行スレッドが切り替えられる。これに対して、ノンプリエンプティブ型では、実行中のスレッド自身が制御をスレッドスケジューラ122に渡す。
【0053】
本実施の形態では、スレッドスケジューラ122は、ノンプリエンプティブ型のマルチスレッド制御を行う。ストレージ制御装置100では、I/O制御部110から実行時間の短い(粒度の小さい)タスクが大量に発生する。このため、ノンプリエンプティブ型を採用して、スレッドの切り替え制御の一部をスレッド自身が担うようにすることで、切り替え制御を効率化できる。
【0054】
ところで、スレッドを用いたタスクの実行制御では、タスク同士や、タスクとスレッドとの間の実行順序が定まっていない場合がある。例えば、
図5のようなタスクキュー131を用いたとしても、タスクキュー131の中のどの位置にタスクを挿入できるかによって、タスクの実行順が変化してしまう。また、
図5のような実行キュー134を用いたとしても、実行キュー134の中のどの位置にスレッドを挿入できるかによって、スレッドやタスクの実行順が変化してしまう。このため、このように実行順序が定まっていない場合、時間的に後から投入されたタスクが先に実行される、すなわちタスクの追い越しが発生する場合がある。
【0055】
タスクの追い越しが連続して発生して、同じタスクが何度も追い越されてしまうと、そのタスクは長時間実行待ちのままになってしまう。このように、特定のタスクが長時間実行待ちになることは、タスクの沈み込みと呼ばれる。ストレージ制御装置100では、リードやライトなどのI/O処理は複数のタスクを含むが、その中の1つのタスクに沈み込みが発生すると、I/O要求に対する応答性能が悪化してしまう。これは、特定のI/O処理の応答時間が延びる事象を発生させるだけでなく、応答時間の異なるI/O処理が混在することで応答性能が不安定に見えるという事象も発生させる。このため、タスクの沈み込みをできるだけ発生させないようにすることが望まれる。
【0056】
タスクを投入順に実行するための方法として、タスクキュー131および実行キュー134に対しては新たなエントリを常に末尾に登録するとともに、1タスクに1アイドルスレッドを割り当てるようにする方法が考えられる。ここで、
図6を用いて、このような方法を用いた場合のタスク実行制御の比較例について説明する。
【0057】
図6は、タスク実行制御の比較例を説明するための図である。なお、
図6では、
図5に示した構成を用いてタスク実行制御を行うものとして説明する。
図6の例では、スレッドプール121に対してタスクTSK1,TSK2が順に登録されたとする。その結果、状態ST1に示すように、タスクキュー131には先頭からタスクTSK1,TSK2が登録される。また、状態ST1では、アイドルスレッドキュー132にスレッドTHR5~THR7が登録されているとする。
【0058】
この状態から、スレッドプール121に対してタスクTSK3が投入されたとする。この場合、状態ST2に示すように、タスクキュー131の末尾にタスクTSK3が追加される。
【0059】
また、タスクキュー131に登録された各スレッドにはスレッドプール121からスレッドが割り当てられ、そのスレッドが実行キュー134の末尾に追加される。状態ST2からは、状態ST3に示すように、タスクキュー131の先頭からタスクTSK1が取り出され、このタスクTSK1に対して、アイドルスレッドキュー132から取り出されたスレッドTHR5が割り当てられる。そして、状態ST4に示すように、タスクTSK1に割り当て済みのスレッドTHR5が、実行キュー134の末尾に追加される。
【0060】
また、図示しないが、この後、タスクTSK2にスレッドTHR6が割り当てられ、そのスレッドTHR6が実行キュー134の末尾に追加される。さらに、タスクTSK3にスレッドTHR7が割り当てられ、そのスレッドTHR7が実行キュー134の末尾に追加される。
図6の比較例では基本的に、タスクキュー131に大量のタスクが登録された場合、残っているアイドルスレッドのすべてがタスクキュー131のタスクに割り当てられ、それらのスレッドが実行キュー134に登録される。
【0061】
スレッドスケジューラ122は、実行キュー134の先頭からスレッドを1つずつ取り出して実行する。状態ST4では、スレッドTHR1が実行中であり、実行キュー134には先頭から順にスレッドTHR2,THR3,THR4,THR5が登録されている。この状態からスレッドTHR1によるタスクの実行が終了したとすると、スレッドTHR1はアイドルスレッドキュー132の末尾に追加されて、アイドルスレッドに戻される。そして、実行キュー134の先頭からスレッドTHR2が取り出されてカレントスレッドポインタ133に接続され、スレッドTHR2の実行が開始される。さらにその後、実行キュー134から同様の手順でスレッドTHR3,THR4,THR5が順に取り出され、実行される。また、タスクの実行が終了したスレッドは、アイドルスレッドに戻される。
【0062】
このように、タスクが投入された順にタスクにスレッドが割り当てられ、そのスレッドが実行キュー134の末尾に追加されることで、タスクの投入順にタスクを実行することができる。これにより、タスクの沈み込みが発生する可能性を低減できる。
【0063】
しかしながら、
図6の方法では、スレッドに割り当てられたタスクが終了するたびに、スレッドが切り替えられ、コンテキストスイッチが発生する。コンテキストスイッチでは、レジスタの書き替えなどが行われるため、処理負荷が大きい。また、多くのタスクを並列処理しようとするほどスレッドの数が多くなり、その分だけコンテキストスイッチの発生回数も多くなる。例えば、前述のようにストレージ制御では各タスクの粒度が小さく、しかも多くのI/O処理が短時間に発生することから、数千個から数万個のスレッドが生成され得る。このため、コンテキストスイッチの発生回数も増大し、その分の処理のオーバヘッドが大きくなって、I/O処理性能が低下する。さらに、スレッドに割り当てられたタスクが終了するたびに、アイドルスレッドキュー132へのスレッドの追加が行われるため、オーバヘッドはさらに大きくなってしまう。
【0064】
タスクの粒度が小さいことから、タスクの実行時間に対してオーバヘッドは相対的に大きく、I/O処理性能への影響が大きい。そのため、性能改善のためにスレッドの実行数(ワーカスレッドの数)を低減して、スレッドの切り替えやアイドルスレッドへの遷移の回数を少なくすることが望まれる。さらに、スレッドの数が多いほど必要なメモリ領域が大きくなる。スレッドによってメモリ領域が圧迫されると、それ以外の処理のためのメモリ領域のローカリティが低下し、キャッシュミスやページフォールトが頻出する原因となる。このような観点からも、スレッドの数を低減することが望まれる。
【0065】
また、
図6の方法を用いた場合でも、タスクの実行順が適正でなくなる場合がある。例えば、スレッドは、タスクの実行中に待ち合わせが発生して、サスペンドする場合がある。サスペンドしたスレッドが待ち合わせ状態から復帰すると、そのスレッドは実行キュー134の末尾に追加される。また、スレッドのイールドが発生するとスレッドの処理は後回しにされ、そのスレッドが実行キュー134の末尾に追加される。このように、タスクキュー131内のタスクに新たに割り当てられたスレッドだけでなく、タスクに割り当て済みのスレッドも実行キュー134に登録されることが原因となって、本来実行すべき順でタスクが実行されないケースが起こり得る。
【0066】
例えば、アイドルスレッドが枯渇して新規のタスクにスレッドを割り当てられない状態が発生すると、タスクがスレッドプール121に投入された後に、待ち合わせから復帰したスレッドまたはイールドが発生したスレッドが、実行キュー134に追加される場合がある。この場合、待ち合わせ状態から復帰したスレッドまたはイールドが発生したスレッドに割り当てられたタスクは、新規に投入されたタスクより先に実行されてしまい、タスクの実行順は本来実行すべき順序とは違ってしまう。また、タスクキュー131からタスクを取り出してスレッドを割り当てる、という処理に時間がかかることによって、そのスレッドを実行キュー134に登録するまでに遅延が発生することもあり得る。この場合にも、待ち合わせ状態から復帰したスレッドまたはイールドが発生したスレッドに割り当てられたタスクが先に実行キュー134に登録されて実行されてしまい、タスクの実行順が適正でなくなることがあり得る。
【0067】
すなわち、ここでいう「タスクの実行順が適正」とは、スレッドプール121に対する新規タスクの投入時刻と、スレッドが割り当て済みのタスクが実行キュー134に追加される時刻との間での前後関係が守られるように、タスクが実行されることを示す。
図6の方法を用いた場合でも、このような時間的な前後関係が変化した状態でタスクが実行されてしまう可能性がある。
【0068】
そこで、本実施の形態のストレージ制御装置100は、以下の
図7~
図10に示す処理により、タスクの実行順を適正化しつつ、スレッドの実行数を低減する。
図7は、チケット番号の付加について説明するための図である。ストレージ制御装置100では、タスクの実行順を適正化するために、チケットカウンタ123が用いられる。チケットカウンタ123は、タスクやスレッドの実行順(実行優先度)を示すチケット番号を発行するカウンタである。本実施の形態において、チケットカウンタ123は、昇順のチケット番号を発行する。この場合、チケット番号が小さいほど実行優先度が高い。チケット番号は、タスクキュー131に登録されるタスク、および実行キュー134に登録されるスレッドに付加される。
【0069】
例えば、
図7に示すように、スレッドプール121に対して新規のタスクが投入され、そのタスクがタスクキュー131の末尾に登録されたとき、そのタスクに対して、チケットカウンタ123から発行されたチケット番号が付加される。
図7の例では、新規のタスクTSK7がタスクキュー131に追加されたとき、タスクTSK7に対してチケット番号「5」が付加されている。
【0070】
また、
図7に示すように、イールドの発生や待ち合わせ状態からの復帰によってスレッドが実行キュー134の末尾に登録されたとき、そのスレッドに対して、チケットカウンタ123から発行されたチケット番号が付加される。
図7の例では、タスクTSK7の投入直後のタイミングで、タスクTSK4に割り当てられたスレッドTHR4が実行キュー134の末尾に追加されたとする。この場合、スレッドTHR4に対してチケット番号「6」が付加される。
【0071】
このような処理により、タスクキュー131のタスク、およびタスクに割り当てられた実行キュー134のスレッドのそれぞれに対して、正しい実行順を示すチケット番号が付加されるようになる。ここでいう「正しい実行順」とは、スレッドプール121に対するタスクの投入タイミングや、イールドの発生または待ち合わせ状態からの復帰のタイミングについて、時系列的な順序が一致していることを示す。
【0072】
図8は、スレッドの実行制御を示す第1の図である。
図8では、スレッドTHR1によってタスクTSK1が実行されているとする。そして、イールドや待ち合わせが発生せず、タスクTSK1の実行が終了したとする。このとき、タスクキュー131の先頭のタスクTSK7に付加されたチケット番号「2」と、実行キュー134の先頭のスレッドTHR2に付加されたチケット番号「3」とが比較される。この比較により、タスクTSK7と、スレッドTHR2が割り当てられたタスクTSK2のどちらを先に実行すべきかが判定される。
【0073】
図8の例では、タスクTSK7に付加されたチケット番号「2」の方が小さいので、タスクTSK7を先に実行すべきと判定される。この場合、タスクキュー131からタスクTSK7が取り出され、そのタスクTSK7に対して、タスクTSK1の実行を終了したスレッドTHR1が割り当てられる。そして、スレッドTHR1をそのまま用いてタスクTSK7が実行される。このケースでは、同一のカレントスレッドによって異なるタスクが連続して実行されるので、スレッドの切り替えが発生せず、その切り替えに伴うコンテキストスイッチも発生しない。
【0074】
図9は、スレッドの実行制御を示す第2の図である。
図9では、
図8の手順でスレッドTHR1によってタスクTSK7が実行されているとする。そして、イールドや待ち合わせが発生せず、タスクTSK7の実行が終了したとする。このとき、タスクキュー131の先頭のタスクTSK8に付加されたチケット番号「4」と、実行キュー134の先頭のスレッドTHR2に付加されたチケット番号「3」とが比較される。この比較により、タスクTSK8と、スレッドTHR2が割り当てられたタスクTSK2のどちらを先に実行すべきかが判定される。
【0075】
図9の例では、スレッドTHR2に付加されたチケット番号「3」の方が小さいので、スレッドTHR2を先に実行すべきと判定される。この場合、カレントスレッドであるスレッドTHR1はアイドルスレッドキュー132に追加されて、アイドルキューに戻される。そして、実行キュー134からスレッドTHR2が取り出され、このスレッドTHR2がカレントスレッドとなって、タスクTSK2が実行される。
【0076】
図10は、スレッドの実行制御を示す第3の図である。
図10では、
図9の手順でスレッドTHR2によってタスクTSK2が実行されているとする。そして、スレッドTHR2のイールドまたは待ち合わせが発生したとする。このとき、タスクキュー131の先頭のタスクTSK8に付加されたチケット番号「4」と、実行キュー134の先頭のスレッドTHR3に付加されたチケット番号「5」とが比較される。この比較により、タスクTSK8と、スレッドTHR3が割り当てられたタスクTSK3のどちらを先に実行すべきかが判定される。
【0077】
図10の例では、タスクTSK8に付加されたチケット番号「4」の方が小さいので、タスクTSK8を先に実行すべきと判定される。この場合、カレントスレッドであるスレッドTHR2はサスペンド状態となる。イールド発生の場合、スレッドTHR2は実行キュー134の末尾に追加される。待ち合わせ発生の場合、スレッドTHR2は待ち合わせ管理データ135の管理下に入る。また、タスクキュー131からタスクTSK8が取り出されるとともに、アイドルスレッドキュー132からアイドルスレッド(ここではスレッドTHR5)が取り出されて、タスクTSK8に対してスレッドTHR5が割り当てられる。そして、スレッドTHR5がカレントスレッドとなって、タスクTSK8が実行される。
【0078】
以上の
図7~
図10に示した処理によれば、実行キュー134にはすでにタスクに割り当て済みのスレッドしか登録されず、タスクキュー131に登録された新規のタスクに対しては、そのタスクを実行する段階でスレッドが割り当てられる。タスクに対するスレッドの割り当てにかかる時間は、タスクが投入されてからタスクの実行が開始されるまでのどの段階でスレッド割り当てが行われたとしても、変わらない。そのため、タスクの実行段階でスレッドを割り当てることで、スレッド割り当ての処理負荷を増やすことなく、新規のワーカスレッドの発生数を可能な限り抑制できる。その結果、ワーカスレッドの同時発生数を低減できる。
【0079】
また、
図8のケースのように、カレントスレッドから実行すべきタスクが解放されたとき、タスクキュー131のタスクは同じカレントスレッドを用いて実行される。このように1つのスレッドで複数のタスクを連続して実行できる仕組みを設けたことにより、ワーカスレッドの同時発生数をさらに低減できる。
【0080】
ワーカスレッドの同時発生数の低減は、ワーカスレッドが多い分だけ実行スレッドの切り替え回数が多くなるという意味で、間接的にコンテキストスイッチの発生回数の低減に寄与する。また、
図8のケースでは、スレッドを切り替えずにタスクを連続実行できるので、
図8の処理は直接的にコンテキストスイッチの発生回数の低減に寄与する。いずれにしても、コンテキストスイッチの発生回数が低減されることで、その発生によるオーバヘッドを小さくすることができ、その結果としてストレージ制御におけるI/O処理性能を向上させることができる。
【0081】
また、
図7~
図10に示した処理によれば、タスクキュー131に追加されるタスクと、実行キュー134に追加されるスレッドに対して、実行優先度を示すチケット番号が付加される。そして、タスクキュー131の先頭タスクと実行キュー134の先頭スレッドとの間でチケット番号が比較され、その比較結果によって、先頭タスクと、先頭スレッドが割り当てられているタスクのどちらを先に実行するかが判定される。このような仕組みにより、タスクの実行順を適正化できる。すなわち、スレッドプール121に対する新規タスクの投入時刻と、スレッドが割り当て済みのタスクが実行キュー134に追加される時刻との間での前後関係が守られるように、タスクの実行順を制御できる。
【0082】
特に、
図8のケースでは、実行キュー134内のスレッドが割り当てられたタスクより実行優先度の高いタスクキュー131内のタスクを先に実行でき、なおかつ、そのタスクを現在のカレントスレッドによって連続的に実行できる。したがって、タスクやスレッドへのチケット番号の付加と、タスクキュー131の先頭タスクと実行キュー134の先頭スレッドとの間のチケット番号の比較は、タスク実行順の適正化とコンテキストスイッチの発生回数低減の両方に寄与する。
【0083】
ここで、タスク実行順の適正化についての具体例を示す。
図11は、タスクの発生順の例を示す図である。
図11の例では、スレッドTHR11によってタスクTSK11が実行されている状態から、スレッドプール121に対して新規のタスクTSK12,TSK13が順に投入される。次に、タスクTSK1に割り当てられたスレッドTHR1が待ち合わせ状態から復帰する。次に、スレッドプール121に対して新規のタスクTSK14が投入される。次に、タスクTSK2に割り当てられたスレッドTHR2が待ち合わせ状態から復帰し、さらにタスクTSK3に割り当てられたスレッドTHR3が待ち合わせ状態から復帰する。次に、スレッドプール121に対して新規のタスクTSK15が投入される。次に、タスクTSK4に割り当てられたスレッドTHR4が待ち合わせ状態から復帰する。次に、スレッドプール121に対して新規のタスクTSK16が投入される。
【0084】
なお、第2の実施の形態のストレージ制御装置100では、上記のタスクの発生順にしたがってチケット番号「1」~「9」が発行される。
図11においてタスクTSK1~TSK4に付加されているチケット番号「3」,「5」,「6」,「8」は、実際にはスレッドTHR1~THR4に付加される。
【0085】
図12は、比較例によるタスクの実行制御例を示す図である。この
図12は、
図6に示した比較例の処理によって
図11のタスクの実行を制御した場合を示す。なお、比較例の処理では、
図11に示されたチケット番号は付加されない。また、スレッドプール121にタスクが投入された場合、そのタスクが一旦タスクキュー131に登録された後、そのタスクにスレッドが割り当てられるが、
図12の説明ではタスクキュー131への登録を省略する。
【0086】
図12の初期状態では、スレッドTHR11によってタスクTSK11が実行中であり、アイドルスレッドキュー132に登録されているアイドルスレッドの数が「3」であるとする。この状態から、スレッドプール121にタスクTSK12が投入されると、タスクTSK12に対してアイドルスレッドキュー132からスレッドTHR12が割り当てられ、スレッドTHR12が実行キュー134に追加される。このとき、アイドルスレッドの数は「2」に減少する(状態ST11)。
【0087】
次に、スレッドプール121にタスクTSK13が投入されると、タスクTSK13に対してアイドルスレッドキュー132からスレッドTHR13が割り当てられ、スレッドTHR13が実行キュー134に追加される。このとき、アイドルスレッドの数は「1」に減少する(状態ST12)。次に、タスクTSK1に割り当てられたスレッドTHR1が待ち合わせ状態から復帰すると、スレッドTHR1が実行キュー134に追加される(状態ST13)。
【0088】
次に、スレッドプール121にタスクTSK14が投入されると、タスクTSK14に対してアイドルスレッドキュー132からスレッドTHR14が割り当てられ、スレッドTHR14が実行キュー134に追加される。このとき、アイドルスレッドの数は「0」に減少する(状態ST14)。次に、タスクTSK2に割り当てられたスレッドTHR2が待ち合わせ状態から復帰すると、スレッドTHR2が実行キュー134に追加される(状態ST15)。次に、タスクTSK3に割り当てられたスレッドTHR3が待ち合わせ状態から復帰すると、スレッドTHR3が実行キュー134に追加される(状態ST16)。
【0089】
次に、スレッドプール121にタスクTSK15が投入され、タスクTSK15がタスクキュー131に登録される。しかし、このときアイドルスレッドが残っていないので、タスクTSK15にスレッドを割り当てることができず、タスクTSK15はタスクキュー131に登録されたままになる(状態ST17)。次に、タスクTSK4に割り当てられたスレッドTHR4が待ち合わせ状態から復帰すると、スレッドTHR4が実行キュー134に追加される(状態ST18)。
【0090】
次に、スレッドプール121にタスクTSK16が投入され、タスクTSK16がタスクキュー131に登録される。しかし、このときアイドルスレッドが残っていないので、タスクTSK16にスレッドを割り当てることができず、タスクTSK16はタスクキュー131に登録されたままになる(状態ST19)。
【0091】
次に、スレッドTHR11によるタスクTSK11の実行が終了したとする。タスクTSK11の終了によりスレッドTHR11は不要になり、スレッドTHR11はアイドルスレッドキュー132に登録されてアイドルスレッドになる。これにより、アイドルスレッドの数は「1」に増加し、タスクキュー131のタスクTSK15にスレッドを割り当て可能になる。したがって、タスクキュー131からタスクTSK15が取り出され、タスクTSK15に対してアイドルスレッドキュー132からスレッドTHR11が割り当てられ、スレッドTHR11が実行キュー134に追加される。このとき、アイドルスレッドの数は再度「0」となる。また、実行キュー134の先頭からスレッドTHR12が取り出され、スレッドTHR12によってタスクTSK12が実行される(状態ST20)。
【0092】
次に、タスクTSK12を実行中のスレッドTHR12にイールドが発生し、スレッドTHR12が実行キュー134の末尾に追加されたとする。このとき、実行キュー134の先頭からスレッドTHR13が取り出され、スレッドTHR13によりタスクTSK13が実行される(状態ST21)。
【0093】
これ以後、実行キュー134からスレッドが順次取り出されて、取り出されたスレッドによってタスクが実行される。したがって、タスクTSK1,TSK14,TSK2,TSK3,TSK4,TSK15,TSK12の順に実行される。
図11でのタスクの順序と比較すると、タスクTSK15とタスクTSK4との順序が入れ替わっており、タスクが正しい順序で実行されていないことがわかる。また、
図12の状態ST21ではタスクTSK16にはスレッドが割り当てられていないので、タスクTSK16の投入後にイールドしたスレッドTHR12が割り当てられたタスクTSK12は、タスクTSK16より先に実行されてしまう。
【0094】
以上の
図12は、アイドルスレッドが枯渇して新規タスクに対するスレッドの割り当てが不可能になることによって、タスクの実行順が変化してしまう場合について例示した。しかし、他の例として、新規タスクに対するスレッドの割り当て処理にかかる時間によって、タスクの実行順が変化する場合もある。例えば、あるタスクが投入されてスレッドの割り当て処理が開始された後、別のスレッドが待ち合わせ状態から復帰したとする。このとき、スレッドの割り当て処理が完了する前に復帰したスレッドが実行キュー134に追加されてしまうと、タスクの実行順が変化してしまう。
【0095】
図13、
図14は、第2の実施の形態によるタスクの実行制御例を示す図である。
図13、
図14は、第2の実施の形態のストレージ制御装置100において
図11のタスクの実行を制御した場合を示す。
【0096】
図13の初期状態では、
図12の初期状態と同様に、スレッドTHR11によってタスクTSK11が実行中であり、アイドルスレッドキュー132に登録されているアイドルスレッドの数が「3」であるとする。この状態から、スレッドプール121にタスクTSK12が投入されると、タスクTSK12はタスクキュー131に追加され、チケット番号「1」がタスクTSK12に付加される(状態ST31)。次に、スレッドプール121にタスクTSK13が投入されると、タスクTSK13はタスクキュー131に追加され、チケット番号「2」がタスクTSK13に付加される(状態ST32)。
【0097】
次に、タスクTSK1に割り当てられたスレッドTHR1が待ち合わせ状態から復帰すると、スレッドTHR1が実行キュー134に追加され、チケット番号「3」がスレッドTHR1に付加される(状態ST33)。次に、スレッドプール121にタスクTSK14が投入されると、タスクTSK14はタスクキュー131に追加され、チケット番号「4」がタスクTSK14に付加される(状態ST34)。
【0098】
次に、タスクTSK2に割り当てられたスレッドTHR2が待ち合わせ状態から復帰すると、スレッドTHR2が実行キュー134に追加され、チケット番号「5」がスレッドTHR2に付加される(状態ST35)。次に、タスクTSK3に割り当てられたスレッドTHR3が待ち合わせ状態から復帰すると、スレッドTHR3が実行キュー134に追加され、チケット番号「6」がスレッドTHR3に付加される(状態ST36)。
【0099】
次に、スレッドプール121にタスクTSK15が投入されると、タスクTSK15はタスクキュー131に追加され、チケット番号「7」がタスクTSK15に付加される(状態ST37)。次に、タスクTSK4に割り当てられたスレッドTHR4が待ち合わせ状態から復帰すると、スレッドTHR4が実行キュー134に追加され、チケット番号「8」がスレッドTHR4に付加される(状態ST38)。次に、スレッドプール121にタスクTSK16が投入されると、タスクTSK16はタスクキュー131に追加され、チケット番号「9」がタスクTSK16に付加される(状態ST39)。
【0100】
次に、スレッドTHR11によるタスクTSK11の実行が終了し、スレッドTHR11が不要になったとする。このとき、タスクキュー131の先頭のタスクTSK12に付加されたチケット番号「1」と、実行キュー134の先頭のスレッドTHR1に付加されたチケット番号「3」とが比較される。この例ではタスクTSK12に付加されたチケット番号「1」の方が小さいので、タスクTSK12を先に実行すべきと判定される。この場合、タスクキュー131からタスクTSK12が取り出され、タスクTSK12に対して、タスクTSK11の実行を終了したスレッドTHR11が割り当てられ、スレッドTHR11をそのまま用いてタスクTSK12が実行される(状態ST40)。同一のカレントスレッドによって2つのタスクが連続して実行されるので、スレッドの切り替えが発生せず、その切り替えに伴うコンテキストスイッチも発生しない。
【0101】
次に、タスクTSK12を実行中のスレッドTHR11にイールドが発生し、スレッドTHR11が実行キュー134の末尾に追加されたとする。スレッドTHR11にはチケット番号「10」が付加される。このとき、タスクキュー131の先頭のタスクTSK13に付加されたチケット番号「2」と、実行キュー134の先頭のスレッドTHR1に付加されたチケット番号「3」とが比較される。この例ではタスクTSK13に付加されたチケット番号「2」の方が小さいので、タスクTSK13を先に実行すべきと判定される。この場合、タスクキュー131からタスクTSK13が取り出されるとともに、アイドルスレッドキュー132からアイドルスレッド(ここではスレッドTHR12)が取り出される。そして、タスクTSK13に対してスレッドTHR12が割り当てられ、スレッドTHR12によってタスクTSK13が実行される。このとき、アイドルスレッドの数は「2」に減少する(状態ST41)。
【0102】
以下、
図14を用いて説明を続ける。
次に、スレッドTHR12によるタスクTSK13の実行が終了し、スレッドTHR12が不要になったとする。このとき、タスクキュー131の先頭のタスクTSK14に付加されたチケット番号「4」と、実行キュー134の先頭のスレッドTHR1に付加されたチケット番号「3」とが比較される。この例ではスレッドTHR1に付加されたチケット番号「3」の方が小さいので、スレッドTHR1を先に実行すべきと判定される。この場合、スレッドTHR12はアイドルスレッドキュー132に追加されてアイドルキューに戻される。これにより、アイドルスレッドの数は「3」に増加する。また、実行キュー134からスレッドTHR1が取り出され、スレッドTHR1によってタスクTSK1が実行される(状態ST42)。
【0103】
次に、タスクTSK1を実行中のスレッドTHR1にイールドが発生し、スレッドTHR1が実行キュー134の末尾に追加されたとする。このとき、タスクキュー131の先頭のタスクTSK14に付加されたチケット番号「4」と、実行キュー134の先頭のスレッドTHR2に付加されたチケット番号「5」とが比較される。この例ではタスクTSK14に付加されたチケット番号「4」の方が小さい。この場合、タスクキュー131からタスクTSK14が取り出されるとともに、アイドルスレッドキュー132からアイドルスレッド(ここではスレッドTHR13)が取り出され、スレッドTHR13によってタスクTSK14が実行される。このとき、アイドルスレッドの数は「2」に減少する(状態ST43)。
【0104】
次に、タスクTSK14を実行中のスレッドTHR13にイールドが発生し、スレッドTHR13が実行キュー134の末尾に追加されたとする。このとき、タスクキュー131の先頭のタスクTSK15に付加されたチケット番号「7」と、実行キュー134の先頭のスレッドTHR2に付加されたチケット番号「5」とが比較される。この例ではスレッドTHR2に付加されたチケット番号「5」の方が小さい。この場合、実行キュー134からスレッドTHR2が取り出され、スレッドTHR2によってタスクTSK2が実行される(状態ST44)。
【0105】
次に、タスクTSK2を実行中のスレッドTHR2にイールドが発生し、スレッドTHR2が実行キュー134の末尾に追加されたとする。このとき、タスクキュー131の先頭のタスクTSK15に付加されたチケット番号「7」と、実行キュー134の先頭のスレッドTHR3に付加されたチケット番号「6」とが比較される。この例ではスレッドTHR3に付加されたチケット番号「6」の方が小さい。この場合、実行キュー134からスレッドTHR3が取り出され、スレッドTHR3によってタスクTSK3が実行される(状態ST45)。
【0106】
次に、タスクTSK3を実行中のスレッドTHR3にイールドが発生し、スレッドTHR3が実行キュー134の末尾に追加されたとする(図示せず)。このとき、タスクキュー131の先頭のタスクTSK15に付加されたチケット番号「7」と、実行キュー134の先頭のスレッドTHR4に付加されたチケット番号「8」とが比較される。この例ではタスクTSK15に付加されたチケット番号「7」の方が小さい。この場合、タスクキュー131からタスクTSK15が取り出されるとともに、アイドルスレッドキュー132からアイドルスレッド(ここではスレッドTHR14)が取り出され、スレッドTHR14によってタスクTSK15が実行される。このとき、アイドルスレッドの数は「1」に減少する(状態ST46)。
【0107】
タスクTSK15を実行中のスレッドTHR14にイールドが発生し、スレッドTHR14が実行キュー134の末尾に追加されたとする(図示せず)。このとき、タスクキュー131の先頭のタスクTSK16に付加されたチケット番号「9」と、実行キュー134の先頭のスレッドTHR4に付加されたチケット番号「8」とが比較される。この例ではスレッドTHR4に付加されたチケット番号「8」の方が小さい。この場合、実行キュー134からスレッドTHR4が取り出され、スレッドTHR4によってタスクTSK4が実行される(状態ST47)。
【0108】
以上の
図13、
図14の処理によれば、タスクが
図11に示した順序と同じ順序で実行される。特に、
図12の処理ではタスクTSK15,TSK4の実行順が入れ替わっていたが、
図14ではこれらの実行順が入れ替わらない。また、
図14の状態ST47の後では、タスクTSK16のチケット番号「9」とスレッドTHR11のチケット番号「10」との比較に応じてタスクTSK16が先に実行されるので、この点でも
図12の処理からタスク実行順が改善される。このように、本実施の形態のストレージ制御装置100によれば、タスクの実行順を適正化できる。
【0109】
さらに、
図12の処理と比較して、
図13、
図14の処理によればアイドルスレッドがタスクに割り当てられる数が少なくなるので、スレッドの同時使用数(ワーカスレッドの同時発生数)を低減できる。これは、新規に投入されたタスクに対しては実行段階でスレッドが割り当てられ、なおかつその際に、既存のカレントスレッドを割り当てて、そのカレントスレッドによってタスクを実行可能な場合があるからである。例えば、
図13の状態ST40では、同じスレッドTHR11によってタスクTSK11,TSK12が連続して実行されている。これにより、スレッドの切り替え回数を低減でき、その結果、コンテキストスイッチの発生回数が低減されて、その発生によるオーバヘッドを抑制できる。したがって、ストレージ制御装置100のI/O処理性能を向上させることができる。
【0110】
次に、ストレージ制御装置100の処理についてフローチャートを用いて説明する。
まず、
図15は、タスク投入処理の手順を示すフローチャートの例である。
図15の処理は、スレッドプール121に新規のタスクが投入されると開始される。
【0111】
[ステップS11]スレッドプール121は、チケットカウンタ123からチケット番号を取得する。
[ステップS12]スレッドプール121は、チケットカウンタ123をカウントアップする。
【0112】
[ステップS13]スレッドプール121は、取得したチケット番号を、投入されたタスクに付加する。
[ステップS14]スレッドプール121は、チケット番号が付加されたタスクをタスクキュー131の末尾に追加する。
【0113】
図16~
図18は、スレッドのスケジューリング処理の手順を示すフローチャートの例である。
[ステップS21]スレッドスケジューラ122は、実行キュー134が空かを判定する。スレッドスケジューラ122は、実行キュー134が空の場合、ステップS22の処理を実行し、実行キュー134にスレッドが登録されている場合、
図17のステップS31の処理を実行する。
【0114】
[ステップS22]スレッドスケジューラ122は、タスクキュー131が空かをスレッドプール121に問い合わせる。スレッドスケジューラ122は、スレッドプール121からの返答に基づき、タスクキュー131が空の場合、ステップS21の処理を実行し、タスクキュー131にタスクが登録されている場合、ステップS23の処理を実行する。
【0115】
[ステップS23]スレッドスケジューラ122は、スレッドプール121を通じて、タスクキュー131の先頭タスクを読み出す。具体的には、関数を示すポインタや関数の引数など、タスクに関する情報が読み出される。
【0116】
[ステップS24]スレッドスケジューラ122は、アイドルスレッドキュー132が空かをスレッドプール121に問い合わせる。スレッドスケジューラ122は、スレッドプール121からの返答に基づき、アイドルスレッドキュー132が空の場合、ステップS21の処理を実行し、アイドルスレッドキュー132にアイドルスレッドが登録されている場合、ステップS25の処理を実行する。
【0117】
[ステップS25]スレッドスケジューラ122は、スレッドプール121を通じて、アイドルスレッドキュー132から先頭のアイドルスレッドを取り出す。
[ステップS26]スレッドスケジューラ122は、ステップS23で読み出したタスクをタスクキュー131から除去するようにスレッドプール121に依頼する。これにより、該当タスクがタスクキュー131から取り出される(除去される)。
【0118】
[ステップS27]スレッドスケジューラ122は、ステップS23で読み出したタスクに対して、ステップS25で取り出したスレッドを割り当てる。具体的には、スレッドに対し、そのスレッドの引数として、タスクが示す関数ポインタや関数の引数が引き渡される。
【0119】
[ステップS28]スレッドに制御が移され(CPUリソースが明け渡され)、スレッドによってタスクが実行される。その後、制御がスレッドスケジューラ122に戻ると、スレッドスケジューラ122はステップS21の処理を実行する。
【0120】
以上の
図16の処理では、実行キュー134が空であり、タスクキュー131にタスクが登録されている場合、タスクキュー131から取り出されたタスクにアイドルスレッドが割り当てられ、このスレッドによってタスクが実行される。
【0121】
以下、
図17を用いて説明を続ける。
[ステップS31]スレッドスケジューラ122は、実行キュー134の先頭スレッドを読み出す。具体的には、スレッドの引数(タスクが示す関数ポインタ、関数の引数を含む)やスレッドに付加されたチケット番号が読み出される。
【0122】
[ステップS32]スレッドスケジューラ122は、タスクキュー131が空かをスレッドプール121に問い合わせる。スレッドスケジューラ122は、スレッドプール121からの返答に基づき、タスクキュー131が空の場合、
図18のステップS41の処理を実行し、タスクキュー131にタスクが登録されている場合、ステップS33の処理を実行する。
【0123】
[ステップS33]スレッドスケジューラ122は、スレッドプール121を通じて、タスクキュー131の先頭タスクを読み出す。具体的には、関数を示すポインタや関数の引数、付加されたチケット番号など、タスクに関する情報が読み出される。
【0124】
[ステップS34]スレッドスケジューラ122は、ステップS31で読み出したスレッドのチケット番号と、ステップS33で読み出したタスクのチケット番号とを比較する。スレッドスケジューラ122は、タスクのチケット番号の方が小さい場合、ステップS35の処理を実行し、スレッドのチケット番号の方が小さい場合、
図18のステップS41の処理を実行する。
【0125】
[ステップS35]スレッドスケジューラ122は、アイドルスレッドキュー132が空かをスレッドプール121に問い合わせる。スレッドスケジューラ122は、スレッドプール121からの返答に基づき、アイドルスレッドキュー132が空の場合、
図18のステップS41の処理を実行し、アイドルスレッドキュー132にアイドルスレッドが登録されている場合、ステップS36の処理を実行する。
【0126】
[ステップS36]スレッドスケジューラ122は、スレッドプール121を通じて、アイドルスレッドキュー132から先頭のアイドルスレッドを取り出す。
[ステップS37]スレッドスケジューラ122は、ステップS33で読み出したタスクをタスクキュー131から除去するようにスレッドプール121に依頼する。これにより、該当タスクがタスクキュー131から取り出される(除去される)。
【0127】
[ステップS38]スレッドスケジューラ122は、ステップS33で読み出したタスクに対して、ステップS36で取り出したスレッドを割り当てる。具体的には、スレッドに対し、そのスレッドの引数として、タスクが示す関数ポインタや関数の引数が引き渡される。
【0128】
[ステップS39]スレッドに制御が移され、スレッドによってタスクが実行される。その後、制御がスレッドスケジューラ122に戻ると、スレッドスケジューラ122は
図16のステップS21の処理を実行する。
【0129】
以下、
図18を用いて説明を続ける。
[ステップS41]スレッドスケジューラ122は、ステップS31で読み出したスレッドを実行キュー134から除去する。
【0130】
[ステップS42]ステップS31で読み出されたスレッドに制御が移され、このスレッドによってタスクが実行される。その後、制御がスレッドスケジューラ122に戻ると、スレッドスケジューラ122は
図16のステップS21の処理を実行する。
【0131】
以上の
図17、
図18の処理では、タスクキュー131および実行キュー134のいずれも空でない場合には、タスクキュー131の先頭タスクのチケット番号と実行キュー134の先頭スレッドのチケット番号とが比較される。先頭タスクのチケット番号の方が小さく、アイドルスレッドが残っている場合には、アイドルスレッドが取り出され、そのスレッドによって先頭タスクが実行される(ステップS39)。先頭スレッドのチケット番号の方が小さい場合、および、先頭タスクのチケット番号の方が小さいがアイドルスレッドが残っていない場合には、先頭スレッドが実行される(ステップS42)。
【0132】
図19は、スレッドによるタスク実行処理の手順を示すフローチャートの例である。
図19の処理は、
図16のステップS28、
図17のステップS39、
図18のステップS42の処理に対応する。
【0133】
[ステップS51]スレッドによる関数実行処理が行われる。
ここで、ステップS51の処理が終了した状態とは、スレッドが割り当てられていたタスクに含まれる処理が終了し、スレッドが解放された状態である。ステップS51の処理が終了すると、解放されたスレッドによりステップS52~S59の処理が実行される。なお、ステップS51の終了時点で制御がスレッドからスレッドスケジューラ122に一時的に戻され、ステップS52~S59の処理がスレッドスケジューラ122によって実行されてもよい。
【0134】
[ステップS52]スレッドは、タスクキュー131が空かをスレッドプール121に問い合わせる。スレッドは、スレッドプール121からの返答に基づき、タスクキュー131が空の場合、ステップS59の処理を実行し、タスクキュー131にタスクが登録されている場合、ステップS53の処理を実行する。
【0135】
[ステップS53]スレッドは、スレッドプール121を通じて、タスクキュー131の先頭タスクを読み出す。具体的には、関数を示すポインタや関数の引数、付加されたチケット番号など、タスクに関する情報が読み出される。
【0136】
[ステップS54]スレッドは、実行キュー134が空かを判定する。スレッドは、実行キュー134が空の場合、ステップS57の処理を実行し、実行キュー134にスレッドが登録されている場合、ステップS55の処理を実行する。
【0137】
[ステップS55]スレッドは、実行キュー134の先頭スレッドを読み出す。具体的には、スレッドの引数やスレッドに付加されたチケット番号が読み出される。
[ステップS56]スレッドは、ステップS53で読み出したタスクのチケット番号と、ステップS55で読み出したスレッドのチケット番号とを比較する。スレッドは、タスクのチケット番号の方が小さい場合、ステップS57の処理を実行し、スレッドのチケット番号の方が小さい場合、ステップS59の処理を実行する。前者の場合、タスクキュー131の先頭タスクの実行優先度が高いと判定され、後者の場合、実行キュー134の先頭スレッドが割り当てられたタスクの実行優先度が高いと判定される。
【0138】
[ステップS57]スレッドは、ステップS53で読み出したタスクをタスクキュー131から除去するようにスレッドプール121に依頼する。これにより、該当タスクがタスクキュー131から取り出される(除去される)。
【0139】
[ステップS58]スレッドは、ステップS53で読み出したタスクに対して、自分自身(カレントスレッド)を割り当てる。具体的には、スレッドに対し、そのスレッドの引数として、タスクが示す関数ポインタや関数の引数が引き渡される。
【0140】
この後、処理がステップS51に進められ、ステップS53で読み出したタスクに対応する関数が、同じスレッドによって実行される。すなわち、同じスレッドによって複数のタスクが連続的に実行される。この場合、ステップS53で読み出したタスクの実行時にコンテキストスイッチが発生しない。
【0141】
[ステップS59]スレッドはサスペンドし、自分自身をアイドルスレッドキュー132に登録するようにスレッドプール121に依頼する。これにより、スレッドはアイドルスレッドキュー132の末尾に追加されて、アイドルスレッドに遷移する。この後、制御がスレッドスケジューラ122に戻され、処理が
図16のステップS21に進められる。
【0142】
ここで、ステップS56,S59の順に処理が行われた場合、その後に
図16のステップS21で実行キュー134が空でないと判定され、さらに
図17のステップS31~S39が実行されることで、実行キュー134の先頭スレッドが実行される。一方、ステップS52,S59の順に処理が行われた場合には、
図16のステップS21での判定結果は確定されない。そして、ステップS21で実行キュー134が空でないと判定された場合には、
図17のステップS31~S39が実行されることで、同様に実行キュー134の先頭スレッドが実行される。いずれのケースでも、ステップS59でスレッドがサスペンドし、ステップS39で別のスレッドが実行されることで、コンテキストスイッチが発生する。
【0143】
一方、ステップS58で現状のカレントスレッドがタスクキュー131の先頭タスクに割り当てられ、ステップS51でカレントスレッドにより先頭タスクが実行されるケースでは、同一のスレッドによって複数のタスクが連続的に実行される。この場合、スレッドの切り替えが発生しないので、スレッド切り替えに伴うコンテキストスイッチを発生させずに複数のタスクを連続的に実行できる。
【0144】
図20は、関数実行処理の手順を示すフローチャートの例である。
図20の処理は、
図19のステップS51の処理に対応する。
[ステップS61]スレッドは、自分自身に対応付けられた関数ポインタおよび関数の引数に基づいて、関数を実行する。
【0145】
[ステップS62]待ち合わせが発生した場合、処理がステップS63に進められる。待ち合わせが発生しなかった場合、処理がステップS64に進められる。
[ステップS63]スレッドはサスペンドし、スレッド自身の情報を待ち合わせ管理データ135に登録することで、待ち合わせ状態に遷移する。この後、制御がスレッドスケジューラ122に戻され、処理が
図16のステップS21に進められる。
【0146】
[ステップS64]イールドが発生した場合、スレッドによるタスクの処理が途中で休止され、処理がステップS65に進められる。イールドが発生しなかった場合、すなわち、ステップS61での関数の処理が終了した場合には、関数実行処理が終了し、処理が
図19のステップS52に進められる。
【0147】
[ステップS65]スレッドは、チケットカウンタ123からチケット番号を取得する。
[ステップS66]スレッドは、チケットカウンタ123をカウントアップする。
【0148】
[ステップS67]スレッドは、取得したチケット番号を自分自身に付加する。
[ステップS68]スレッドはサスペンドし、チケット番号が付加された自分自身を実行キュー134の末尾に追加する。この後、制御がスレッドスケジューラ122に戻され、処理が
図16のステップS21に進められる。
【0149】
ここで、スレッドの待ち合わせの例について補足説明する。
ここでは例として、特定のハードウェアとの間で通信を行うタスクに割り当てられたスレッドの待ち合わせについて説明する。以下の処理は、特定のハードウェアと通信するためのインタフェース回路との間で実行される。例えば、特定のハードウェアとしてホストサーバ50と通信する場合、ホストサーバ50と通信するためのホストインタフェース105との間で以下の処理が実行される。
【0150】
RAM102には、上記のインタフェース回路に対応する完了キューが用意される。完了キューは、インタフェース回路に対してタスクが依頼した処理が完了した場合に、その完了を示すエントリが登録されるキューである。また、待ち合わせ管理データ135には、インタフェース回路に対応する待ち合わせ管理キューが含まれる。待ち合わせ管理キューは、サスペンドして待ち合わせ状態になったスレッドに対応するエントリが登録されるキューである。なお、通信先の特定のハードウェアが複数存在する場合、完了キューおよび待ち合わせ管理キューは、ハードウェアのそれぞれに対応するインタフェース回路ごとに用意される。
【0151】
スレッドは、インタフェース回路に対して処理を依頼するタスクを実行すると、依頼した処理が完了したことを示すエントリが完了キューにあるかを確認する。インタフェース回路は、スレッドから処理が依頼されると、その処理を実行し、実行が完了すると、完了メッセージをスレッドから指定された受信バッファ上の領域に格納するとともに、処理が完了したことを示すエントリを完了キューに登録する。このエントリには、処理の依頼元のスレッドの識別情報が含まれる。
【0152】
例えば、インタフェース回路は、スレッドから上記のハードウェアからのデータ受信が依頼されると、依頼されたデータをハードウェアから受信する。インタフェース回路は、データ受信が完了すると、完了メッセージと受信したデータとを受信バッファに格納するとともに、依頼元のスレッドの識別情報とを含むエントリを完了キューに登録する。スレッドは、スレッド自身の識別情報を含むエントリが完了キューにない場合、サスペンドし、スレッド自身を示すエントリを待ち合わせ管理キューに登録することで待ち合わせ状態になる。待ち合わせ管理キューのエントリには、スレッドの識別情報と、受信バッファにおける、完了メッセージや受信データの格納先アドレスが含まれる。
【0153】
図20の処理では、ステップS61において、インタフェース回路に処理を依頼するための関数が実行される。そして、この関数の実行が完了したことを示すエントリが完了キューに登録されていない場合、ステップS62で「Yes」と判定され、ステップS63でスレッドが待ち合わせ管理キューに登録される。
【0154】
一方、スレッドスケジューラ122は、間欠的なタイミングで完了キューをポーリングし、待ち合わせ管理キューに登録されたスレッドに対応するエントリが完了キューに登録されているかを確認する。該当するエントリが完了キューに登録されていた場合、スレッドスケジューラ122は、エントリに対応するスレッドを待ち合わせ管理キューから取り出し、そのスレッドを実行キュー134の末尾に登録する。これにより、スレッドは待ち合わせ状態から復帰する。スレッドは、実行キュー134から取り出されたときに、受信バッファ上の完了メッセージや受信データを用いて、タスクに含まれる後続の処理を実行する。
【0155】
図21は、スレッドスケジューラによるスレッドの復帰判定処理の手順を示すフローチャートの例である。
[ステップS71]スレッドスケジューラ122は、待ち合わせ状態のスレッドのうち、復帰するスレッドがあるかを判定する。上記の待ち合わせの例では、スレッドスケジューラ122が完了キューをポーリングし、待ち合わせ管理キューに登録されたスレッドに対応するエントリが完了キューに登録されている場合、そのスレッドを復帰するスレッドと判定する。スレッドスケジューラ122は、復帰するスレッドがある場合、ステップS72の処理を実行し、復帰するスレッドがない場合、復帰判定処理を終了する。
【0156】
[ステップS72]スレッドスケジューラ122は、チケットカウンタ123からチケット番号を取得する。
[ステップS73]スレッドスケジューラ122は、チケットカウンタ123をカウントアップする。
【0157】
[ステップS74]スレッドスケジューラ122は、復帰すると判定されたスレッドを待ち合わせ管理データ135から取り出し、取得したチケット番号をそのスレッドに付加する。上記の待ち合わせの例では、このとき、復帰すると判定されたスレッドが待ち合わせ管理キューから取り出される(待ち合わせ管理キューからは除去される)。
【0158】
[ステップS75]スレッドスケジューラ122は、チケット番号が付加されたスレッドを実行キュー134の末尾に追加する。これにより、スレッドは待ち合わせ状態から復帰する。
【0159】
図21の復帰判定処理は、例えば、次のようなタイミングで実行される。
ノンプリエンプティブ型(協調型)のマルチスレッド制御では、一例として、スレッドの実行が終了して制御がスレッドスケジューラ122に戻ったときに、復帰可能なスレッドがあるかを確認する、というルールが採用される。このルールにしたがえば、
図16のステップS28、
図17のステップS39、
図18のステップS42でのスレッドによるタスクの実行が終了して、制御がスレッドスケジューラ122に戻ったときに、
図21の処理が実行されればよい。ただし、本実施の形態では、同一のスレッドが複数のタスクを連続的に実行し得る。このため、さらに、スレッドが1つのタスクの実行を終了してから、同じスレッドが次のタスクを実行するまでの期間に、
図21の処理が実行される。例えば、
図19におけるステップS57の実行直前からステップS58の実行直後までの期間に、
図21の処理が実行されればよい。この場合、
図21の処理は、スレッドスケジューラ122の代わりにスレッドが実行してもよい。
【0160】
また、別の方法として、タスクの関数が実行されるたびに
図21の処理が実行されてもよい。例えば、
図20のステップS61における関数の実行が終了するたびに、
図21の処理が実行される。この場合にも、
図21の処理は、スレッドスケジューラ122の代わりにスレッドが実行してもよい。
【0161】
なお、上記の各実施の形態に示した装置(例えば、情報処理装置10、ストレージ制御装置100,200)の処理機能は、コンピュータによって実現することができる。その場合、各装置が有すべき機能の処理内容を記述したプログラムが提供され、そのプログラムをコンピュータで実行することにより、上記処理機能がコンピュータ上で実現される。処理内容を記述したプログラムは、コンピュータで読み取り可能な記録媒体に記録しておくことができる。コンピュータで読み取り可能な記録媒体としては、磁気記憶装置、光ディスク、光磁気記録媒体、半導体メモリなどがある。磁気記憶装置には、ハードディスク装置(HDD)、磁気テープなどがある。光ディスクには、CD(Compact Disc)、DVD(Digital Versatile Disc)、ブルーレイディスク(Blu-ray Disc:BD、登録商標)などがある。光磁気記録媒体には、MO(Magneto-Optical disk)などがある。
【0162】
プログラムを流通させる場合には、例えば、そのプログラムが記録されたDVD、CDなどの可搬型記録媒体が販売される。また、プログラムをサーバコンピュータの記憶装置に格納しておき、ネットワークを介して、サーバコンピュータから他のコンピュータにそのプログラムを転送することもできる。
【0163】
プログラムを実行するコンピュータは、例えば、可搬型記録媒体に記録されたプログラムまたはサーバコンピュータから転送されたプログラムを、自己の記憶装置に格納する。そして、コンピュータは、自己の記憶装置からプログラムを読み取り、プログラムにしたがった処理を実行する。なお、コンピュータは、可搬型記録媒体から直接プログラムを読み取り、そのプログラムにしたがった処理を実行することもできる。また、コンピュータは、ネットワークを介して接続されたサーバコンピュータからプログラムが転送されるごとに、逐次、受け取ったプログラムにしたがった処理を実行することもできる。
【0164】
以上の各実施の形態に関し、さらに以下の付記を開示する。
(付記1) 新たに発生したタスクが登録される第1のキューと、タスクに割り当てられているスレッドのうち、実行可能状態のスレッドが登録される第2のキューとを記憶する記憶部と、
第1のスレッドによる第1のタスクの実行が終了したとき、前記第1のキューの先頭に登録された第2のタスクと、前記第2のキューの先頭に登録された第2のスレッドとの間の実行優先度を判定し、
前記第2のスレッドを先に実行すべきと判定された場合、前記第2のスレッドを前記第2のキューから取り出し、前記第2のスレッドによって前記第2のスレッドが割り当てられたタスクを実行し、
前記第2のタスクを先に実行すべきと判定された場合、前記第2のタスクを前記第1のキューから取り出し、前記第1のスレッドによって前記第2のタスクを実行する、処理部と、
を有する情報処理装置。
【0165】
(付記2) 前記処理部は、さらに、
新規タスクが発生すると、前記新規タスクを前記第1のキューの末尾に登録するとともに、カウント値を取得するたびにカウント値が更新されるカウンタから、カウント値を取得して前記新規タスクに付加し、
前記実行可能状態のスレッドを前記第2のキューの末尾に登録する際に、前記カウンタからカウント値を取得して前記実行可能状態のスレッドに付加し、
前記実行優先度の判定では、前記第2のタスクに付加されたカウント値と前記第2のスレッドに付加されたカウント値との比較結果に基づいて前記実行優先度を判定する、
付記1記載の情報処理装置。
【0166】
(付記3) 前記処理部は、イールドによって前記第1のスレッドによる前記第1のタスクの実行が途中で休止したとき、前記第1のスレッドを前記第2のキューの末尾に登録するとともに、前記カウンタからカウント値を取得して前記第1のスレッドに付加する、
付記2記載の情報処理装置。
【0167】
(付記4) 前記処理部は、
待ち合わせの発生によって前記第1のスレッドによる前記第1のタスクの実行が途中で休止したとき、前記第1のスレッドをサスペンドさせて待ち合わせ状態に遷移させ、
前記第1のスレッドが待ち合わせ状態から復帰したとき、前記第1のスレッドを前記第2のキューの末尾に登録するとともに、前記カウンタからカウント値を取得して前記第1のスレッドに付加する、
付記2記載の情報処理装置。
【0168】
(付記5) 前記処理部は、
前記第1のスレッドによる前記第1のタスクの実行が途中で休止したとき、前記実行優先度を判定し、
前記第2のスレッドを先に実行すべきと判定された場合、前記第2のスレッドを前記第2のキューから取り出し、前記第2のスレッドによって前記第2のスレッドが割り当てられたタスクを実行し、
前記第2のタスクを先に実行すべきと判定された場合、タスクに割り当てられていない第3のスレッドを前記第2のタスクに割り当て、前記第3のスレッドによって前記第2のタスクを実行する、
付記1乃至4のいずれか1つに記載の情報処理装置。
【0169】
(付記6) 前記記憶部は、タスクに割り当てられていない未割り当てスレッドが登録される第3のキューをさらに記憶し、
前記処理部は、前記実行優先度の判定によって前記第2のスレッドを先に実行すべきと判定された場合、前記第1のスレッドを前記未割り当てスレッドとして前記第3のキューに登録する、
付記1乃至4のいずれか1つに記載の情報処理装置。
【0170】
(付記7) コンピュータに、
第1のスレッドによる第1のタスクの実行が終了したとき、新たに発生したタスクが登録される第1のキューの先頭に登録された第2のタスクと、タスクに割り当てられているスレッドのうち実行可能状態のスレッドが登録される第2のキューの先頭に登録された第2のスレッドとの間の実行優先度を判定し、
前記第2のスレッドを先に実行すべきと判定された場合、前記第2のスレッドを前記第2のキューから取り出し、前記第2のスレッドによって前記第2のスレッドが割り当てられたタスクを実行し、
前記第2のタスクを先に実行すべきと判定された場合、前記第2のタスクを前記第1のキューから取り出し、前記第1のスレッドによって前記第2のタスクを実行する、
処理を実行させる実行制御プログラム。
【0171】
(付記8) 前記コンピュータに、
新規タスクが発生すると、前記新規タスクを前記第1のキューの末尾に登録するとともに、カウント値を取得するたびにカウント値が更新されるカウンタから、カウント値を取得して前記新規タスクに付加し、
前記実行可能状態のスレッドを前記第2のキューの末尾に登録する際に、前記カウンタからカウント値を取得して前記実行可能状態のスレッドに付加する、
処理をさらに実行させ、
前記実行優先度の判定では、前記第2のタスクに付加されたカウント値と前記第2のスレッドに付加されたカウント値との比較結果に基づいて前記実行優先度を判定する、
付記7記載の実行制御プログラム。
【0172】
(付記9) 前記コンピュータに、
イールドによって前記第1のスレッドによる前記第1のタスクの実行が途中で休止したとき、前記第1のスレッドを前記第2のキューの末尾に登録するとともに、前記カウンタからカウント値を取得して前記第1のスレッドに付加する、
処理をさらに実行させる付記8記載の実行制御プログラム。
【0173】
(付記10) 前記コンピュータに、
待ち合わせの発生によって前記第1のスレッドによる前記第1のタスクの実行が途中で休止したとき、前記第1のスレッドをサスペンドさせて待ち合わせ状態に遷移させ、
前記第1のスレッドが待ち合わせ状態から復帰したとき、前記第1のスレッドを前記第2のキューの末尾に登録するとともに、前記カウンタからカウント値を取得して前記第1のスレッドに付加する、
処理をさらに実行させる付記8記載の実行制御プログラム。
【0174】
(付記11) 前記コンピュータに、
前記第1のスレッドによる前記第1のタスクの実行が途中で休止したとき、前記実行優先度を判定し、
前記第2のスレッドを先に実行すべきと判定された場合、前記第2のスレッドを前記第2のキューから取り出し、前記第2のスレッドによって前記第2のスレッドが割り当てられたタスクを実行し、
前記第2のタスクを先に実行すべきと判定された場合、タスクに割り当てられていない第3のスレッドを前記第2のタスクに割り当て、前記第3のスレッドによって前記第2のタスクを実行する、
処理をさらに実行させる付記7乃至10のいずれか1つに記載の実行制御プログラム。
【0175】
(付記12) 前記コンピュータに、
前記実行優先度の判定によって前記第2のスレッドを先に実行すべきと判定された場合、タスクに割り当てられていない未割り当てスレッドが登録される第3のキューに対して、前記第1のスレッドを前記未割り当てスレッドとして登録する、
処理をさらに実行させる付記7乃至10のいずれか1つに記載の実行制御プログラム。
【符号の説明】
【0176】
10 情報処理装置
11 記憶部
12 処理部
21 第1のキュー
22 第2のキュー
A1~A3,A11,A12 タスク
B1~B3 スレッド