(19)【発行国】日本国特許庁(JP)
(12)【公報種別】特許公報(B2)
(11)【特許番号】
(24)【登録日】2024-06-28
(45)【発行日】2024-07-08
(54)【発明の名称】メッセージ送受信方法およびオペレーティングシステム
(51)【国際特許分類】
G06F 9/54 20060101AFI20240701BHJP
【FI】
G06F9/54 B
(21)【出願番号】P 2023148135
(22)【出願日】2023-09-13
(62)【分割の表示】P 2021110048の分割
【原出願日】2021-07-01
【審査請求日】2023-09-13
(73)【特許権者】
【識別番号】501100881
【氏名又は名称】イーソル株式会社
(74)【代理人】
【識別番号】100157912
【氏名又は名称】中島 健
(74)【代理人】
【識別番号】100074918
【氏名又は名称】瀬川 幹夫
(72)【発明者】
【氏名】大野 智史
(72)【発明者】
【氏名】権藤 正樹
【審査官】田中 幸雄
(56)【参考文献】
【文献】特開2021-60707(JP,A)
【文献】特開2016-45510(JP,A)
【文献】特開2000-347881(JP,A)
(58)【調査した分野】(Int.Cl.,DB名)
G06F 9/54
(57)【特許請求の範囲】
【請求項1】
複数のプロセッサコアと、前記複数のプロセッサコアがアクセス可能なメモリと、を備えたコンピュータが、オペレーティングシステムに実行させるメッセージ送受信方法であって、
前記オペレーティングシステムは、前記複数のプロセッサコアと1対1で対応して設けられた複数のマイクロカーネルを並行して実行可能であり、
前記複数のマイクロカーネルのそれぞれが、対応するプロセッサコアに割り当てられたスレッドの制御を行うように構成されており、
前記複数のマイクロカーネルのうちの少なくとも1つは、どのプロセッサコアにどのスレッドが割り当てられているかを管理するスレッド管理機能を備え、
前記メモリには、スレッドの生成時に、当該スレッドに固有のスレッドメッセージバッファが確保されており、
前記スレッドメッセージバッファにメッセージを書き込むことで、異なる前記マイクロカーネルに所属するスレッド間でメッセージングを実行可能とした、
メッセージ送受信方法。
【請求項2】
前記スレッドメッセージバッファのサイズは、スレッド生成時のパラメータにより指定可能である、
請求項1に記載のメッセージ送受信方法。
【請求項3】
前記オペレーティングシステムは、スレッド生成後に前記スレッドメッセージバッファのサイズを変更可能なAPIを備えている、
請求項1または2に記載のメッセージ送受信方法。
【請求項4】
複数のプロセッサコアと、前記複数のプロセッサコアがアクセス可能なメモリと、を備えたコンピュータ上で実行されるオペレーティングシステムであって、
前記オペレーティングシステムは、前記複数のプロセッサコアと1対1で対応して設けられた複数のマイクロカーネルを並行して実行可能であり、
前記複数のマイクロカーネルのそれぞれが、対応するプロセッサコアに割り当てられたスレッドの制御を行うように構成されており、
前記複数のマイクロカーネルのうちの少なくとも1つは、どのプロセッサコアにどのスレッドが割り当てられているかを管理するスレッド管理機能を備え、
前記メモリには、スレッドの生成時に、当該スレッドに固有のスレッドメッセージバッファが確保されており、
前記スレッドメッセージバッファにメッセージを書き込むことで、異なる前記マイクロカーネルに所属するスレッド間でメッセージングを実行可能とした、
オペレーティングシステム。
【請求項5】
前記スレッドメッセージバッファのサイズは、スレッド生成時のパラメータにより指定可能である、
請求項4に記載のオペレーティングシステム。
【請求項6】
スレッド生成後に前記スレッドメッセージバッファのサイズを変更可能なAPIを備えている、
請求項4または5に記載のオペレーティングシステム。
【発明の詳細な説明】
【技術分野】
【0001】
この発明は、複数のプロセッサコアを搭載したコンピュータ上で実行されるメッセージ送受信方法およびオペレーティングシステムに関する。
【背景技術】
【0002】
本出願人は、特許文献1において、複数のプロセッサコアを搭載したコンピュータ上で実行される同期制御システムおよび同期制御方法に関する発明を提案した。この特許文献1に記載された発明では、プロセッサコアごとにオペレーティングシステムのマイクロカーネルが実行されるようになっている。そして、このマイクロカーネルが、ロックオブジェクトを使用して、異なるプロセッサコアで実行されているスレッド間の排他制御や同期制御を行うようになっている。
【0003】
ところで、このようなロックオブジェクトを使用した制御は、排他制御や同期制御には便利であるが、スレッド間の同期だけでなく、何からの情報(メッセージ)を相手側に通知したい場合がある。
【0004】
メッセージの送受信の方法としては、メッセージバッファを使用したものが知られている(非特許文献1参照)。このようなメッセージバッファを使用した方法では、最初にメッセージバッファが作成される。その後、送信側がメッセージバッファ領域にメッセージを格納する。また、受信側はメッセージバッファ領域からメッセージを取り出す。なお、受信側がメッセージバッファ領域からメッセージを取り出そうとしたときに、まだメッセージが格納されていない場合は、受信側が受信待ち状態になる。また、送信側がメッセージを送信しようとしたときに、メッセージバッファ領域に空きがなくあふれてしまう場合には、送信側が送信待ち状態になる。
【先行技術文献】
【特許文献】
【0005】
【非特許文献】
【0006】
【文献】トロンフォーラム、「RTOS入門編」第4回タスク間同期・通信機能2、[online]、[令和3年6月23日検索]、インターネット〈URL:https://www.tron.org/ja/page-722/rtos04/〉
【発明の概要】
【発明が解決しようとする課題】
【0007】
非特許文献1に記載されているようなメッセージバッファ機能を使用するには、送受信の前にメッセージバッファが確保されており、また、メッセージバッファの場所(IDやアドレス)を、送信側および受信側のいずれもが共有して認識している必要がある。
【0008】
このため、特許文献1に記載されているような、プロセッサコアごとにマイクロカーネルを実行している環境において、マイクロカーネル間で同様の通信を行う場合にも、あらかじめメッセージバッファが確保されており、異なるプロセッサコアで実行されているマイクロカーネルのそれぞれが、メッセージバッファを特定するための情報を共有して認識している必要がある。
【0009】
この問題を解決する最も単純な方法は、マイクロカーネルごとにあらかじめメッセージバッファを確保しておく方法である。すなわち、異なるプロセッサコア間で通信を行う場合に、送信元のマイクロカーネルが、受信先のマイクロカーネルのメッセージバッファにメッセージを書き込むようにすれば、プロセッサコアを跨いだ通信が可能となる。
【0010】
しかしながら、上記したようにマイクロカーネルごとにあらかじめメッセージバッファを確保しておく方法では、システムの安全性を担保することが困難であった。例えば、メッセージの受信量が一時的に増加してメッセージの受信処理が間に合わなくなると、メッセージバッファがあふれてしまい、マイクロカーネルの全スレッドが停止しまうおそれがあった。
【0011】
なお、メッセージバッファのサイズを限りなく増加させれば上記したような問題は解消できる。しかしながら、メッセージバッファに使用できるメモリには上限があるため、この解決策は現実的ではない。
【0012】
別の解決策として、マイクロカーネルごとに必要となるメッセージバッファのサイズを正確に見積もることが考えられる。正確な見積もりが可能であれば、その分だけあらかじめメッセージバッファを確保することで、メッセージバッファの不足を回避できる。しかしながら、どのプロセッサコアでどのスレッドが実行されるかの予測が困難なシステムでは、必要となるメッセージバッファのサイズをあらかじめ見積もることは難しい。例えば、プロセッサコアを有効活用するためにスレッドのマイグレーションを行うシステム(詳しくは後述するが、優先度の高いスレッドが集中して実行されているプロセッサコアがある場合、一部のスレッドを他のプロセッサコアへと移動させることで、プロセッサコア間の負荷を自動的に調節するようなシステム)の場合、どのプロセッサコアでどのスレッドが実行されるかはわからないため、プロセッサコアごとのメッセージ量を見積もることはできない。このように、スレッドがマイグレーションするようなシステムにおいては、マイクロカーネルごとにあらかじめ適切なサイズのメッセージバッファを確保し、メッセージバッファの不足を回避することは困難である。
【0013】
また、スレッドには、高い安全性が求められるものと、そこまで高い安全性が求められないものとが混在している。このため、メッセージバッファが不足するとしても、高い安全性が求められるスレッドが停止しないように制御される必要がある。
【0014】
上記した点を踏まえ、本発明は、メッセージの受信量が一時的に増加した場合でも、高い安全性が求められるスレッドへの影響を最小限とすることできるメッセージ送受信方法を実現することを課題とする。
【課題を解決するための手段】
【0015】
上記した課題を解決するため、本発明は、複数のプロセッサコアと、前記複数のプロセッサコアがアクセス可能なメモリと、を備えたコンピュータが、オペレーティングシステムに実行させるメッセージ送受信方法において、前記オペレーティングシステムは、前記複数のプロセッサコアと1対1で対応して設けられた複数のマイクロカーネルを並行して実行可能であり、前記複数のマイクロカーネルのそれぞれが、対応するプロセッサコアに割り当てられたスレッドの制御を行うように構成されており、前記複数のマイクロカーネルのうちの少なくとも1つは、どのプロセッサコアにどのスレッドが割り当てられているかを管理するスレッド管理機能を備え、前記メモリには、スレッドの生成時に、当該スレッドに固有のスレッドメッセージバッファが確保されており、前記スレッドメッセージバッファにメッセージを書き込むことで、異なる前記マイクロカーネルに所属するスレッド間でメッセージングを実行可能とした。
【発明の効果】
【0016】
本発明は上記の通りであり、スレッドの生成時に、当該スレッドに固有のスレッドメッセージバッファが確保されている。このため、スレッドごとにメッセージが管理されており、高い安全性が求められないスレッドに対するメッセージが一時的に増加してバッファが枯渇した場合でも、高い安全性が求められるスレッドが影響を受けることはない。このため、メッセージの受信量が一時的に増加した場合でも、重要なメッセージを確実に送受信することができる。
【図面の簡単な説明】
【0017】
【
図1】コンピュータシステムの概略を示すブロック図である。
【
図2】各プロセッサコアに配置されたマイクロカーネルの概略を示す説明図である。
【
図3】メッセージ送受信の概略を示す説明図である。
【
図5】割り込み発生時のメッセージ受信処理のフロー図である。
【
図6】API呼び出し時のメッセージ受信処理のフロー図である。
【発明を実施するための形態】
【0018】
本発明の実施形態について、図を参照しながら説明する。
(ハードウェア構成)
本実施形態に係るコンピュータシステムは、
図1に示すようなコンピュータを備えている。このコンピュータは、CPU10、メモリ20(主記憶装置)、図示しない補助記憶装置、を備えている。
【0019】
本実施形態に係るCPU10は、1つのプロセッサパッケージ内に複数のプロセッサコア11を搭載したマルチコアプロセッサである。
図1に示すCPU10は、64個のプロセッサコア11を搭載している。なお、この
図1は例示に過ぎず、プロセッサコア11の数はいくつであってもよい。また、CPU10は、必ずしも単一のプロセッサパッケージからなるものでなくてもよく、複数のプロセッサパッケージからなるように構成されていてもよい。
【0020】
メモリ20は、CPU10が直接アクセスすることができる記憶装置であり、実行中のスレッドのコンテキストやその他のデータが記憶されている。例えばこのメモリ20には、オペレーティングシステムの一部であるマイクロカーネル30の実体としてのコンテキストデータや、オペレーティングシステムによって実行を制御されるスレッドの実体としてのコンテキストデータなどが配置されている。なお、これらのオペレーティングシステムやスレッドのプログラムは補助記憶装置に記憶されており、必要に応じてメモリ20に読み込まれることで、CPU10によって使用可能となる。
【0021】
(オペレーティングシステムの概要)
オペレーティングシステムは、CPU10が実行するプログラムを制御するソフトウェアである。本実施形態に係るオペレーティングシステムは、複数のプロセッサコア11を搭載したCPU10(マルチコアプロセッサ)をサポートしている。このオペレーティングシステムでは、プログラムの実行単位をスレッドと呼んでいる。
【0022】
本実施形態に係るオペレーティングシステムは、マイクロカーネル型のオペレーティングシステムであり、オペレーティングシステムの基本的な機能の多くをマイクロカーネルとして提供している。オペレーティングシステムの基本的な機能であるマイクロカーネル30は、上記した複数のプロセッサコア11と1対1で対応して設けられ、各プロセッサコア11において並行して実行される。具体的には、システム起動時にプロセッサコア11ごとにマイクロカーネル30のインスタンスが生成され、マイクロカーネル30の機能を外部に提供するサーバースレッドが、対応するプロセッサコア11(「自コア」と言う)上で常に実行される。
【0023】
各プロセッサコア11に配置されたマイクロカーネル30は、それぞれ、
図2に示すような機能を備えている。すなわち、ローカルスケジューラ31(スケジューリング機能)、メッセージマネージャ34(メッセージ送受信機能)、割り込みマネージャ35(割り込み管理機能)、インタフェースライブラリ39などの機能を備えている。
【0024】
ローカルスケジューラ31(スケジューリング機能)は、プロセッサコア11におけるスレッドの切り替えを行う機能である。ローカルスケジューラ31は、自コアに割り振られたスレッドの中から実行するものを選択し、選択したスレッドにプロセッサコア11の実行権を与えるスケジューリングを行う。このローカルスケジューラ31によって、複数のマイクロカーネル30のそれぞれが、対応するプロセッサコア11に割り当てられたスレッドの制御を行うように構成されている。
【0025】
メッセージマネージャ34(メッセージ送受信機能)は、後述するメッセージ送受信モジュール40を使用して、スレッド間やマイクロカーネル30間でのメッセージ送受信を行うための機能である。メッセージマネージャ34は、指定されたパラメータに従い、メッセージ送受信モジュール40を介して、スレッドやマイクロカーネル30へメッセージを送信する機能と、スレッドやマイクロカーネル30から通知されるメッセージを受信する機能を持つ。また、このメッセージマネージャ34は、送信先や受信先の解決を行う機能を有している。具体的には、メッセージ送信の際に、インタフェース層(インタフェースライブラリ39の呼び出し)で指定される受信先スレッドのIDを、受信先のマイクロカーネル30(プロセッサコア11)に変換する処理を実行する。また、このメッセージマネージャ34は、メッセージ受信の際に、受信したスレッド宛てのメッセージをスレッドに届ける処理を実行する。これらの処理の詳細については、後ほど説明する。
割り込みマネージャ35(割り込み管理機能)は、プロセッサコア11で発生した割り込みをハンドリングする機能である。
【0026】
インタフェースライブラリ39は、オペレーティングシステムのサービスをシステムコールとして呼び出すためのものである。このインタフェースライブラリ39は、例えばメッセージ送信用のAPIやメッセージ受信用のAPIを提供しており(後述)、これらのAPIをスレッドから呼び出すことで、スレッドがメッセージの送受信機能を使用できるようにしている。
【0027】
なお、各マイクロカーネル30は、自コアに割り当てられたスレッドに関する情報や、自コアに割り当てられたスレッド宛のメッセージを管理するための情報を保持している。具体的には、
図2に示すように、メモリ20にマイクロカーネル30ごとにマイクロカーネル制御情報26が記憶されている。このマイクロカーネル制御情報26には、自コアに割り当てられたスレッドに固有のスレッドメッセージバッファ25(後述)のアドレスや、当該スレッドメッセージバッファ25内の未読メッセージを指し示すポインタなどの情報が含まれている。各マイクロカーネル30は、自分のマイクロカーネル制御情報26には自由にアクセスできるが、他のマイクロカーネル30に係るマイクロカーネル制御情報26にはアクセスすることはできない。
【0028】
各マイクロカーネル30は、互いに独立して動作するが、メッセージ送受信モジュール40を介してメッセージの送受信を行うことができる。言い換えれば、各マイクロカーネル30は、メッセージ送受信モジュール40を介してのみ、互いの状態を参照し、互いの状態に影響を与えることができる。このメッセージ送受信モジュール40は、マイクロカーネル30よりも更にハードウェアに近い層を構成するモジュールであり、すべてのマイクロカーネル制御情報26を直接参照することが可能となっている。
【0029】
なお、各マイクロカーネル30間でメッセージの送受信を行う際には、受信順を管理するために排他制御が必要となる。この排他制御はメッセージ送受信モジュール40によって実行される。例えば、メッセージ送受信モジュール40は、マイクロカーネル制御情報26に対する排他的なアクセスを実現する。これにより、メッセージ送受信モジュール40は、メッセージの受信順を管理している。一方、マイクロカーネル30は、メッセージ送受信モジュール40から順番に渡されるメッセージを処理していくだけであり、メッセージの受信順は管理していない。このように、メッセージの送受信の順序に係る排他制御は、メッセージ送受信モジュール40によって一元的に管理されている。
【0030】
また、マイクロカーネル30が、後述するスレッドメッセージバッファ25にアクセスするとき(例えば、スレッドメッセージバッファ25の空きを参照したり、スレッドメッセージバッファ25のキューを操作したりするとき)には、スレッドメッセージバッファ25を参照するための専用のモジュール(メッセージ送受信モジュール40であってもよいし、メッセージ送受信モジュール40とは別のモジュールであってもよい)を使用する。このモジュールがスレッドメッセージバッファ25へのアクセスを排他制御する。
【0031】
(クラスタおよびスケジューリングについて)
本実施形態に係るオペレーティングシステムは、プロセッサコア11の管理効率を高めるため、クラスタと呼ぶグルーピングの概念を使用している。クラスタは、複数のプロセッサコア11をグループ化したものであり、各プロセッサコア11は少なくともいずれかのクラスタに所属している。このクラスタをさらに上位のクラスタにグループ化して、クラスタを階層構造とすることも可能である。
【0032】
図1に示す例では、4つのクラスタ(スケジューリングクラスタ15)を設け、それぞれのクラスタに16個のプロセッサコア11が含まれるようにグループ化している。また、この4つのスケジューリングクラスタ15が1つの上位クラスタ(ハードウェアクラスタ16)に所属している。
【0033】
各クラスタには、スレッドをいずれかのプロセッサコア11に割り振るためのスレッドスケジューラ32、33が配置されている。このスレッドスケジューラ32、33は、マイクロカーネル30の一部として実行される。
【0034】
スレッドスケジューラ32は、サーバースレッドとして構築され、自身が管轄するスレッドとプロセッサコア11の範囲で、所定のポリシーに従って、スレッドをどのプロセッサコア11へ割り振るかを決定する。スレッドをプロセッサコア11へ振り分けることをロードバランシングと呼び、どのようにスレッドをプロセッサコア11へ振り分けるかを定義するポリシーをロードバランシングポリシーと呼ぶ。本実施形態においては、優先度の高いスレッドが複数のプロセッサコア11にできるだけ均一に割り当てられるようにロードバランシングポリシーが設定されている。なお、ロードバランシングの具体的な処理としては、例えば特開2015-164052号に記載された処理を使用することができる。
【0035】
スレッドスケジューラ32は負荷を分散する目的で、オペレーティングシステム内に複数インスタンスが存在することがある。スレッドスケジューラ32が複数になると、スレッドスケジューラ32間でロードバランスを取る必要性から、さらに上位のスレッドスケジューラ33が置かれる。
【0036】
本実施形態においては、各スケジューリングクラスタ15に1つずつスレッドスケジューラ32が配置され、このスレッドスケジューラ32がスケジューリングクラスタ15内のどのプロセッサコア11にスレッドを割り当てるかを決定するようになっている。また、ハードウェアクラスタ16に1つの上位のスレッドスケジューラ33が配置され、この上位のスレッドスケジューラ33がハードウェアクラスタ16内のどのスケジューリングクラスタ15にスレッドを割り当てるかを決定するようになっている。
【0037】
なお、スレッドスケジューラ32、33は、プロセッサコア11やクラスタを超えてスレッドを管理しなければならないため、どのプロセッサコア11にどのスレッドが割り当てられているかを管理するスレッド管理機能を備えている。具体的には、スケジューリングクラスタ15を管理するスレッドスケジューラ32は、スケジューリングクラスタ15内の全スレッドのコア配置を管理しており、最上位のスレッドスケジューラ33は、オペレーティングシステム内の全スレッドのコア配置を管理している。このため、あるスレッドがどのプロセッサコア11に配置されているかを知りたい場合は、スレッドスケジューラ32に問い合わせればよい。もし、問い合わせを受けたスレッドスケジューラ32が管理するクラスタにスレッドがない場合でも、当該スレッドスケジューラ32が上位のスレッドスケジューラ33に問い合わせるので、スレッドが配置されているプロセッサコア11を解決することができる。
【0038】
このスレッドスケジューラ32、33は、プロセッサコア11間の負荷の偏りに応じて、スレッドを実行するプロセッサコア11の再割り当て(マイグレーション)を行う。例えば、優先度の高いスレッドが集中して実行されているプロセッサコア11がある場合、一部のスレッドを他のプロセッサコア11へと移動させることで、自動的に負荷の調整を行う。優先度ベースのロードバランシングポリシーが適用されている場合には、優先度の高いスレッドが複数のプロセッサコア11にできるだけ均一に割り当てられるように再配置を行う。
【0039】
ただし、すべてのスレッドが上記したようなマイグレーションを起こすわけではなく、マイグレーションを起こさないスレッドも存在する。具体的には、スレッドの生成時にパラメータで動作コアを指定すると、このスレッドはコアアフィニティスレッドと呼ばれ、その後マイグレーションを起こさない。一方、生成時のパラメータで動作コアを指定しなかった場合は、このスレッドはマイグレーション可能スレッドと呼ばれ、その後マイグレーションする可能性がある。
【0040】
なお、すでに説明したように、スレッドスケジューラ32、33によってスレッドが割り振られた先のマイクロカーネル30には、ローカルスケジューラ31が存在している。ローカルスケジューラ31は、自コアに割り振られたスレッドの中から実行するスレッドを選択し、RUNNING状態とする。あるスレッドを選定し、これをRUNNING状態とすることをスケジューリングと呼び、これを決定するポリシーをスケジューリングポリシーと呼ぶ。本実施形態においては、自コアに割り振られたスレッドの中から、最も優先度の高いREADYスレッドを選び、RUNNING状態とする、優先度ベースのスケジューリングポリシーが適用されている。
【0041】
上記したように、本実施形態に係るオペレーティングシステムは、スレッドの実行権を制御するスケジューラとして、スレッドスケジューラ32,33とローカルスケジューラ31との2種類を備え、この2つが相互に連動しながら動作する階層型スケジューラの構成となっている(
図1参照)。具体的には、すべてのマイクロカーネル30は、それぞれローカルスケジューラ31が配置されている。そして、スケジューリングクラスタ15内のいずれか1つのマイクロカーネル30には、スレッドスケジューラ32が配置されている。また、スケジューリングクラスタ15よりも上位のクラスタ(例えばハードウェアクラスタ16)がある場合、当該クラスタ内のいずれか1つのマイクロカーネル30には、上位のスレッドスケジューラ33が配置されている。
【0042】
なお、スレッドスケジューラ32,33は、サーバースレッドとして実行される。このため、スレッドスケジューラ32,33がメッセージの送受信を行う場合も、後述するメッセージ機能が使用される。例えば、あるスレッドがどのプロセッサコア11に配置されているかについて、スレッドスケジューラ32に問い合わせを行う場合にも、後述するメッセージ機能が使用される。
【0043】
(メッセージ機能の概要)
メッセージは、オペレーティングシステムによって提供されるスレッド間の通信手段である。メッセージは、最もハードウェアに近い下位層では、マイクロカーネル30からマイクロカーネル30へ送信されるが、上位のインタフェース層では、スレッドからスレッドに対して送信することが可能である。すなわち、ユーザプログラムがインタフェースライブラリ39を使用してメッセージ送信を行う場合には、送信先にスレッドを指定して実行することが可能である。この場合、メッセージマネージャ34によって、そのスレッドが割り当てられているマイクロカーネル30が特定され、メッセージが伝達される。
なお、メッセージには「送信」と「受信」があり、また、送信と受信のそれぞれに「同期」と「非同期」がある。
【0044】
同期送信は、受信先スレッドがメッセージを受信するまで送信完了を待ち合わせる処理である。待ち合わせは、送信元スレッドをWAIT状態とすることで実施される。一方、非同期送信は、受信先スレッドのメッセージ受信を待たずに送信を完了する処理である。
【0045】
また、同期受信は、メッセージを受信するまで受信完了を待ち合わせる処理である。待ち合わせは、受信先スレッドをWAIT状態とすることで実施される。一方、非同期受信は、メッセージが送信済みの場合のみ受信を実施し、メッセージが送信済みでない場合はエラーとなる処理である。
【0046】
本オペレーティングシステムは、
図3に示すように、メッセージ送信用のAPI(message_send)と、メッセージ受信用のAPI(message_recieve)を備えている。これらのAPIをスレッドから呼び出すことで、スレッドがメッセージを送信したり、スレッドがメッセージを受信したりすることができる。
【0047】
メッセージ送信用のAPI(message_send)は、パラメータとして「送信先スレッドのID」「送信するデータの先頭アドレス」「送信するデータのサイズ」「同期/非同期のフラグ」を指定して実行する。
【0048】
なお、メッセージの送信には受信先のマイクロカーネル30またはプロセッサコア11を特定する必要があるが、これらはマイクロカーネル30が内部的に解決するため、APIのパラメータとして指定する必要はない。具体的には、メッセージマネージャ34は、スレッドスケジューラ32に問い合わせることで、受信先のマイクロカーネル30やプロセッサコア11を特定することができるようになっている。
【0049】
また、メッセージマネージャ34は、受信先スレッドが所属するプロセッサコア11を記憶するキャッシュ(Message Resolver Cache)を備えており、以前にメッセージを送信した際に解決したメッセージ受信先の内容を保持している。
【0050】
このため、メッセージ送信用のAPIが呼び出されると、メッセージマネージャ34は、まず受信先のスレッドが自コアに割り当てられているかをチェックする。自コアに割り当てられていれば、マイクロカーネル30を探す必要はない。一方、自コアに割り当てられていない場合には、キャッシュを検索する。キャッシュにヒットした場合は、キャッシュの受信先を使用してメッセージを送信する。キャッシュミスした場合には、スレッドスケジューラ32に問い合わせることで受信先を特定し、メッセージを送信するとともに、キャッシュの内容を更新する。
【0051】
また、メッセージ受信用のAPI(message_recieve)は、パラメータとして「データ格納領域の先頭アドレス」「データ格納領域のサイズ」「同期/非同期のフラグ」を指定して実行する。
【0052】
受信先のスレッドからmessage_recieveが呼び出されると、マイクロカーネル30は、すでに受信済みメッセージを検索し、受信先のスレッドに宛てたものが存在するかをチェックする。メッセージが存在する場合は、message_recieveのパラメータとして指定されたデータ格納領域に、メッセージをコピーして返却する。メッセージが存在しない場合、同期受信であればメッセージを受信するまで受信先のスレッドを待機させる。メッセージが存在せず、非同期受信の場合は、エラーを返却する。
【0053】
(メッセージのバッファ管理)
本実施形態に係るオペレーティングシステムは異なるマイクロカーネル30に所属するスレッド間でメッセージングを行う際、メッセージバッファを介して行う。メッセージバッファは、ハードウェアクラスタ16内の全てのプロセッサコア11からアクセス可能となっている。メッセージバッファは各スレッドに固有のものがスレッドの生成時に確保される。このようなスレッドに固有のメッセージバッファをスレッドメッセージバッファ25と呼ぶ。スレッドメッセージバッファ25は、スレッドごとに作成されるため、スレッドと同じ数だけ確保されることになる。
【0054】
スレッドメッセージバッファ25のサイズは、スレッド生成時のパラメータによって指定することができる。また、オペレーティングシステムのAPIを使用することで、スレッド生成後にスレッドメッセージバッファ25のサイズを変更することも可能である。スレッドメッセージバッファ25のサイズは、受信可能な最大メッセージサイズと格納可能なメッセージ数を指定して、ユーザが任意に設定可能である。スレッドメッセージバッファ25はキュー構造となっており、上記したメッセージ数だけメッセージを保存することができる。
【0055】
マイクロカーネル30を介して送信したスレッド宛てのメッセージは、スレッドメッセージバッファ25へ格納される。このスレッドメッセージバッファ25へ格納されたメッセージは、受信側のマイクロカーネル30の処理によって、message_recieveのパラメータとして指定されたデータ格納領域にコピーされる。コピー後、スレッドメッセージバッファ25に格納したメッセージは破棄される。
図3を参照しつつ、上記したスレッドメッセージバッファ25を介したメッセージ送受信の流れを説明する。
【0056】
送信元スレッドから受信先スレッドAにメッセージを送信する場合、送信元スレッドがmessage_sendを呼び出す。このとき、受信先スレッドのIDには、受信先スレッドAのIDを指定する。
【0057】
メッセージの送信要求(message_send)を受け取った送信元のマイクロカーネル30は、受信先スレッドAのIDを基に受信先のマイクロカーネル30を特定する。具体的には、上記したように、キャッシュを検索するか、またはスレッドスケジューラ32に問い合わせることで、受信先のマイクロカーネル30を特定する。
【0058】
受信先のマイクロカーネル30を特定したら、メッセージ送受信モジュール40を使用して、メッセージをスレッドメッセージバッファ25に書き込む。すなわち、メッセージ送受信モジュール40は、受信先のマイクロカーネル30のマイクロカーネル制御情報26と受信先スレッドAのIDとを基に、受信先スレッドAに割り当てられたスレッドメッセージバッファ25を特定する。そして、スレッドメッセージバッファ25を特定出来たら、このバッファにメッセージを書き込む。なお、メッセージを書き込む際には、メッセージの書き込まれていない空きのキューを獲得して、そこに書き込む。空きのキューがない状態は、スレッドメッセージバッファ25に空きがないため、メッセージ送信に失敗することになる(message_sendはエラーを返す)。書き込まれたメッセージは、マイクロカーネル制御情報26において書き込み順に受信キューで管理されるため、受信先のマイクロカーネル30は、書き込み順にメッセージを読み出せるようになっている。具体的には、上記した受信キューには、スレッドメッセージバッファ25の先頭アドレスが、書き込み順につながれて格納されている。
【0059】
一方、受信先スレッドAがメッセージを受信する場合、まず、メッセージを受け取るためのデータ格納領域を確保する。そして、このデータ格納領域の先頭アドレスとサイズをパラメータに指定して、message_receiveを呼び出す。
【0060】
メッセージの受信要求(message_receive)を受け取った受信先のマイクロカーネル30は、受信先スレッドA宛てのメッセージをすでに受信しているかをチェックする。具体的には、上記した受信キューを参照し、未読のメッセージがあるかを確認する。未読のメッセージがある場合には、受信キューに格納されたアドレスを基にスレッドメッセージバッファ25に書き込まれたメッセージを読み込む。
【0061】
受信先スレッドA宛てのメッセージが存在する場合は、message_receiveのパラメータで指定されたデータ格納領域にメッセージをコピーし、当該メッセージをスレッドメッセージバッファ25から削除する。
【0062】
受信先スレッドA宛てのメッセージが存在せず、かつ、同期受信が指定されている場合は、受信先スレッドA宛てのメッセージが届くまで待機する。受信先スレッドA宛てのメッセージが届いたら、message_receiveのパラメータで指定されたデータ格納領域にメッセージをコピーし、当該メッセージをスレッドメッセージバッファ25から削除する。
【0063】
なお、上記した説明では、受信先スレッドAにメッセージを送信しているが、受信先スレッドBにメッセージを送信する場合でも、上記と同様の処理によりメッセージを送信することができる。このときには、受信先スレッドBに割り当てられたスレッドメッセージバッファ25を使用して、メッセージのやり取りが行われる。このように、受信先のスレッドごとに異なるスレッドメッセージバッファ25を使用してメッセージングが行われる。 また、スレッドメッセージバッファ25は特定のプロセッサコア11に依存していないため、スレッドがマイグレーションした場合でも、スレッドメッセージバッファ25は移動せずにそのまま使用することができる。ただし、当該スレッドを管理するマイクロカーネル30が変わることになるため、マイクロカーネル制御情報26の書き換えは必要となる。具体的には、スレッドがいなくなるマイクロカーネル30に係るマイクロカーネル制御情報26からは、当該スレッドに係る情報、例えば当該スレッドに割り当てられたスレッドメッセージバッファ25のアドレス情報は削除される。そして、スレッドが追加されるマイクロカーネル30に係るマイクロカーネル制御情報26には、当該スレッドに係る情報、例えば当該スレッドに割り当てられたスレッドメッセージバッファ25のアドレス情報が追加される。
【0064】
(メッセージ送信処理)
メッセージ送信処理の具体的な流れについて、
図4のフローを参照しながら説明する。このメッセージ送信処理は、メッセージ送信用API(message_send)が呼び出されたときに、送信元カーネル(送信元スレッドが属するマイクロカーネル30)によって実行される処理である。
図4のフローは、message_sendの内部で実行される処理を説明している。ただし、このフローでは、エラー処理などの一部の処理については説明を省略している。例えば、不正なパラメータが指定された場合には、message_sendの戻り値としてエラー値を返却するが、このような処理については説明を省略している。
【0065】
まず、
図4に示すステップS105において、任意の送信元スレッドがメッセージ送信用API(message_send)を呼び出す。このAPI呼び出しを送信元カーネルが受け取ることによって、メッセージ送信処理が開始される。そして、ステップS110に進む。
【0066】
ステップS110では、受信先スレッドが同一プロセッサコア11に割り当てられているかがチェックされる。具体的には、message_sendで指定された受信先スレッドのIDを基にマイクロカーネル制御情報26を参照し、受信先スレッドを送信元カーネルが制御しているかがチェックされる。受信先スレッドが同一プロセッサコア11に割り当てられている場合は、ステップS160に進む。また、受信先スレッドが同一プロセッサコア11に割り当てられていない場合は、ステップS115に進む。
【0067】
ステップS160に進んだ場合、送信元スレッドと受信先スレッドとが同じプロセッサコア11に割り当てられており、同じマイクロカーネル30によって制御されているため、スレッドメッセージバッファ25を介することなく受信先スレッドにメッセージを渡すことができる。具体的には、受信先スレッドがすでに受信待ち状態であれば、message_receiveで指定されたデータ格納領域にメッセージをコピーする。また、受信先スレッドが受信待ち状態でなければ、message_receiveが呼び出されたときに、message_receiveで指定されたデータ格納領域にメッセージをコピーする。このとき、message_sendが非同期で実行されていれば、message_receiveが呼び出されるのを待たずにmessage_sendを終了し、送信元スレッドへと処理を返却する。以上でメッセージ送信処理が終了する。
【0068】
一方、ステップS115に進んだ場合、以前にメッセージを送信した際に解決したメッセージ受信先のキャッシュ(Message Resolver Cache)を検索し、受信先スレッドの所属の解決を試みる。キャッシュに受信先スレッドが見つかった場合は、受信先スレッドが属するマイクロカーネル30(受信先カーネル)を特定し、ステップS135へ進む。一方、キャッシュに受信先スレッドが見つからなかった場合には、ステップS120に進む。
【0069】
ステップS120では、スレッドスケジューラ32に問い合わせを行う前処理として、メッセージを送信元スレッドのスレッドメッセージバッファ25にコピーして退避させる。この処理は、メッセージを格納している領域が、スレッドスケジューラ32に問い合わせを行っている間に書き換えられることを防止するためである。そして、ステップS125に進む。
【0070】
ステップS125では、受信先スレッドのIDを基に、スレッドスケジューラ32(スレッド管理機能)に問い合わせを行い、受信先カーネルを特定するための情報(例えば、受信先カーネルのIDまたはプロセッサコア11のID)を取得する。この問い合わせ自体も、スレッドメッセージバッファ25を使用したメッセージ送信(後述するステップS145~ステップS150を参照)により実行される(ただし、送信元カーネルにスレッドスケジューラ32が配置されている場合は、スレッドメッセージバッファ25を使用したメッセージ送受信は不要である)。問い合わせを受けたスレッドスケジューラ32は、必要に応じて上位のスレッドスケジューラ33にさらに問い合わせを行い、受信先カーネルを特定する。受信先カーネルを特定したら、スレッドスケジューラ32は、スレッドメッセージバッファ25を使用したメッセージ送信によって、受信先カーネルを特定するための情報を送信元カーネルに渡す。そして、ステップS130に進む。
【0071】
ステップS130では、ステップS125で解決した受信先スレッドと受信先カーネルの情報を、キャッシュ(Message Resolver Cache)に登録する。例えば、受信先スレッドのIDと受信先カーネルのID(またはプロセッサコア11のID)とを紐付けたデータを、メモリ20に記憶させる。そして、ステップS135に進む。
【0072】
ステップS135では、受信先カーネルに係る情報(IDなど)を指定してメッセージ送受信モジュール40を呼び出し、メッセージ送信を行う。メッセージ送受信モジュール40は、受信先カーネルに係る情報(IDなど)が判明しているので、この情報を基に受信先カーネルのマイクロカーネル制御情報26を参照する。受信先カーネルのマイクロカーネル制御情報26には、受信先カーネルが管理するスレッドのスレッドメッセージバッファ25のアドレスが記憶されている。よって、受信先カーネルが管理するマイクロカーネル制御情報26と受信先スレッドのIDとを基に、受信先スレッドに割り当てられたスレッドメッセージバッファ25(送信先バッファ)のアドレスを取得することができる。そして、ステップS140に進む。
【0073】
ステップS140では、ステップS135の処理において送信先バッファを特定できたかをチェックする。すなわち、ステップS115でYESとなったものの、キャッシュに登録されている情報が古い場合(キャッシュに登録された後でスレッドマイグレーションが発生していた場合)、キャッシュの情報を基に特定した受信先カーネルに受信先スレッドが存在せず、送信先バッファを特定できない場合がある。このような場合は、ステップS120に戻り、スレッドスケジューラ32への問い合わせを行う。一方、送信先バッファを特定できた場合は、ステップS145に進む。
【0074】
ステップS145では、メッセージ送受信モジュール40が、送信先バッファにメッセージを書き込む(コピーする)。このとき、受信先カーネルのマイクロカーネル制御情報26を書き換えて、メッセージが書き込まれたことが分かるようにしておく。なお、もしこのときに送信先バッファが不足してあふれてしまう場合は、メッセージ送信は失敗する。このため、重要なメッセージを受信するスレッドのスレッドメッセージバッファ25は、枯渇しないように十分な余裕をもって確保すべきである。そして、ステップS150に進む。
【0075】
ステップS150では、メッセージ送受信モジュール40が、受信先カーネルに対応するプロセッサコア11に割り込みを発生させ、受信先カーネルに書き込み(ステップS145)の終了を通知する。このCPU割り込みは、受信先カーネルの割り込みハンドラによって処理されるため、受信先カーネルは割り込みによって書き込み(ステップS145)があったことを検知することができる。そして、ステップS155に進む。
【0076】
ステップS155は、同期制御の場合にのみ実行される処理である。このステップS155では、受信先カーネルからの受信完了通知がメッセージにより通知されることを待機する。受信先カーネルから受信完了通知を受け取ったら、メッセージ送信処理を終了し、message_sendの呼び出し元へと処理を返す。なお、非同期制御の場合には、受信先カーネルからの受信完了通知を待つことなく、メッセージ送信処理を終了し、message_sendの呼び出し元へと処理を返す(ただし、非同期実行かつステップS125が行われた場合には、その時点でmessage_sendの呼び出し元へと処理を返される。この場合は、ステップS155ではmessage_sendの呼び出し元に処理を返さない)。
【0077】
(割り込み発生時のメッセージ受信処理)
次に、割り込み発生時のメッセージ受信処理の具体的な流れについて、
図5のフローを参照しながら説明する。このメッセージ受信処理は、上記したメッセージ送信処理のステップS150において発生した割り込みを検知したときに、受信先カーネル(受信先スレッドが属するマイクロカーネル30)の割り込みハンドラによって実行される処理である。
【0078】
まず、
図5に示すステップS205において、メッセージの書き込み完了を通知するCPU割り込みが発生する。このCPU割り込みによって、受信先カーネルの割り込みハンドラが起動し、メッセージ受信処理が開始される。そして、ステップS210に進む。
【0079】
ステップS210では、メッセージ送受信モジュール40が、受信先カーネルのマイクロカーネル制御情報26を参照し、未取り出しのメッセージを特定する。未取り出しのメッセージが複数ある場合は、所定のポリシー(メッセージの到達順、メッセージの優先度順、など)に従って、順番にメッセージを処理する。なお、マイクロカーネル制御情報26には、メッセージを格納したスレッドメッセージバッファ25のアドレスが記憶されているだけであり、実際のメッセージはスレッドメッセージバッファ25に記憶されている。そして、ステップS210に進む。
【0080】
ステップS220では、メッセージ送受信モジュール40が、受信先カーネル(メッセージマネージャ34)に、読み出し対象のメッセージを示すスレッドメッセージバッファ25のポインタを渡す。受信先カーネルは、スレッドメッセージバッファ25の中身を参照し、メッセージを読み込む。メッセージのヘッダには、メッセージの宛先(例えば受信先スレッドのID)が記載されている。これを参照し、受信先スレッドを特定する。そして、ステップS225に進む。
【0081】
ステップS225では、受信先スレッドが受信待ちであるかがチェックされる。具体的には、受信先スレッドが同期制御を指定してメッセージ受信用API(message_receive)を呼び出しており、WAIT状態となっているかがチェックされる。受信待ちでない場合は、ステップS230に進む。受信待ちの場合は、ステップS235に進む。
【0082】
ステップS230では、受信待ちメッセージキューにメッセージ(のポインタ)を追加する。受信待ちメッセージキューは、スレッドの受け取りを待っている受信メッセージをスレッドごとに管理するためのキューである。受信先スレッドがmessage_receiveを呼び出してメッセージを受け取るまで、受信先スレッドの受信待ちメッセージキューに当該メッセージが保持されることになる。そして、割り込み処理を終了する。
【0083】
ステップS235に進んだ場合、message_receiveのパラメータとして指定されたデータ格納領域に、スレッドメッセージバッファ25の内容をコピーする。そして、ステップS240に進む。
【0084】
ステップS240では、メッセージをスレッドメッセージバッファ25から削除する(本実施形態においては、キュー構造で管理されているスレッドメッセージバッファ25について、当該メッセージが格納されていた領域を、空きバッファとしてキューに戻す処理を行う)。また、読み出したメッセージを取り出し済みとするために、自身(受信先カーネル)のマイクロカーネル制御情報26を書き換える。そして、ステップS245に進む。
【0085】
ステップS245では、受信先スレッドのWAIT状態を解除する。これにより、受信先スレッドにおいて、message_receiveの呼び出し元へと処理が返される。そして、割り込み処理を終了する。
【0086】
(API呼び出し時のメッセージ受信処理)
次に、API(message_receive)呼び出し時のメッセージ受信処理の具体的な流れについて、
図6のフローを参照しながら説明する。このメッセージ受信処理は、メッセージ受信用API(message_receive)が呼び出されたときに、受信先カーネル(受信先スレッドが属するマイクロカーネル30)によって実行される処理である。
図6のフローは、message_receiveの内部で実行される処理を説明している。ただし、このフローでは、エラー処理などの一部の処理については説明を省略している。例えば、不正なパラメータが指定された場合には、message_receiveの戻り値としてエラー値を返却するが、このような処理については説明を省略している。
【0087】
まず、
図6に示すステップS305において、任意の受信先スレッドがメッセージ受信用API(message_receive)を呼び出す。このAPI呼び出しを受信先カーネルが受け取ることによって、処理が開始される。そして、ステップS310に進む。
【0088】
ステップS310では、受信待ちメッセージキューにメッセージがあるか(
図5のステップS230で追加されたメッセージがあるか)がチェックされる。メッセージがある場合は、ステップS315に進む。メッセージがない場合は、ステップS330に進む。
【0089】
ステップS315に進んだ場合、message_receiveのパラメータとして指定されたデータ格納領域に、スレッドメッセージバッファ25の内容をコピーする。そして、ステップS320に進む。
【0090】
ステップS320では、メッセージをスレッドメッセージバッファ25から削除する(上記したように、メッセージが格納されていた領域を、空きバッファとしてスレッドメッセージバッファ25のキューに戻す処理を行う)。また、読み出したメッセージを取り出し済みとするために、自身(受信先カーネル)のマイクロカーネル制御情報26を書き換える。以上でメッセージ受信処理が完了したので、message_receiveの呼び出し元へと処理を返す。
【0091】
また、ステップS330に進んだ場合、同期受信であるかがチェックされる。同期受信の場合は、ステップS335に進む。非同期受信の場合は、message_receiveの呼び出し元へとエラーを返し、処理を終了する。
【0092】
ステップS335では、受信先スレッドをWAIT状態に設定する。これにより、受信先スレッドは、
図5のステップS245でWAIT状態を解除するまで待機することになる。WAIT状態を解除されたら、処理を終了し、message_receiveの呼び出し元へと処理を返す。
【0093】
(まとめ)
上記したように、本実施形態によれば、スレッドの生成時に、当該スレッドに固有のスレッドメッセージバッファ25が確保されている。このため、高い安全性が求められないスレッドに対するメッセージが一時的に増加してバッファが枯渇した場合でも、高い安全性が求められるスレッドが影響を受けることはない。このため、メッセージの受信量が一時的に増加した場合でも、重要なメッセージを確実に送受信することができる。
【0094】
また、スレッドメッセージバッファ25を確保するにあたり、スレッドごとに使用する最大サイズを見積もり、スレッドごとに任意のサイズを設定することができる。スレッドが使用するバッファのサイズは、スレッドがマイグレーションしても変わらないので、必要なバッファサイズの計算も容易である。
【0095】
例えば、あるスレッドが必要とするバッファサイズは「1メッセージ当たりの格納可能最大サイズ×格納可能なメッセージ数」で求めることができる。高い安全性が求められるスレッドについては、十分なバッファを確保することで、仮にほかのスレッドのバッファがあふれてしまった場合でも、影響なくメッセージを受信することができる。
【符号の説明】
【0096】
10 CPU
11 プロセッサコア
15 スケジューリングクラスタ
16 ハードウェアクラスタ
20 メモリ
25 スレッドメッセージバッファ
26 マイクロカーネル制御情報
30 マイクロカーネル
31 ローカルスケジューラ
32 スレッドスケジューラ(スレッド管理機能)
33 上位のスレッドスケジューラ
34 メッセージマネージャ
35 割り込みマネージャ
39 インタフェースライブラリ
40 メッセージ送受信モジュール