(57)【特許請求の範囲】
【請求項１】
複数の同時実行中スレッド間における共有可能リソースの排他的制御を管理するための方法であって、前記共有可能リソースへのアクセスは、ロックによって制御され、前記ロックは、前記ロックの所有権を要求するスレッドの順序付けられたセットを維持し、前記方法は、
スレッドの前記セット内の前記ロックを次に所有するスレッドが、前記ロックの請求を非アトミックに公表するステップであって、前記請求が、単一メモリ・アクセスでのみ読み取りおよび書き込みが行われることが可能な構造を備える、前記ステップと、
請求を公表する前記ステップの後、前記ロックを次に所有する前記スレッドが、それがプリエンプトされているかどうかを判定するステップと、
前記判定に応答して、前記ロックを次に所有する前記スレッドが、それがプリエンプトされていない場合は、前記ロックを獲得し、それがプリエンプトされている場合は、前記ロックの獲得を再び試みるステップと、
前記次に所有するスレッドがプリエンプトされていることに応答して、それ以降に所有するスレッドが、前記ロックを不公平に獲得し、前記ロックをアトミックに一貫性をもって変更して、次のロック・オーナが、それがプリエンプトされていると判定することができるようにするステップと、
を含む、方法。
【請求項２】
前記順序付けられたセットは、チケットを含み、前記ロックの所有権を要求する各スレッドは、チケットを獲得し、
前記請求は、前記次に所有するスレッドによって獲得された前記チケットの識別子と、前記次に所有するスレッドが前記ロックを請求している旨の表示とを含む、
請求項１に記載の方法。
【請求項３】
前記次に所有するスレッドのチケットを現在のチケットと比較し、前記次に所有するスレッドのチケットと現在のチケットとの間の一致に応答して、前記ロックを非アトミックに獲得するステップをさらに含む、請求項２に記載の方法。
【請求項４】
前記請求の構造が、ユニオンである、請求項１に記載の方法。
【請求項５】
前記次に所有するスレッドがプリエンプトされているとの判定に応答して、前記次に所有するスレッドが、前記ロックの所有権の要求をキャンセルする、請求項１に記載の方法。
【請求項６】
複数の同時実行中スレッド間における共有可能リソースの排他的制御を管理するためのシステムであって、
前記共有可能リソースへのアクセスを制御するためのロックであって、前記ロックが、前記ロックの所有権を要求するスレッドの順序付けられたセットを維持する、前記ロックと、
単一メモリ・アクセスでのみ読み取りおよび書き込みが行われ、スレッドの前記セット内の次に所有するスレッドによって非アトミックに公表され、前記ロックの請求を行うことが可能な請求構造と、
前記請求を公表した後、前記ロックを次に所有する前記スレッドが、それがプリエンプトされているかどうかを判定するための手段と、
前記次に所有するスレッドがプリエンプトされているかどうかを判定するための前記手段に応答して、前記ロックを次に所有する前記スレッドが、それがプリエンプトされていない場合は、前記ロックを獲得し、それがプリエンプトされている場合は、前記ロックの獲得を再び試みるための手段と、
前記次に所有するスレッドがプリエンプトされていることに応答して、それ以降に所有するスレッドが、前記ロックを不公平に獲得し、前記ロックをアトミックに一貫性をもって変更して、次のロック・オーナが、それがプリエンプトされていると判定することができるようにするための手段と、
を備える、システム。
【請求項７】
前記順序付けられたセットは、チケットを含み、前記ロックの所有権を要求する各スレッドは、チケットを獲得し、
前記請求は、前記次に所有するスレッドによって獲得された前記チケットの識別子と、前記次に所有するスレッドが前記ロックを請求している旨の表示とを含む、
請求項６に記載のシステム。
【請求項８】
前記次に所有するスレッドのチケットを現在のチケットと比較し、前記次に所有するスレッドのチケットと現在のチケットとの間の一致に応答して、前記次に所有するスレッドが、前記ロックを非アトミックに獲得するための手段をさらに備える、請求項７に記載のシステム。
【請求項９】
前記次に所有するスレッドがプリエンプトされていることに応答して、前記次に所有するスレッドが、前記ロックの所有権の要求をキャンセルする、請求項６に記載のシステム。
【請求項１０】
前記請求構造が、ユニオンである、請求項６に記載のシステム。
【請求項１１】
請求項１〜５に記載の何れか１項に記載の方法の各ステップをコンピュータに実行させる、コンピュータ・プログラム。
【請求項１２】
請求項１１に記載の前記コンピュータ・プログラムをコンピュータ可読記憶媒体に記録した、コンピュータ可読記憶媒体。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、複数の同時実行中スレッド間における共有可能リソースの排他的制御を管理することに関し、より詳細には、ロック要求者プリエンプション問題（lock requester preemption problem）を免れているが、ロック要求者プリエンプション問題の管理からもたらされる性能低下なしに、共有可能リソースの排他的制御を管理することに関する。
【背景技術】
【０００２】
（ロック・フリー・クラスのアルゴリズムを除く）同時アルゴリズムは、何らかの種類のアクセス制御メカニズムを利用して、同期、すなわち、共有リソースへの個別アクセスを保証する。例えば、相互排他ロックを使用して、各スレッドは、続行するために、個別共有リソースにアクセスする前に、ロックを獲得しなければならず、またはロックが利用可能でない場合は、スレッドは、それがロックの現在のオーナによって解放されるまで、待機しなければならない。
【０００３】
この文脈では、スレッド待機は、２つの可能な方法で達成することができる。ビジー・ロック（busy lock）を使用することができ、その場合、スレッドは、ロックを検査するタイト・ループに入り、ロックが行われていないことが分かるまで、ループを続行する。パッシブ・ロック（passive lock）を使用することができ、その場合、スレッドは、自らを待機中スレッドの連結リストの待ち行列に加え、実行を一時停止して、ロックが利用可能になったときにロック・オーナによってウェイク・アップされるのを待機する。
【０００４】
先行技術のビジー・ロックは、一般に、ロッキング・アルゴリズムの２つの主要なクラス、すなわち、不公平と公平とに分類される。一般に、不公平ロッキング・アルゴリズムでは、各ロック要求者は、そのロック要求者がロックを獲得したことを検出するまで、他のすべてのロック要求者と争ってループする。ロックの獲得は、すべての競合するロック要求者スレッドによる命令の実行の相対的タイミングに依存するので、ロックの獲得は、設計よりもより偶然によって生じる。反対に、公平ロッキング・アルゴリズムでは、ロックによって保護された共有可能リソースへのアクセスは、順序付けられ、各ロック要求者は、スレッドがロックを使用して自らを開始する前に、順番が先行するロック要求者が、ロックが制御するいかなるクリティカル・セクションの作業であれそれを完了するのを待機する。ロック自体は、ロックの所有権を要求するスレッドの順序付けられたリストを維持することができる。
【０００５】
ビジー・ロックは、多くの副作用の弊害を被り、それらは、不公平および公平クラスの両方に共通である。一般に、公平ロックと不公平ロックは、前記副作用に対処する際に、各々が成功する方法または成功しない方法において相補的である。最も顕著な相違は、不公平ロック・アルゴリズムでは、ロック・オーナがロックを獲得したことが分かるが、公平ロックでは、ロック・オーナがロックを獲得したことが仮定されることである。
【０００６】
John M. Mellor-Crummey and Michael L.Scott, 1991, “Algorithms for scalable synchronizationon shared-memory multiprocessors”, ACM Trans. Comput.Syst. 9, 1 (February 1991), 21-65は、メモリまたは相互接続競合を引き起こさない、ビジー・ウェイト同期アルゴリズムを開示している。どのプロセッサも、別々のローカルにアクセス可能なフラグ変数に基づいてスピンし、他のあるプロセッサが、適切な時に、単一リモート書き込み操作を用いて、スピンを終了させる。フラグ変数は、コヒーレント・キャッシング（coherent caching）の結果として、または物理的に分散する共有メモリのローカル部分における割り当てのおかげで、ローカルにアクセス可能であることができる。
【０００７】
Bijun He, William N. Scherer, and MichaelL. Scott, 2005, “Preemption adaptivity intime-published queue-based spin locks”, Proceedings ofthe 12th international conference on High Performance Computing (HiPC’05), 7-18は、各スレッドがそれの現在のタイムスタンプを共有メモリのロケーションに定期的に記録する、時刻公表ヒューリスティック（time-publishing heuristic）を開示している。現代のプロセッサの高分解能の大まかに同期が取られたクロックを仮定すると、この規約は、スレッドが、それらのタイムスタンプの流布に基づいて、どのスレッドがアクティブであるかを正確に推測することを可能にする。
【０００８】
Phuong Hoai Ha, Marina Papatriantafilou,and Philippas Tsigas, 2005, “Reactive Spin-locks: ASelf-tuning Approach”, Proceedings of the 8thInternational Symposium on Parallel Architectures, Algorithms and Networks(ISPAN ’05). IEEE Computer Society, Washington, DC,USA, 33-39は、実験的に調整されるパラメータも、入力の確率分布も、必要とされないことを意味する、完全に自己調整的な、反応型スピン・ロック・アルゴリズムを開示している。スピン・ロックは、競合的なオンライン・アルゴリズムに基づいて築かれる。
【０００９】
Ryan Johnson, Manos Athanassoulis, RaduStoica, and Anastasia Ailamaki, 2009, “A new look atthe roles of spinning and blocking”, Proceedings of theFifth International Workshop on Data Management on New Hardware (DaMoN ’09). ACM, New York, NY, USA, 21-26は、競合管理の負荷制御の面を分離して、２つの問題、すなわち、スピニング・ベースの競合管理と、ブロッキング・ベースの負荷制御とを別々に取り扱うことによって、スピニングおよびブロッキング同期間における推移するトレードオフを簡素化することを開示している。
【００１０】
F. Ryan Johnson, Radu Stoica, AnastasiaAilamaki, and Todd C. Mowry, 2010, “Decouplingcontention management from scheduling”, Proceedings ofthe fifteenth edition of ASPLOS on Architectural support for programminglanguages and operating systems (ASPLOS XV). ACM, New York, NY, USA, 117-128は、存在し得るいかなる競合からも切り離して、システム内のアクティブ・スレッドの数を管理する、負荷制御メカニズムを開示している。ＯＳスケジューラとの有害な対話から競合管理を分離することによって、スピニングの効率は、ブロッキングのロバスト性と結び付けられる。提案された負荷制御メカニズムは、負荷の軽いおよび負荷の重いシステムの両方について、安定した高い性能をもたらし、ＯＳレベルにおける特別な特権または変更を必要とせず、既存のコードに役立つライブラリとして実施することができる。
【００１１】
Jonathan Eastep, David Wingate, Marco D.Santambrogio, and Anant Agarwal, 2010, “Smartlocks:lock acquisition scheduling for self-aware synchronization”, Proceedings of the 7th international conference on Autonomiccomputing (ICAC ’10). ACM, New York, NY, USA, 215-224は、スマートロックと呼ばれる、マルチコアおよび非対称マルチコアのための自己認識同期（self-aware synchronization）ライブラリを開示している。スマートロックは、性能または問題固有の基準に関連し得るユーザ定義の目標に向けて最適化を行うために、ヒューリステックおよび機械学習を使用して、実行中に、それの内部実装を適応させるスピン・ロック・ライブラリである。スマートロックは、反応型ロックなど先行研究からの適応技法に基づいて築かれるが、マルチコアにおける非対称性に対処するために特別に設計された、ロック獲得スケジューリングと呼ばれる、新規な形態の適応を導入する。ロック獲得スケジューリングは、複数のスレッド（またはプロセス）がロックを求めてスピンしている場合に、長期効果を最良にするために、どの待機者が次にロックを取得するかについて最適化を行う。
【００１２】
Kishore Kumar Pusukuri, Rajiv Gupta, andLaxmi N. Bhuyan, 2011, “No More Backstabbing... AFaithful Scheduling Policy for Multithreaded Programs”,Proceedings of the 2011 International Conference on Parallel Architectures andCompilation Techniques (PACT ’11). IEEE ComputerSociety, Washington, DC, USA, 12-21は、コンテキスト・スイッチおよびロック保有者スレッド・プリエンプション（lock-holder thread preemption）を劇的に減少させる、忠実スケジューリング（ＦＦ：Faithful Scheduling）と呼ばれる、スケジューリング・ポリシーを開示している。
【００１３】
Jiannan Ouyang and John R. Lange, 2013, “Preemptable ticket spinlocks: improving consolidated performance inthe cloud”, Proceedings of the 9th ACM SIGPLAN/SIGOPSinternational conference on Virtual execution environments (VEE ’13). ACM, New York, NY, USA, 191-200は、ロック待機者プリエンプション問題（Lock Waiter Preemption problem）、および待機者がロックを獲得することができるようになる前にプリエンプトされる問題を開示している。これは、ロック自体が利用可能である場合でも、ロックへのアクセスをブロックする効果を有する。両方の問題を解決するために、プリエンプタブル・チケット・スピンロックス（Preemptable Ticket spinlocks）が開示され、それは、チケット・ロックによって提供される順序付け保証を緩和することによって、仮想マシンが常に前に進むことを可能にするように設計された、新しいロッキング・プリミティブである。
【先行技術文献】
【特許文献】
【００１４】
【特許文献１】英国特許出願ＧＢ１４０６８３３．２
【非特許文献】
【００１５】
【非特許文献１】John M. Mellor-Crummey and MichaelL. Scott, 1991, “Algorithms for scalablesynchronization on shared-memory multiprocessors”, ACMTrans. Comput. Syst. 9, 1 (February 1991), 21-65
【非特許文献２】Bijun He, William N. Scherer, andMichael L. Scott, 2005, “Preemption adaptivity intime-published queue-based spin locks”, Proceedings ofthe 12th international conference on High Performance Computing (HiPC’05), 7-18
【非特許文献３】Phuong Hoai Ha, MarinaPapatriantafilou, and Philippas Tsigas, 2005, “ReactiveSpin-locks: A Self-tuning Approach”, Proceedings of the8th International Symposium on Parallel Architectures, Algorithms and Networks(ISPAN ’05). IEEE Computer Society, Washington, DC,USA, 33-39
【非特許文献４】Ryan Johnson, Manos Athanassoulis,Radu Stoica, and Anastasia Ailamaki, 2009, “A new lookat the roles of spinning and blocking”, Proceedings ofthe Fifth International Workshop on Data Management on New Hardware (DaMoN ’09). ACM, New York, NY, USA, 21-26
【非特許文献５】F. Ryan Johnson, Radu Stoica,Anastasia Ailamaki, and Todd C. Mowry, 2010, “Decouplingcontention management from scheduling”, Proceedings ofthe fifteenth edition of ASPLOS on Architectural support for programminglanguages and operating systems (ASPLOS XV). ACM, New York, NY, USA, 117-128
【非特許文献６】Jonathan Eastep, David Wingate,Marco D. Santambrogio, and Anant Agarwal, 2010, “Smartlocks:lock acquisition scheduling for self-aware synchronization”, Proceedings of the 7th international conference on Autonomiccomputing (ICAC ’10). ACM, New York, NY, USA, 215-224
【非特許文献７】Kishore Kumar Pusukuri, Rajiv Gupta,and Laxmi N. Bhuyan, 2011, “No More Backstabbing... AFaithful Scheduling Policy for Multithreaded Programs”,Proceedings of the 2011 International Conference on Parallel Architectures andCompilation Techniques (PACT ’11). IEEE ComputerSociety, Washington, DC, USA, 12-21
【非特許文献８】Jiannan Ouyang and John R. Lange,2013, “Preemptable ticket spinlocks: improvingconsolidated performance in the cloud”, Proceedings ofthe 9th ACM SIGPLAN/SIGOPS international conference on Virtual executionenvironments (VEE ’13). ACM, New York, NY, USA, 191-200
【発明の概要】
【発明が解決しようとする課題】
【００１６】
先行技術の実施に伴う問題は、スレッドがスピンしている間に、それのタイム・スライスが経過したために、オペレーティング・システムがスレッドをプリエンプトすることである。これは、「ロック要求者プリエンプション」（ＬＲＰ）問題と呼ばれる。プリエンプトされたスレッドよりも前のロック要求者は、ロックを獲得し、解放するが、プリエンプトされたスレッドは、それの順番が到来したことをチェックするためにそこにおらず、そのため、プリエンプトされたスレッド以降のどのスレッドも、オペレーティング・システムが、プリエンプトされたスレッドを再びスケジュールするのを待機しなければならない。そうしている間に、以降の各待機中スレッドは、それのタイム・スライスを使い果たす可能性が高く、オペレーティング・システムによってプリエンプトされて、ロックが提供することができるスループットの一部分でロックを経験するスレッドのコンボイ（convoy）を形成する。現代のマルチコアＣＰＵおよび仮想マシン（ＶＭ）環境を用いる場合、これらのボトルネックは、より頻繁に見られる。本発明の課題は複数の同時実行中スレッド間における共有可能リソースの排他的制御を管理するための方法、システム、およびコンピュータ・プログラムを提供することである。
【課題を解決するための手段】
【００１７】
本発明の実施形態は、複数の同時実行中スレッド間における共有可能リソースの排他的制御を管理するための方法を提供し、共有可能リソースへのアクセスは、ロックによって制御され、ロックは、ロックの所有権を要求するスレッドの順序付けられたセットを維持し、方法は、スレッドのセット内のロックを次に所有するスレッドが、ロックの請求を非アトミックに公表するステップであって、請求が、単一メモリ・アクセスでのみ読み取りおよび書き込みが行われることが可能な構造を備える、ステップと、請求を公表する前記ステップの後、ロックを次に所有する前記スレッドが、それがプリエンプトされているかどうかを判定するステップと、前記判定に応答して、ロックを次に所有する前記スレッドが、それがプリエンプトされていない場合は、ロックを獲得し、それがプリエンプトされている場合は、ロックの獲得を再び試みるステップと、次に所有するスレッドがプリエンプトされていることに応答して、それ以降に所有するスレッドが、ロックを不公平に獲得し、ロックをアトミックに一貫性をもって変更して、次のロック・オーナが、それがプリエンプトされていると判定することができるようにするステップとを含む。
【００１８】
一実施形態では、前記順序付けられたセットは、チケットを含み、ロックの所有権を要求する各スレッドは、チケットを獲得し、前記請求は、次に所有するスレッドによって獲得されたチケットの識別子と、次に所有するスレッドがロックを請求している旨の表示とを含む。
【００１９】
好ましくは、方法は、前記次に所有するスレッドのチケットを現在のチケットと比較し、前記次に所有するスレッドのチケットと現在のチケットとの間の一致に応答して、ロックを非アトミックに獲得するステップをさらに含む。これは、他のロック要求者が存在しない状況において、性能を改善する利点を有する。
【００２０】
一実施形態では、前記請求構造は、ユニオン（union）である。
【００２１】
一実施形態では、前記次に所有するスレッドがプリエンプトされているとの判定に応答して、前記次に所有するスレッドは、ロックの所有権の要求をキャンセルする。
【００２２】
本発明の実施形態は、複数の同時実行中スレッド間における共有可能リソースの排他的制御を管理するためのシステムも提供し、システムは、共有可能リソースへのアクセスを制御するためのロックであって、ロックが、ロックの所有権を要求するスレッドの順序付けられたセットを維持する、ロックと、単一メモリ・アクセスでのみ読み取りおよび書き込みが行われ、スレッドのセット内の次に所有するスレッドによって非アトミックに公表され、ロックの請求を行うことが可能な請求構造と、請求を公表する前記ステップの後、ロックを次に所有する前記スレッドが、それがプリエンプトされているかどうかを判定するための手段と、前記次に所有するスレッドがプリエンプトされているかどうかを判定するための前記手段に応答して、ロックを次に所有する前記スレッドが、それがプリエンプトされていない場合は、ロックを獲得し、それがプリエンプトされている場合は、ロックの獲得を再び試みるための手段と、次に所有するスレッドがプリエンプトされていることに応答して、それ以降に所有するスレッドが、アトミック比較およびスワップ命令を通して、ロックを獲得するための手段とを備える。
【００２３】
本発明の実施形態は、複数の同時実行中スレッド間における共有可能リソースの排他的制御を管理するためのコンピュータ・プログラム製品も提供し、共有可能リソースへのアクセスは、ロックによって制御され、ロックは、ロックの所有権を要求するスレッドの順序付けられたセットを維持し、コンピュータ・プログラム製品は、コンピュータ可読プログラム・コードが具現化されたコンピュータ可読記憶媒体であって、コンピュータ可読プログラム・コードが、前記プログラムがコンピュータ上で実行された場合に、上で説明された方法を実行するように適応させられる、コンピュータ可読記憶媒体を備える。
【００２４】
本発明の好ましい実施形態を、今から、添付の図面を参照しながら、例としてより詳細に説明する。
【図面の簡単な説明】
【００２５】
【図１】各スレッドが３０００万回ビジー・ロックを獲得しなければならない第１のテスト・ケース・シナリオにおける、「チケット」および「テスト、セット・アンド・テスト、バックオフ」アルゴリズムの各々についての、テスト・ケース実行時間対スレッドの数についてのグラフである。
【図２】５０％のＣＰＵ負荷を有する単一ＣＰＵ仮想マシンの形態を取る負荷が加えられたときの第２のテスト・ケース・シナリオにおける、「チケット」アルゴリズムについての、テスト・ケース実行時間対スレッドの数についてのグラフである。
【図３】５０％のＣＰＵ負荷を有する単一ＣＰＵ仮想マシンの形態を取る負荷が加えられたときの第２のテスト・ケース・シナリオにおける、「テスト、セット・アンド・テスト、バックオフ」アルゴリズムについての、テスト・ケース実行時間対スレッドの数についてのグラフである。
【図４】第２のテスト・ケース・シナリオにおける、「チケット」アルゴリズムについての、異なるＣＰＵの数ごとの、ロング・スピンの回数対スレッドの数についてのグラフである。
【図５】第２のテスト・ケース・シナリオにおける、「テスト、セット・アンド・テスト、バックオフ」アルゴリズムについての、異なるＣＰＵの数ごとの、ロング・スピンの回数対スレッドの数についてのグラフである。
【図６】５０％のＣＰＵ負荷を有する単一ＣＰＵ仮想マシンの形態を取る負荷が加えられたときの第２のテスト・ケース・シナリオにおける、「プリエンプタブル・ロック」アルゴリズムについての、テスト・ケース実行時間対スレッドの数についてのグラフである。
【図７】利用可能なＣＰＵと同数のロック要求者（このケースでは、６つのスレッド、６つのＣＰＵ）を有し、物理ＣＰＵ時間の５０％を占有する仮想マシンの形態を取る外部負荷の数量を（０から５まで）変化させて実行される場合の、「チケット」、「テスト、セット・アンド・テスト、バックオフ」、および「プリエンプタブル・ロック」アルゴリズムの各々についての実行時間を示す図である。
【図８】共有リソースを制御するロックにアクセスすることを望む複数のスレッドを有する、本発明の実施形態のブロック図である。
【図９】図８のlock.displayユニオンをより詳細に示す図である。
【図１０】本発明に従ってロックを獲得するための方法の実施形態のフローチャートである。
【図１１】本発明に従ってロックを獲得するための方法の実施形態のフローチャートである。
【図１２】本発明に従ってロックを獲得するための方法の実施形態のフローチャートである。
【図１３】本発明に従ってロックを獲得するための方法の実施形態のフローチャートである。
【図１４】本発明に従ってロックを獲得するための方法の実施形態のフローチャートである。
【図１５】本発明に従ってロックを獲得するための方法の実施形態のフローチャートである。
【図１６】図１０から図１５の実施形態で獲得されたロックを解放するための方法の実施形態のフローチャートである。
【図１７】５０％のＣＰＵ負荷を有する単一ＣＰＵ仮想マシンの形態を取る負荷が加えられたときの第２のテスト・ケース・シナリオにおける、本発明によるアルゴリズムの実施形態についての、テスト・ケース実行時間対スレッドの数についてのグラフである。
【図１８】利用可能なＣＰＵと同数のロック要求者（このケースでは、６つのスレッド、６つのＣＰＵ）を有し、物理ＣＰＵ時間の５０％を占有する仮想マシンの形態を取る外部負荷の数量を（０から５まで）変化させて実行される場合の、「チケット」、「テスト、セット・アンド・テスト、バックオフ」、および「プリエンプタブル・ロック」アルゴリズムの各々についての実行時間を、本発明によるアルゴリズムの実施形態と一緒に示す図である。
【発明を実施するための形態】
【００２６】
上で説明されたように、ビジー・ロックは、副作用の弊害を被ることがあり、副作用は、（ｉ）「待機スレッドの全起動（Thundering herd）」、（ｉｉ）「ＣＰＵキャッシュ無効化（CPU cacheinvalidation）」、（ｉｉｉ）「コア内スレッド欠乏（In core threadstarvation）」、（ｉｖ）「欠乏（Starvation）」、および（ｖ）「コンボイ(Convoys)」を含む。
【００２７】
「待機スレッドの全起動」−典型的なロックのテスト・アンド・セットは、特定のアセンブリ言語命令を使用して、ロックを獲得しようと試み、その命令は、特定の値をロック構造に書き込み、先にストアされた値を、バスをロックして、読み戻す。ロックから読み戻された値が、先にストアされた値と異なる場合、ロックが獲得されており、そうではない場合、ロックを獲得する新しい試みが必要とされる。このプロセスは、２つのスレッドだけがロックを獲得しようと試みている場合は機能する。しかしながら、多くのスレッド、「待機スレッドの全起動」のスレッドが、ロックを獲得しようと試みている場合、ロックは、ビジーになり、それは、ＣＰＵ上で、およびより重要なことには、バス・リソース上でかなりの消耗を引き起こし、ならびに以下で説明されるＣＰＵキャッシュ無効化を引き起こす。
【００２８】
「ＣＰＵキャッシュ無効化」−テスト・アンド・セットなど、同じメモリ・ロケーションへの度重なる再書き込みのせいで、書き込みが重いアルゴリズムは、他のＣＰＵが、ループのたびに、それらの内部メモリ・キャッシュに再ロードするように強いる。ただ１つのスレッドが、ロック上でループしている場合、これは問題ではないが、２つ以上のスレッドが、異なるＣＰＵ上で動作しながら、同じロック上でループしている場合、各々は、ロックのために他のメモリ・キャッシュ・エントリを無効化して、それらが、はるかに高いコストで、キャッシュからの代わりに、メモリからロックにアクセスするように強い、ロック性能に著しい影響を与える。
【００２９】
「コア内スレッド欠乏」−上述の問題は、ロックを放棄しようと試みているロック・オーナが、ＣＰＵ内の１つのスレッドに関連付けられ、一方、他のスレッドがロックを獲得するためにループするときに、（ＣＰＵが実行の複数の論理スレッドを実行しており、オペレーティング・システムがそれを２つの異なるＣＰＵとして見るが、実行中スレッドが、例えば、メモリ・アクセスのために、停止する必要がある場合にだけ、スレッド間のスイッチングが行われる）粒度の粗いコア内スレッドが、より一層ロック性能を低下させることがある場合、より悪化し得る。待機者スレッドが、オーナ・スレッドに譲るまで（粒度が粗いので、しばらくの間、そうしないことがある）、ロック・オーナは、実行の機会を取得しないので、ロックは、実際上、立ち往生する。
【００３０】
「欠乏」−利用可能なＣＰＵよりも多くのスレッドが、同じロックにアクセスしようと試みる場合、すべてのＣＰＵは、最後にはビジーになり、同じロックを獲得しようと試みながら、タイト・ループを実行する。これは、他のスレッドが、それらがロックにアクセスしようと試みているのか、それともさらに悪いことには、無関係の作業をしているのかに拘わらず、ＣＰＵリソースを獲得するのを妨げる。ロック・オーナと関連付けられたＣＰＵを除いて、すべてのＣＰＵは、ロック上でループしているが、いかなる有益な作業もしていないので、システム全体は、実際上、欠乏状態にされて、急停止する。
【００３１】
「コンボイ」−この副作用は、チケットまたはリストなどの、例えば、Ｋ４２といった（発案者のメラー−クラミ（Mellor-Crummey）およびスコット（Scott）にちなんで名づけられた）ＭＣＳまたはその派生物などの、アクセスが順序付けられた公平ロック・アルゴリズムに特有である。これらのアルゴリズムでは、各スレッドは、それ自らがロックを獲得するのを許可される前に、先行ロック要求者がロックを獲得し、放棄するのを待機しなければならない。正味の結果は、ロック・オーナが、何らかの理由で、ロックの解放を遅延させられた場合、遅延が、次の待機者に伝搬する。これが、今度は、次のスレッドが遅延させられる原因となることがあり、それが、次のスレッドが遅延させられる原因となり、遅延の連鎖は、さらなる待機者がいなくなったときにだけ断たれる。これらの状況では、ロック上のスループットは、深刻な影響を受け、各スレッドは、先行スレッドの挙動をまねながら、足並みを揃えているように見える。プログラミング・エラーが存在する、すなわち、ロックが長時間にわたって獲得される場合、またはオペレーティング・システム問題が存在する、すなわち、ロック所有スレッドがオペレーティング・システムによってプリエンプトされ、オペレーティング・システムがそのスレッドを動作状態に戻すまで、アクセスが可能でない場合、ロック・オーナは、ロックの解放を遅延させられることがある。
【００３２】
不公平アルゴリズムは、待機スレッドの全起動およびＣＰＵキャッシュ無効化から被る弊害がほとんどである。これは、各スレッドが、ロックを獲得しようと試みて、ロックに連続的に走り書き（scribbling）を行うせいである。「走り書き」は、ロックがスレッド情報で上書きされると、それはもはや現在のものではなく、したがって、正しくない。ロックにアクセスしようと試みているスレッドが多いほど、より多くのキャッシュ無効化が生じる。走り書き活動がより高価になるほど、待機スレッドの全起動がますます問題となる。反対に、公平アルゴリズムは、コンボイから弊害を被り、各スレッドは、先行スレッドがそれの作業を完了するのを待機しなければならず、どのような理由にしろ、先行スレッドが遅延させられた場合、そのような遅延は、ロック要求者と次のロック要求者との間にギャップが生じるまで、すなわち、次のロック要求者が、ロックが空いたときにロックを獲得しようと試みるときまで、すべての待機者に伝搬する。
【００３３】
コンボイの最も一般的なトリガは、スレッドがスピンしている間に、それのタイム・スライスが経過したために、オペレーティング・システムがスレッドをプリエンプトすることである。これは、「ロック要求者プリエンプション」問題と呼ばれる。プリエンプトされたスレッドよりも前のロック要求者は、ロックを獲得し、解放するが、プリエンプトされたスレッドは、それの順番が到来したことをチェックするためにそこにおらず、そのため、プリエンプトされたスレッド以降のどのスレッドも、オペレーティング・システムがプリエンプトされたスレッドを再びスケジュールするのを待機しなければならない。そうしている間に、以降の各待機中スレッドは、それのタイム・スライスを使い果たす可能性が高く、オペレーティング・システムによってプリエンプトされて、ロックが提供することができるスループットの一部分でロックを経験するスレッドのコンボイを形成する。現代のマルチコアＣＰＵおよび仮想マシン（ＶＭ）環境を用いる場合、これらのボトルネックは、より頻繁に見られる。仮想マシン・スケジューラは、物理ＣＰＵを離れて、ロック保有者を実行する仮想ＣＰＵをスケジュールすることができる。ＶＭ環境で動作するアプリケーションは、ＶＭスケジューラを制御せず、それの仮想ＣＰＵが再びスケジュールされるのを待機して立ち往生する。仮想ＣＰＵプリエンプションは、仮想ホスト環境における問題の大半であるので、例として、Ｌｉｎｕｘ（Ｒ）オペレーティング・システムは、非ホスト環境において、チケット・ロック（公平）を、それらの優れた性能のために使用するが、ハイパーバイザ環境では、仮想ＣＰＵがひとたびプリエンプトされ、続いてコンボイが起こると、ゲスト・オペレーティング・システムは文字通り急停止するので、セット・アンド・テスト・ロック（不公平）を依然として保持している。Ｌｉｎｕｘカーネルのハイパーバイザ・エディションにおいて使用可能なように公平ロックを適応させようと試みる作業が、少なくとも２０１０年以来続けられている。
【００３４】
以下のテスト・ケースは、問題を明示している。各スレッドがクリティカル・セクションを、定められた回数の間、定期的に通過しなければならない、マルチスレッド・アプリケーションについて考える。
【００３５】
static void *
load(void *args)
{
int seed = time(NULL);
int c, t;
for (c = 0; c < target; c++)
{
<ロック・ミューテックス>;
for (t = delay_l; t; t--)
<アセンブラ・ノーオペレーション>;
counter++;
<アンロック・ミューテックス>;
for (t = delay_u; t; t--)
<アセンブラ・ノーオペレーション>;
if ((rand_r(&seed) % yield_rate) ==0)
<譲る>;
}
}
【００３６】
上記のテスト・ケースにおける、２つの遅延（「delay_l」および「delay_u」）、「target」、ならびに「yield_rate」は、メイン・プログラムにおいて事前設定され、「counter」は、ビジー・ロックによって制御されるグローバル・リソースである。テストは、すべてのスレッドが、それらの作業を完了したときに、すなわち、各スレッドが、要求された回数の間に、ビジー・ロックを獲得したときに完了する。
【００３７】
図１を参照すると、それは、「公平」である「チケット」アルゴリズム、および「不公平」である「テスト、セット・アンド・テスト、バックオフ」アルゴリズムの、６ＣＰＵ  ｘ８６マシン上における、他の負荷がない、各スレッドが３０００万回ビジー・ロックを獲得しなければならない場合の、テスト・ケース実行時間対スレッドの数を示している。ただ１つのスレッドがクリティカル・セクションを通過する場合、２つのアルゴリズムは、類似の実行時間を有し、それは、同等なコスト、すなわち、１回のバスのロック、ロックを獲得するための（約１００クロック・サイクルのコストが掛かる）キャッシュ無効化書き込み、ロックを解放するための１回のキャッシュ無効化書き込み（約６クロック・サイクル）に依存する。
【００３８】
スレッドが２つの場合でも、アルゴリズムは、同等である。実際に、「テスト、セット・アンド・テスト、バックオフ」アルゴリズムは、より良好であるとしても僅かにそうであり得るにすぎない。どちらのアルゴリズムを用いても、スレッドが２つの場合のアルゴリズムのコストは、スレッドが１つの場合のアルゴリズムのコストに、Ｎ回の非無効化キャッシュ読み取り、ループ当たり１回のビジー・ウェイティングを加えたものと同じである。しかしながら、スレッドの数が、２つのスレッドよりも増加した場合、状況は、急速に変化する。「チケット」アルゴリズムのコストは、スレッドが２つのケースと同じであるが、一方で、「テスト、セット・アンド・テスト、バックオフ」アルゴリズムの場合、各ロック解放の後には、Ｎ回のバスのロック、（各々１００クロック・サイクルのコストが掛かる）キャッシュ無効化書き込み、ビジー・ウェイト後にロックを獲得しようとするスレッドごとに１回の試みが続く。関与するスレッドの数が多いほど、「テスト、セット・アンド・テスト、バックオフ」アルゴリズムのコストは、高くなる。明らかに、「チケット」アルゴリズムの挙動が、はるかに望ましい。
【００３９】
図２および図３を参照すると、それらは、５０％のＣＰＵ負荷を有する単一ＣＰＵ仮想マシンの形態を取る負荷が６ＣＰＵシステムに加えられ、したがって、スレッドが利用可能なＣＰＵ時間の量が減らされた場合の、「チケット」アルゴリズム対「テスト、セット・アンド・テスト、バックオフ」アルゴリズムの挙動を示している。
【００４０】
図２は、５０％のＣＰＵ負荷を有する単一ＣＰＵ仮想マシンの形態を取る負荷が加えられたときの第２のテスト・ケース・シナリオにおける、「チケット」アルゴリズムについての、テスト・ケース実行時間対スレッドの数についてのグラフを示している。「チケット」アルゴリズムを用いる場合、作業中スレッドの数が、利用可能なＣＰＵの数と一致する限り、実行時間は、「負荷なし」ケースと同等に留まっている。実行中スレッドの数が、利用可能なＣＰＵの数を超過すると、すなわち、いくつかのスレッドが、ＣＰＵリソースを求めて、仮想マシンと争うようになると直ちに、テスト実行時間は、深刻な悪化を見せる。例として、「負荷なし」のラベルが付けられた実線は、仮想マシンが動作していない場合の、「チケット」アルゴリズムの挙動を示している。テスト・ケース持続時間は、スレッドの数が利用可能なＣＰＵの数まで増加するとき、線形に増加する。
【００４１】
「１つのＣＰＵを使用」のラベルが付けられた超微細の破線は、１つのＣＰＵが１つの仮想マシンのためにビジーである場合の挙動を示している。テスト・ケース持続時間は、実行中スレッドの数が（ＣＰＵの数−１）よりも少ない間は、線形に増加するが、実行中スレッドが、仮想マシンの実行のためにビジーであるＣＰＵを使用しなければならなくなると、深刻な悪化を見せる。仮想マシンのためにビジーであるＣＰＵの数が増加するにつれて、テスト・ケース実行時間も増加する。１つを除くすべてのＣＰＵがビジーになる時間までには、テスト・ケース持続時間は、２倍を超える。これは、仮想ＣＰＵの動作を可能にするために、ロックを獲得する順番が次のスレッドが、オペレーティング・システムによってプリエンプトされたせいであり、それが、今度は、コンボイを形成する。仮想ＣＰＵの実行など他のことに占有されるＣＰＵの数が多くなるほど、プリエンプションの回数が多くなり、実行時間が悪化する。
【００４２】
図２の例では、各仮想マシン負荷が各ＣＰＵ時間の５０％に制限される場合に限って、グラフが再現可能であることは、まるで価値がない。これが超えられた場合、実行時間は、きわめて予測不可能になり、一般に、図２のグラフよりも良好な実行はなく、実行時間が５０％負荷のケースよりも５倍、６倍、または７倍悪化する実行が多い。
【００４３】
図３は、５０％のＣＰＵ負荷を有する単一ＣＰＵ仮想マシンの形態を取る負荷が加えられたときの第２のテスト・ケース・シナリオにおける、「テスト、セット・アンド・テスト、バックオフ」アルゴリズムについての、テスト・ケース実行時間対スレッドの数についてのグラフを示している。図２の「チケット」の例とは対照的に、「テスト、セット・アンド・テスト、バックオフ」の例では、他のことに占有されるＣＰＵの数が多くなるにつれて、実行時間が悪化することはない。実際に、実行時間は、負荷とともに実質的に改善する。これの理由は、あるスレッドが、仮想マシンの実行を可能にするためにプリエンプトされ、それが、ロック上でループするスレッドの数を制限し、仮想マシン負荷がないときに代わって現れる、待機スレッドの全起動の効果を抑制するからである。これは、上で言及されたように、ロックがひとたび解放されると、すべての待機中スレッドが、同時にバスのロック、キャッシュ無効化書き込みを実行するせいである。負荷があるときは、「テスト、セット・アンド・テスト、バックオフ」アルゴリズムの挙動が、はるかに望ましい。
【００４４】
負荷の増加に伴うプリエンプションの数は、ループの平均回数よりもかなり多く続くすべてのロック要求をカウントすることによって、計測することができる。上記の例では、ロック当たりの平均ループは、約１００回と計測された。「ロング・スピン」は、平均ロック・スピンの３００倍よりも多く続く任意のロックの試みと定義することができる。これは、先行ロック要求者がプリエンプトされたために起こる。図４および図５は、「チケット」アルゴリズムおよび「テスト、セット・アンド・テスト、バックオフ」アルゴリズムの各々についての、異なるＣＰＵの数ごとの、ロング・スピンの回数対スレッドの数についてのグラフを示している。
【００４５】
図４は、第２のテスト・ケース・シナリオにおける、「チケット」アルゴリズムについての、異なるＣＰＵの数ごとの、ロング・スピンの回数対スレッドの数についてのグラフを示している。グラフの下の部分の連続線によって示される、負荷がない場合、スレッドの数が増加するにつれて、ロング・スピンの回数は、ゆっくりとした割合で増加する。グラフの下の部分の超微細の破線によって示される、ＣＰＵが１つ使用される場合、ロング・スピンの回数は、５つのスレッドが存在するようになるまで、負荷なしの場合の線と同じ割合で増加し、そこからは、僅かに速い割合で増加する。細かい破線によって示される、ＣＰＵが２つ使用される場合、ロング・スピンの回数は、４つのスレッドが存在するようになるまで、負荷なしの場合の線と同じ割合で増加し、その後、５つのスレッドが存在するところに向かって急峻に増加し、その後、６つのスレッドが存在するところに向かって減少する。超微細の２つの点と３つの破線とよって示される、ＣＰＵが３つ使用される場合、ロング・スピンの回数は、３つのスレッドが存在するようになるまで、負荷なしの場合の線と同じ割合で増加し、その後、４つのスレッドが存在するところに向かって急峻に増加し、その後、５つのスレッドが存在するところに向かって僅かに減少し、その後、再び、６つのスレッドが存在するところに向かって急峻に増加する。細かい点線とよって示される、ＣＰＵが４つ使用される場合、ロング・スピンの回数は、２つのスレッドが存在するようになるまで、負荷なしの場合の線と同じ割合で増加し、その後、３つのスレッド、次に４つのスレッドが存在するところに向かって急峻に増加し、その後、５つのスレッドが存在するところに向かって急峻に減少し、その後、再び、６つのスレッドが存在するところに向かって増加する。２つの点と１つの破線とよって示される、ＣＰＵが５つ使用される場合、ロング・スピンの回数は、３つのスレッドが存在するようになるまで、負荷なしの場合の線と同じ割合で増加し、その後、４つのスレッド、次に５つのスレッドが存在するところに向かってゆっくりと増加し、その後、６つのスレッドが存在するところに向かって急峻に増加する。
【００４６】
図５は、第２のテスト・ケース・シナリオにおける、「テスト、セット・アンド・テスト、バックオフ」アルゴリズムについての、異なるＣＰＵの数ごとの、ロング・スピンの回数対スレッドの数についてのグラフを示している。負荷なしの場合の線、および１つから５つのＣＰＵが使用される場合の線の各々は、スレッドの数が２つまでに制限される間は、低レベルのロング・スピンを示す。３つから６つのスレッドが存在する場合、ロング・スピンの回数は増加するが、図４のそれよりははるかに低いレベルである。
【００４７】
図４の「チケット」アルゴリズムでは、最良のシナリオ、すなわち、仮想マシンを実行するＣＰＵからの追加の負荷がないシナリオは、図５の「テスト、セット・アンド・テスト、バックオフ」アルゴリズムにおける最悪よりもかなり悪い挙動を示す。図４の「チケット」アルゴリズムでは、仮想マシンを実行するＣＰＵからの追加の負荷が増加するにつれて、プリエンプションの回数は、予測不可能であるとともに、制御不可能である。図５の「テスト、セット・アンド・テスト、バックオフ」アルゴリズムでは、プリエンプション挙動は、テスト・ケース持続時間挙動に追随するように思え、すなわち、負荷が高いほど、挙動は良くなる。図５では、「テスト、セット・アンド・テスト、バックオフ」アルゴリズムは、ロックが獲得された後も、いくつかのロック・オーナはプリエンプトされるので、依然としていくつかのロング・スピンを示すことに留意されたい。
【００４８】
「チケット」アルゴリズムを使用するロックなどの公平ロックは、「テスト、セット・アンド・テスト、バックオフ」アルゴリズムを使用するロックなどの不公平な実施を上回る明らかな性能上の利点を提供するので、コンボイおよびロック・オーナ・プリエンプション問題に対する公平ロックの回復力を改善するために、いくつかの試みが行われた。
【００４９】
公平ロックの回復力を改善するそのような試みの例は、時刻公表（またはキャンセル可能）ロック（time published (or cancelable) lock）、仮想化およびハードウェア・ベースの技法、ならびに適応ロック・アルゴリズムを含む。
【００５０】
時刻公表（またはキャンセル可能）ロックは、リスト・ロックの変形であり、リスト・ロックの代表が、ＭＣＳである。リスト・ロック・アルゴリズムでは、各スレッドは、先行ロッカの状態を監視するループを行っておりビジーである。この手法は、ＣＰＵキャッシュ無効化に関して、いくつかの利点を有する。各スレッドは、異なるメモリ・ロケーションを監視しているので、いずれのロック解放も、次のロック・オーナのキャッシュを１回無効化するだけであるが、しかしながら、それは、実施するのにコストが掛かり、他の公平ロック・アルゴリズムよりも多くのコンボイをもたらす傾向がある。
【００５１】
各ロッカがハートビートを提供する挙動を、タイムスタンプを変更する形態に変更することによって、タイムスタンプは変化しないので、プリエンプトされたスレッドを検出することができる。プリエンプトされたスレッドは、（ＭＣＳ−ＴＰのケースでは）ロック解放時に、または（ＣＬＨ−ＴＰアルゴリズムのケースでは）先行ロック要求者の状態を監視している間に、ロック・オーナによってリストから除外され、その結果、コンボイを回避する。そのような手法の不都合な点は、第一に、ロック要求者リストの維持が高価であること、およびアンロック時間における立ち往生していないスレッドの探索、または実行時における立ち往生したスレッドの除外が、それをより一層高価にすることである。ＭＣＳ−ＴＰおよびＣＬＨ−ＴＰはともに、非競合ケースにおいて、実行時間に関して、「テスト、セット・アンド・テスト、バックオフ」よりも約７５％高価である。
【００５２】
仮想化およびハードウェア・ベースの技法を使用すると、スピン・ロック活動がハードウェアを介して検出された、またはゲストＯＳを介して報告された場合に、ハードウェア・サポートを介して、またはゲスト・オペレーティング・システムからのヒントによって、仮想マシンにゲスト仮想マシンのためのすべての仮想ＣＰＵをスケジュールさせることができる。ロックに関与する仮想マシンのためのすべての仮想ＣＰＵが、動作しているので、ロック・オーナは立ち往生させられず、コンボイが回避される。この手法は、ゲストＯＳおよび仮想化レイヤの両方において特別なコーディングを必要とし、やはりコストが掛かるものであり、ロッキング活動に関与するゲスト・マシンのためのすべての仮想ＣＰＵは、潜在的にはいかなる有益な作業も行わずに、他の仮想マシンのための仮想ＣＰＵを犠牲にして、動作させられ、それは、他の仮想マシン上で動作するプロセスが、一時的ではあるが大幅な性能上の低下を見ることがあることを意味する。
【００５３】
「プリエンプタブル・チケット・スピン・ロック」に関して上で説明されたような、適応ロック・アルゴリズムでは、公平ロックと不公平ロックが、単一ロック・アルゴリズムにおいて、各々の最良の特徴を提供するように組み合わされる。
【００５４】
アルゴリズムは、各ロック要求者が、ロックを獲得するために、平均スピン・ループ・カウントとして計算された指定されたループ回数の間は、第１の公平「チケット」ロックを経験し、それが経過した場合、第２の不公平「テスト、セット・アンド・テスト、バックオフ」ロックに移行するような方法で、実施される。すべての以降のロック要求者は、通常動作の下では、最初に第１の公平「チケット」ロックを経験しなければならないので、順番が最初のロック要求者は、他のスレッドと競合する必要なしに、第２の不公平「テスト、セット・アンド・テスト、バックオフ」ロックに達し、待機スレッドの全起動は生じることができないことがほぼ保証される。第２の不公平「テスト、セット・アンド・テスト、バックオフ」ロック上での競合は、ロック要求者スレッドの１つがプリエンプトされ、順番が次の正当なスレッドが第１の公平「チケット」ロックを脱出したのとちょうど同時に、不公平ロックに到達した場合に生じる。
【００５５】
この手法の不都合な点は、負荷がないとき、各ロッキングの試みが、
（ｉ）新しいチケットを取得するための、バスのロック、キャッシュ無効化書き込み（ｘ８６上で１００サイクル）、
（ｉｉ）不公平ロックを獲得するための、バスのロック、キャッシュ無効化書き込み（別の１００サイクル）、
（ｉｉｉ）displayを増加させるための、キャッシュ無効化書き込み、および
（ｉｖ）不公平ロックを解放するための、キャッシュ無効化書き込み
を必要とすることである。
【００５６】
これは、「チケット」アルゴリズムを使用するときの２倍のコストが掛かることを意味する。この追加コストに加えて、タイムアウトの計算は経験的であり、２つ以上のスレッドが同時に不公平ロックに達する状況が存在し、一時的な待機スレッドの全起動をトリガするというのが現実である。
【００５７】
図６は、第２のテスト・ケース・シナリオにおける、プリエンプタブル・ロックの挙動を示している。明らかに、プリエンプタブル・ロックの使用は、追加の負荷が適用されない場合は、「テスト、セット・アンド・テスト、バックオフ」よりも良好ないかなる性能も提供せず、負荷がある場合は、いかなる性能改善も達成せず、そのことは、それが、「チケット」または「テスト、セット・アンド・テスト、バックオフ」の実現可能な代用物ではないことを意味する。利点は、負荷がある場合、それの挙動が予測可能であり、図６に示されるように、負荷がある場合、それがほぼ不変であることである。
【００５８】
図７は、利用可能なＣＰＵと同数のロック要求者（このケースでは、６つのスレッド、６つのＣＰＵ）を有し、物理ＣＰＵ時間の５０％を占有する仮想マシンの形態を取る外部負荷の数量を（０から５まで）変化させて実行される場合の、各アルゴリズムについての実行時間を示している。
【００５９】
「プリエンプタブル・ロック」アルゴリズムに伴う問題は、それが、どのロック要求者にも、「チケット」アルゴリズムを上回るさらなる固定されたかなりのコストを有するように強い、それが、ひいては、ＬＲＰを回避する利点を打ち消すことである。ｘ８６アーキテクチャでは、次のチケットをアトミックに獲得するために使用されるLOCK XADD命令、および不公平ロックを掴み取ろうと試みるために使用されるLOCKXCHG命令の両方は、きわめて高価であり、非ロック・ストアの１０未満に対して、一般に１００クロック・サイクルを超えるオーダである。これは、それらが、（とりわけ、書き込みが他の書き込みと並べ替えられず、ロードが同じロケーションへの書き込みと並べ替えられない）使用中のメモリ・モデルを満たすために、以下のステップ、すなわち、
（ｉ）メモリへのパイプラインの完全なフラッシング、すなわち、実行のために待ち行列に入れられたすべての書き込みがメモリにコミットされるのを待機しなければならないこと、
（ｉｉ）バスのロッキング、
（ｉｉｉ）異なるロック要求者が以前にメモリ内容を変更したので、おそらくはキャッシュ・ミスを暗示する、メモリ読み取り、
（ｉｖ）メモリ書き込み、
（ｖ）メモリへの書き込みパイプラインのフラッシング、および
（ｖｉ）バスのアンロッキング
を実行することを必要とするためである。
【００６０】
このすべては、他のものがスレッド・コア内（現在または他のコア内）でいかなるメモリ・アクセスを行うことも妨げられている間、その結果、おそらくは完全にブロックされる。他のＣＰＵ実装（ＡＲＭ（Ｒ）、Ｉｔａｎｉｕｍ（Ｒ）、ＰＡ  ＲＩＳＣ（Ｒ）、ＰＯＷＥＲ（Ｒ）、ＳＰＡＲＣ（Ｒ））は、僅かに異なる要件を有するが、コストが掛かることはまったく同じである。
【００６１】
本発明の実施形態は、ロック要求者プリエンプション（ＬＲＰ）問題を免れており、ＬＲＰによって影響されない場合に前記公平ロックと同等の性能を提供する、（Ｌｉｎｕｘオペレーティング・システムによって使用される「チケット」などの）公平な非リスト・ビジー・ロックの直接的な代用物を提供する。
【００６２】
図６および図７を参照して上で説明された、「プリエンプタブル・ロック」アルゴリズムでは、ＬＲＰ事例を検出することができるように、ロック要求者またはアンロック操作のすべてに、プリエンプタブル・ロックを形成する２つのロックの各々を毎回経験させることは、前記ＬＲＰ検出の利点を打ち消す。
【００６３】
本発明の実施形態は、各ロック要求におけるアルゴリズムのコストを最小化し、ＬＲＰ検出の負担のほとんどを、ロックを獲得するために待機している間は実際の作業を行わずに依然としてループしている、後のスレッドに移す。
【００６４】
図８は、共有リソース８１２を制御するロック８１０にアクセスすることを望んでいる複数のスレッド（現在のロック・オーナ８０２、次のロック・オーナ８０４、以降のロック・オーナ８０８）を有する、本発明の実施形態のブロック図を示している。ロック８１０は、lock.ticket構造８１４を含み、それは、従来のロックにおいて使用される従来のチケット構造であり、当業者によく知られている。現在のロック・オーナ８０２は、ロック８１０を現在「所有」し、ロック８１０を通した共有リソース８１２への排他的アクセスを有する、スレッドである。次のロック・オーナ８０４は、ロック８１０を通して共有リソース８１２にアクセスすることを望んでいる、スレッドの順序付けられたセットにおける次のスレッドである。以降のロック・オーナ８０８は、やはりロック８１０を通して共有リソース８１２にアクセスすることを望んでいるが、スレッドの順序付けられたセットにおいてさらに下位にある、さらなるスレッドである。テスト・アンド・セット、チケット、および本発明の実施形態などの非リスト・ロックでは、ロック要求者は、それらの前または後に他のスレッドが存在することについての知識を有することができるが、ロック要求者は、これらのスレッドがどれであるかを見ることはできない。リスト・ロックでは、１つのスレッドと次のスレッドとの間に直接的なリンクが存在する。
【００６５】
本発明の実施形態では、ロック８１０は、lock.displayユニオン８１６をさらに含む。これは、ロック８１０の請求者（次のロック・オーナ）８０４が、それらのチケットを用いてロック８１０に署名し、使用中であるとしてロック８１０を印付け、その結果、それらの請求をロック８１０に公表することを可能にする、状態情報をストアすることができる。ロック８１０の請求者（次のロック・オーナ）８０４は、ロック８１０を使用するために、それが列における次のスレッド（次のロック・オーナ）８０４である場合、それのチケットを用いてロックに署名する。それは、detail.taken９１８内の高位ビットを設定することによって、使用中であるとしてロック８１０を印付けもする。ロック８１０内のlock.displayユニオン８１６を操作する前に、次のロック・オーナ８０４は、lock.displayユニオン８１６のコピーを作成し、それを次のロック・オーナ８０４によって所有される記憶域内にdisplay構造８０６としてストアする。
【００６６】
図９は、図８のlock.displayユニオン８１６をより詳細に示している。lock.displayユニオン８１６は、lock.display.detail９２４を含み、それが、detail.taken９１８およびdetail.turn９２０を含む。detail.turn９２０は、現在ロック８１０を請求しているが、所有していない、スレッド（次のロック・オーナ８０４）のチケット番号である。detail.taken９１８は、次のロック・オーナ８０４によって、それがロックを請求していることを示すために使用される、インジケータである。lock.displayユニオン８１６を読み取った他のスレッドは、detail.taken９１８から、ロックが別のスレッドによって請求されていること、およびdetail.turn９２０から、ロックを請求しているスレッドのチケット番号を決定することができる。
【００６７】
lock.displayユニオン８１６は、ユニオンとして実施される。lock.displayユニオン８１６全体が、単一命令で読み取られ、または書き込まれる必要があるので、lock.displayユニオン８１６を実施するためのユニオンの使用は、本発明に従って実施されるロック８１０にとって重要である。ユニオンは、複数の要素によって共有される記憶空間であり、個々のエントリの各々に割り当てられた空間を有する記憶域である構造とは異なる。ユニオンは、構造と同じフォーマットおよびオペレータを有する。各データ・メンバに対してメモリの別々のチャンクを予約する構造とは異なり、ユニオンは、最大のデータ・メンバを収容するのに十分なメモリを割り当てるだけである。ユニオンでは、データ・メンバは、オーバーレイし、またはメモリを共有し、ユニオンは、異なるタイプとしてメンバにアクセスすることができる。図９では、display.detail９２４とdisplay.block９２２は、同じメモリ空間（lock.displayユニオン）８１６を共有する。次に、display.detail９２４は、detail.taken９１８およびdetail.turn９２０を含む構造である。本発明の実施形態では、display.block９２２が、読み取られ、detail.taken９１８とdetail.turn９２０は、同じ命令内でデータ投入される。反対に、display.block９２２に書き込むことによって、detail.taken９１８とdetail.turn９２０は、単一命令内で書き込まれる。display.block９２２は、detail.taken９１８およびdetail.turn９２０のための導管としての役割を果たすにすぎない。
【００６８】
上で言及されたように、lock.displayユニオン８１６全体は、単一命令で読み取られ、または書き込まれる必要がある。この制限の理由は、detail.taken９１８およびdetail.turn９２０が、一貫性のある方法で操作されなければならないためである。lock.displayユニオン８１６を読み取り、またはlock.displayユニオン８１６に書き込むために、２つの別々の命令が使用された場合、別のＣＰＵ上で動作している別のロッカが、detail.taken９１８を、現在のロッカがそれを読み取り、または操作した後には、操作しないが、それがdetail.turn９２０を読み取り、または操作する機会を有する前も同様であることの保証がなくなる。
【００６９】
本発明の実施形態は、各ロック８１０の要求においてアルゴリズムのコストの最小化を達成し、次のロック・オーナ８０４に
（ｉ）かなりより安価な非アトミック操作を使用することによって、それがロック８１０を請求している旨のフラグを立てること、
（ｉｉ）それがプリエンプトされていないことをチェックすること、および
（ｉｉｉ）プリエンプトされている場合は、lock.ticket構造８１４の獲得を再び試みること
を行わせることによって、ロックを獲得するのを待機して依然としてループしている後のスレッド（次のロック・オーナ８０４、以降のロック・オーナ８０８）に、ＬＲＰ検出の負担を移す。
【００７０】
これは、ロック８１０のアルゴリズムのコストの大部分、すなわち、プリエンプトされたスレッドの検出および不公平なロック獲得を、lock.ticket構造８１４を獲得するのを依然として待機しているスレッド（次のロック・オーナ８０４、以降のロック・オーナ８０８）によって使用されるループ内に置く。これは、以下のことを意味する。
（ｉ）後のスレッド（次のロック・オーナ８０４、以降のロック・オーナ８０８）は、ループしてビジーであり、したがって、何も有益なことはしていないので、それらは、全体的な性能に影響せずに、コンボイをチェックし、それを防止することができる。
（ｉｉ）チケット・アルゴリズムについての先の「ロング・スピン」グラフである、図４の特定の例を参照すると、より悪いケースでは、９０００万のロック要求に対して１８万回のロング・スピン（すなわち、ロック要求者プリエンプション）が存在する。アルゴリズム・コストの全体が、プリエンプションだけに移される場合、先に説明されたコストが掛かる活動は、１億８０００万当たり１８万回、すなわち、すべてのロック要求の０．１％だけ行われ、したがって、追加のコストのほぼ全部を省く。図４の特定の例の変形は、異なる数値をもたらすが、同じ原理が適用される。
【００７１】
これは、ＣＬＨ−ＴＰアルゴリズム、すなわち、活動がない場合にスレッドがロック８１０のリストから先行スレッドを除去するアルゴリズムで使用されるが、非リスト・ロックに適用される技法に類似しているように思えるかもしれないが、本発明の実施形態は、ＣＬＨ−ＴＰアルゴリズムとは、重要な方法において異なる。
【００７２】
ＣＬＨ−ＴＰアルゴリズムでは、１つのスレッドが立ち往生し、次のスレッドがそれを検出した場合、次のスレッドは、先行スレッドのロック要求を待ち行列から除去する。これは、少し単純化されているが、基本的に、スレッド・プリエンプションの処理に関与する当事者は２つだけしか存在せず、プリエンプトされたスレッドと後続スレッドである。２つ以上のスレッドがプリエンプトされた場合、次のスレッドは、単に、ゆっくりではあるが（スレッドのリストの操作はコストが掛かる）、確実に、待ち行列内で前進する。
【００７３】
非リスト・ロック・アルゴリズムでは、すべてのスレッド（現在のロック・オーナ８０２、次のロック・オーナ８０４、以降のロック・オーナ８０８）がその上で動作するロック８１０は、ただ１つしか存在せず、したがって、プリエンプトされたロック・オーナを検出したスレッドは、プリエンプトされたスレッドをロックから物理的に除去することができない。
【００７４】
プリエンプトされたロック・オーナを検出したスレッドがすることができる唯一のことは、自らロック８１０獲得し、プリエンプトされたスレッドがひとたび動作を再開したならば、それがプリエンプトされていたこと、それのチケットがもはや有効でないことを検出するために、プリエンプトされたスレッドに頼り、その後、再び最初からロックの獲得に着手することである。プリエンプトされたロック・オーナを検出したスレッドがそうすることに失敗すると、制御された共有リソース８１２に２つのスレッドが同時にアクセスする事態が生じる。それの回避がロックの存在の全理由であるそのような事態は、「衝突」として知られている。
【００７５】
これは、いくつかの種類の状態にある複数のスレッド、すなわち、
１．ロックの解放に着手している、現在のロック・オーナ８０２、
２．使用中としてロックを印付けようと試みている、次のロック・オーナ８０４、
３．プリエンプトされており、自らが他のスレッドによって追い越されるのを今見出している、スレッド、
４．使用中としてロックを印付けることができる前にプリエンプトされた、動作を今再開しようとしており、潜在的に誤って使用中であるとロックを印付けることがあり得る（衝突をもたらす）、古い次のロック・オーナ、
５．次のロック・オーナがプリエンプトされているかどうかをチェックしている、順番が次のスレッド、
６．待ち行列を飛び越して、自らが使用中であるとロックを印付けることができる前にプリエンプトされた、動作を今再開しようとしており、潜在的に待ち行列を飛び越し、誤って使用中であるとロックを印付けることがあり得る（これも衝突をもたらすことがあり得る）、順番が次の古いスレッド
が、すべて同時にロックを変更しようと試みていることがあり得る、はるかに複雑な環境をもたらす。
【００７６】
これらの複数のスレッドの各々は、自らまたは他のスレッドの統制から外れた状態を検出するための技法を利用しなければならず、衝突および可能性がある立ち往生を回避するために、これに対処することができなければならない。２つのスレッドが同時にロック８１０を解放しようと試みる場合、ロック８１０は、チケットが失われるような状態に陥ることがあり得る。これが起こり、スレッドがＬＲＰの発生を検出することができない場合、他のスレッドは、ロック８１０を獲得することができない。
【００７７】
この状況を回避するために、本発明の実施形態では、チケット構造が、次のチケットのマシンおよび現在のdetail.turn９２０ばかりでなく、ロック請求者がそれらのチケットを用いてロックに署名し、使用中としてロックを印付けることができる、ロック状態（lock.displayユニオン）８１６も有するように拡張される。
【００７８】
ロックが解放されるといつでも（上記の状態番号１）、detail.turn９２０は、通常通りインクリメントされ、ロック状態は、「未請求」および最後に使用されたチケットの識別情報になるように設定される。この知られた状態の組合せは、待機者スレッドがプリエンプションを検出することを可能にし、以下で説明される。
【００７９】
本発明によるチケット・ベース・アルゴリズムの実施形態の高レベル実施が、今から説明される。その実施は、１６ビットのチケットを使用し、「taken」フィールドの１ビット内にロック・ステータス（請求済／未請求）を符号化する。その実施についての疑似コードが、以下に示されており、それは、図１０から図１５および図１６を参照して説明されもする。疑似コード内の行番号は、図１０から図１５および図１６内の参照番号に対応する。
【００８０】
union display_t ::=
struct detail
{
short turn;
short taken;
};
int block;
LOAD_DISPLAY(source, dest) ::= dest.block = source.block
bb_lock_t ::=
volatile short ticket;
volatile display_t display;
bb_lock(bb_lock_t lock) ::=
begin 1
display_t display
1002    監視タイムアウトを初期化する
1004    ターゲット・チケットを取得して、lock.ticketをアトミックにインクリメントする
repeat forever
begin 2
1006      LOAD_DISPLAY(lock.display,display)
1008      display.detail.turnとターゲット・チケットとの間の距離を計算する
1010／12  if 距離が０よりも小さい, or 距離が古い距離値よりも大きい, スレッドはプリエンプトされている
＜１００２＞から再び開始する
1014／16  else if 距離が０である, スレッドは次のロック・オーナである
begin 3
1018        lock.display.detail.takenをターゲット・チケットになるように設定し、さらに、ロックが請求されていることを伝えるために、高位ビットを設定する
1022        現在のチケットをメモリからロードする
if 現在のチケットがターゲット・チケットと一致する, then 他のロック要求者は存在しない:
ロックが安全に獲得された, exit
// メモリ・モデルが因果的である場合に、このステップを実行する
1032        LOAD_DISPLAY(lock.display,display)
// メモリ・モデルが因果的でない場合に、次の２つのステップを実行する
1034        ストア−ロード・バリア（store-load barrier）を通して、lock.display.detail.takenに書き込みが行われるのを待機する
1036        lock.display.detail.turnを再び読み取る
1038／40    if display.detail.turnがターゲットと一致する, ロックが安全に獲得されている
1042          exit
else
スレッドはプリエンプトされている, ＜１００２＞から再び開始する
end 3 // 距離が０の場合
1044／46  else if 距離が１である and タイムアウト・チェッキングがオンにされている
begin 4
1048／50    if display.detail.takenが次のロックと一致し、さらに、高位ビットが設定されている, 次のオーナがロックを請求している
1052          タイムアウト・チェッキングをオフにする
1054        else ifdisplay.detail.takenが予想外の値を有する, プリエンプトされたスレッドがdisplayに走り書きした
1056          タイムアウト・チェッキングをオフにする
1058／62    else if display.detail.takenが（ターゲット・チケット−１）と一致し、さらに、高位ビットがクリアされている, 次のロック・オーナがロックをまだ請求していない
begin 5
1064          監視タイムアウトをデクリメントする
1066          if監視タイムアウトが０である
begin 6
1068            監視を使用不可にする
1070            新しいdisplay.block値を、１）ターゲット・チケットになるように設定されたturn、２）ターゲット・チケットになるように設定されたtaken、さらに、設定された高位ビットとして組み立てる
1072            新しいdisplay.block値をlock.display.blockとアトミックに比較し、スワップする
1076            if比較およびスワップの結果が古いdisplayと一致する, ロックが取得される
1078              exit
end 6 // 監視タイムアウトが満了した場合
end 5 // displayが先行ロック・オーナと一致し、ロックが取得されない
end 4// 距離が１であり、タイムアウト・チェッキングがオンにされている場合
end 2 // repeat forever
end 1// bb_lock
bb_unlock(bb_lock_t lock) ::=
begin
display_t display
1102    LOAD_DISPLAY(lock.display,display)
1104    ロックが取得されていないことを伝えるために、display.detail.takenを高位ビットがクリアされたdisplay.detail.turnになるように設定する
1106    display.detail.turnをインクリメントする
1108    LOAD_DISPLAY(display,lock.display)
1110  end
【００８１】
図１０を参照すると、本発明の実施形態では、ステップ１０００において、ロック獲得が、開始される（上記の状態番号２）。ステップ１００２からステップ１０７４は、上記の状態番号２にあるスレッド（次のロック・オーナ）８０４が、ロック８１０の獲得を試みている間に実行するループを表し、それは、ロック８１０のためのチケットの獲得で開始し、ロック８１０の獲得で終了する。ステップ１００２において、監視タイムアウトが、初期化される。監視タイムアウトは、ロックを不公平に獲得しようと試みる前に待機するループの回数である。ステップ１００４において、ターゲット・チケットが、獲得され、lock.ticket構造８１４が、アトミックにインクリメントされる。
【００８２】
ステップ１００６からステップ１０７４は、スレッドが、ロック８１０の獲得を試みている間に実行するループを表し、それは、ロック８１０のための先に獲得されたチケットで開始し、ロック８１０の獲得で終了する。ステップ１００６において、lock.displayユニオン８１６が、単一メモリ・アクセスを使用して、ロック８１０から次のロック・オーナ８０４にコピーされる。上で言及されたように、単一メモリ・アクセスが使用されること、ならびに上で説明された実施では、detail.turn９２０およびdetail.taken９１８からなるdetail構造９２４との間のユニオンが使用されることは、必須である。コピーされたlock.displayユニオンは、図８において、display構造８０６として示されている。方法は、今では、ビジーに移行し、detail.turn９２０が、ターゲット・チケットを示すのを待機する。
【００８３】
ステップ１００８において、ターゲット・チケットとlock display、すなわち、「display.detail.turn」との間の現在の距離が、計算される。距離が０よりも小さい場合、このスレッドは、プリエンプトされており、図８に以降のロック・オーナ８０８として示された他のスレッドによって飛び越される。スレッドは、
（ｉ）最初から再スタートすること、すなわち、処理がステップ１００２に戻ること、または
（ｉｉ）ロックを獲得することをまったく断念すること
を必要とする。
【００８４】
ステップ１０１０において、距離が０以上である場合、処理は、ステップ１０１２に進む。ステップ１０１２において、距離が距離の先の値よりも大きい場合、このスレッドは、プリエンプトされており、図８に以降のロック・オーナ８０８として示された他のスレッドによって飛び越される。上で説明されたように、スレッドは、
（ｉ）最初から再スタートすること、すなわち、処理がステップ１００２に戻ること、または
（ｉｉ）ロックを獲得することをまったく断念すること
を必要とする。
【００８５】
ステップ１０１２において、距離が先の値以下である場合、処理は、接続子「Ａ」を通って、図１１のステップ１０１４に進む。図１１を参照すると、ステップ１０１４において、距離が０に等しくない場合、処理は、接続子「Ｂ」を通って、図１３のステップ１０４４に進む。ステップ１０１４において、距離が０に等しい場合、ステップ１０１６において、スレッドは、次のロック・オーナとして識別される。
【００８６】
ステップ１０１８において、スレッドは、lock.displayユニオン８１６内のdetail.taken９１８をターゲット・チケットになるように設定して、ロックを請求しているスレッドとして、それの識別情報を示し、または公表する。スレッドは、lock.displayユニオン８１６内のdetail.taken９１８の高位ビットを設定して、ロック８１０が請求されていることも示す。これは、ロック８１０内のlock.display.detail.blockが、スレッド内のdisplay.detail.blockとアトミックに比較され、スワップされることによって、達成することができる。しかしながら、性能に関して、これは、非常に高価である。ステップ１０１８において、アトミック比較およびスワップを使用する代わりに、ステップ１０１８からステップ１０３８において、非アトミック操作が使用される。detail.taken９１８をターゲット・チケットになるように設定すること、およびdetail.taken９１８の高位ビットを設定することは、別々の操作として説明されているが、それらは、１つの操作内で組み合わされなければならない。detail.taken９１８の高位ビットの使用は、ロック８１０が請求されている旨のインジケータとして説明されたが、他の任意のインジケータが使用されてもよく、しかしながら、detail.turn９２０、detail.taken９１８、およびインジケータが、単一メモリ・アクセスで更新されなければならないことは必須である。それらが、かりに別個のメモリ・アクセスで更新されたとしたら、セット内の次のスレッド（以降のロック・オーナ）８０８が、請求されていないものとしてロック８１０を見て、その結果、盗用操作を開始する、機会の窓が生じる。
【００８７】
プリエンプトされたスレッドがロック状態に走り書きすることを可能にすることは、ロック８１０の各獲得において、コストが高いアトミック操作を回避する。アトミック比較およびスワップ操作によって走り書きを妨げることは、アルゴリズムの性能が、プリエンプタブル・ロックと比べて、おそらく約１５％の限定された改善しか示さないことを意味する。実施形態では、ストア−ロード・バリア、すなわち、プリエンプトされており、他のスレッドによって自らが追い越されるのを見出すスレッドによる書き込みが、使用中としてロックを印付けることができる前にプリエンプトされた、動作を今再開しようとしており、潜在的に誤って使用中であるとロックを印付けすることがあり得る、古い次のロック・オーナによる読み取りの前に、確実にメモリに公表されるようにするバリアが、生じる。
【００８８】
ストア−ロード・バリアは、性能に関して、きわめて高価になりがちであり、フル・バリア（fullbarrier）、すなわち、いかなるメモリ命令並べ替えも妨げる、またはロード−ロード、ロード−ストア、ストア−ロード、およびストア−ストアを一緒にしたすべての組合せを妨げるバリアに次いで第２位である。しかしながら、ストア−ロード・バリアは、すべてのプラットフォームで利用可能ではなく、フル・バリアは、利用可能な代用物であるにすぎない。フル・バリアだけが利用可能である場合、適切なロード命令並べ替えを通して、ストア−ロード・バリアをシミュレートすることが可能なことがある。例えば、ｘ８６プラットフォームでは、メモリ・モデルは、因果的であり、それは、同じロケーションへのストアの後に続くロードが、先にストアされた値を再読し得るためには、ストアが完了するのを待機しなければならないことを意味する。そのようなプラットフォームでは、先に説明されたように、単一ロード命令でのロック状態およびturn displayの再読は、ロードに着手する前に、ストア命令が完了するのを待機しなければならず、それは、実際のメモリ・バリア（memory barrier）またはアトミック命令のコストの一部分で、バリアを実施する効果を有する。
【００８９】
アルゴリズムは、先に進む前に、ＣＰＵが書き込みを完了するのを待機しなければならないので、この書き込みを待機している間に、すなわち、ストア−ロード・バリアを実行する前に、いくつかの最適化を、基本的にコストをかけずに実行することができる。実施形態では、次のオーナ・スレッドのターゲット・チケットを、現在のチケットと比較することができる。２つが一致した場合、プリエンプションについて監視しているスレッドは存在しない。これが暗示することは、ある条件付きで、次のオーナ・スレッドが、ストア−ロード・バリアを実行することなく、安全に脱出することができることである。このテストの実行は、待機者が存在する場合は、基本的にコストをかけずに生じるが、それは、現在のチケットのロードおよび比較は、ロック状態が走り書きされているのと同時に生じるからである。バリア命令単独、または一連のロード、テスト、およびバリアの総実行時間は、同じ時間を要する。
【００９０】
上で説明された最適化は、ｘ８６またはＳｐａｒｃなど、書き込みが同時にすべてのコアから大域的に見えるプラットフォームにおいて、安全に適用することができる。十分に大きい監視遅延を使用することによって、ロック状態がＣＰＵの他のコアに公表されたかなり後まで、ロックを不公平に獲得しようとする試みが存在しないことを保証することが可能である。これは、待機中スレッドが１つの完全な待機ループを経験するのに要したクロック・サイクルを計算することによって、達成することができる（これは、プラットフォーム固有である）。この数に監視タイムアウトを乗じた数が、バリア命令が要するクロック・サイクルよりもはるかに大きい場合、次のオーナ・スレッドは、かりに次の待機者がロック８１０を獲得しようと試みたとしても、それがロック８１０を不公平に獲得しようと試みるかなり前に、ロック状態がこの新しいスレッドに公表されることを確信することができる。
【００９１】
ステップ１０２２からステップ１０３８は、スレッド（次のロック・オーナ）８０４が、ロック８１０の所有権を求めるそれの請求が成功したことを調べるチェックを行う場合に取られるステップを表す。ステップ１０２２において、現在のチケットが、メモリからロードされる。ステップ１０２４において、現在のチケットがターゲット・チケットと一致するかどうかに関するチェックが行われる。現在のチケットがターゲット・チケットと一致する場合、ステップ１０２６において、他のロック要求者が存在せず、ロックが安全に獲得されたことが確かめられる。処理は、ステップ１０２８において終了する。現在のチケットがターゲット・チケットと一致しない場合、処理は、接続子「Ｃ」を通って、図１２のステップ１０３０に進む。
【００９２】
図１２を参照すると、ステップ１０３０において、メモリ・モデルが因果的かどうかに関するチェックが行われる。例えば、ｘ８６シリーズのプロセッサは、因果的なメモリ・モデルを使用し、ＰＯＷＥＲ（Ｒ）シリーズのプロセッサは、非因果的なメモリ・モデルを使用する。潜在的に因果的に関係するメモリ操作が、システムのどのノードによっても、同じ順序で見られる場合、メモリ・モデルは因果的である。ノードが、読み取りと、その後に続く書き込みを実行する場合、それらが異なる変数上でのものでも、書き込みによってストアされる値は、読み取りの結果に依存することがあるので、第１の操作は、第２の操作の前に因果的に順序付けられていると言われる。同様に、読み取り操作は、読み取りによって取り出されるデータをストアした、同じ変数上での先行する書き込みの後に因果的に順序付けられている。潜在的に因果的に関係するメモリ操作が、システムのどのノードによっても、同じ順序で見られるとは限らない場合、メモリ・モデルは因果的ではない。
【００９３】
システムのためのメモリ・モデルは、本発明の方法の実行の前に知られ、そのため、ステップ１０３０は、一般に、方法がプロセッサによる実行のためにコンパイルされる時に、事前決定することができる。実施形態では、ステップ１０３０は、それが因果的なメモリ・モデルを使用してプロセッサ上で動作しているかどうかに関する表示をチェックすることから成ることができる。別の実施形態では、コンパイルされたコンピュータ・プログラムは、ステップ１０３０の実施を含まないことがあり、メモリ・モデルが因果的であるかどうかに応じて、ステップ１０３２の実施、またはステップ１０３４およびステップ１０３６の実施を含むことができる。
【００９４】
メモリ・モデルが因果的である場合、ステップ１０３２において、lock.displayユニオン８１６が、ロック８１０からスレッド（次のロック・オーナ）８０４に、単一メモリ・アクセスでコピーされる。これは、lock.display.detail.blockから読み取り、display.detail.blockに書き込む、単一操作によって達成される。処理は、ステップ１０３８に進む。
【００９５】
メモリ・モデルが因果的でない場合、ステップ１０３４において、スレッドは、ストア−ロード・バリアを使用して、detail.taken９１８に書き込みが行われるのを待機しなければならない。ストア−ロード・バリアは、バリアの前に実行されたすべてのストアが、他のノードから見えること、およびバリアの後に実行されたすべてのロードが、バリアの時点で見える最新の値を受け取ることを保証する。言い換えると、それは、実際上、バリアの後のすべてのロードに対して、バリアの前のすべてのストアの並べ替えを妨げる。ストア−ロード・バリアを通してdetail.taken９１８に書き込みが行われた場合、ステップ１０３６において、detail.turn９２０が、再び読み取られる。処理は、ステップ１０３８に進む。
【００９６】
ステップ１０３８において、現在のチケット（detail.turn）９２０がターゲット・チケットと一致するかどうかに関するチェックが行われる。現在のチケット（detail.turn）９２０がターゲット・チケットと一致する場合、ステップ１０４０において、ロックが、安全に獲得されており、スレッド（次のロック・オーナ）８０４は、ロック８１０によって制御される共有リソース８１２の操作に着手することができる。処理は、ステップ１０４２において終了する。現在のチケット（detail.turn）９２０がターゲット・チケットと一致しない場合、このスレッドは、プリエンプトされており、図８に以降のロック・オーナ８０８として示された他のスレッドによって飛び越される。スレッドは、
（ｉ）最初から再スタートすること、すなわち、処理が、接続子「Ｄ」を通って、図１０のステップ１００２に戻ること、または
（ｉｉ）ロックを獲得することをまったく断念すること
を必要とする。
【００９７】
図１１のステップ１０１４において、距離が０に等しくない場合、処理は、接続子「Ｂ」を通って、図１３のステップ１０４４に進む。ここで図１３を参照すると、ステップ１０４４において、距離が１に等しくない場合、処理は、接続子「Ｅ」を通って、図１０のステップ１００６に戻る。距離が１に等しくない場合、それは、スレッドがロックの獲得を待機しながらまだループしているが、このスレッドの前に他のスレッドが存在することを意味する。スレッドは、今は、ロックの獲得を待機しながら、スレッドのセット内におけるそれの位置を監視することを続ける。ステップ１０４４において、距離が１に等しい場合、ステップ１０４６において、タイムアウト・チェッキングが使用可能かどうかに関するチェックが行われる。タイムアウト・チェッキングが使用可能でない場合、処理は、接続子「Ｅ」を通って、図１０のステップ１００６に戻る。やはり、それは、スレッドがロックの獲得を待機しながらまだループしているが、このスレッドの前に他のスレッドが存在することを意味する。スレッドは、今は、ロックの獲得を待機しながら、スレッドのセット内におけるそれの位置を監視することを続ける。ステップ１０４６において、タイムアウト・チェッキングが使用可能である場合、処理は、ステップ１０４８に進む。
【００９８】
ステップ１０４４において、１と、１よりも大きい、２、３、または４以上などの数との間の距離についてのチェックを行うことができる。これは、２つ以上のスレッドが、lock.displayユニオン８１６のそのステータスを監視することを可能にする。これは、より多くのスレッドが、ロックを不公平に獲得する機会に同時に飛び付くことを可能にし、それによって、待機スレッドの全起動をトリガするという不都合を有する。そのような不都合は、各待機中スレッドに、スレッドのセットにおけるそれの位置に比例した監視タイムアウトを使用させることによって、回避することができる。しかしながら、これは、複数のスレッドが、最初からロック８１０を再獲得しなければならないことを意味し、それは、ロック８１０のスループットに影響し得る。実際には、距離を１に限定すること、すなわち、監視スレッドの数を１に限定することは、ＬＲＰの防止にいかなる負の影響も有せず、待機スレッドの全起動を回避する。
【００９９】
ステップ１０４８からステップ１０７４は、スレッド（次のロック・オーナ）８０４の後に続くスレッドによって実施される、スレッド（次のロック・オーナ）８０４がロック８１０を実際に請求していることを調べるための監視を行うステップと、スレッド（次のロック・オーナ）８０４がロック８１０を請求していない場合、ロックを不公平に請求するステップとを表す。ステップ１０４８において、ロックの次のオーナがプリエンプトされているかどうかを判定するために、detail.taken９１８が次のロック要求者と一致するかどうかに関するチェックが行われる。detail.taken９１８が、ステップ１００６において単一命令でdetail.taken９１８として読み取られた、次のロック要求者と一致する場合、処理は、ステップ１０５０に進む。detail.taken９１８が、次のロック要求者と一致しない場合、detail.taken９１８は、統制から外れたプリエンプトされたスレッドによって走り書きされており、それはランダムな値を含むので、detail.taken９１８の値に基づいた判定を行うことはできない。このスレッドは、それのチケットを用いてdetail.taken９１８に書き込みを行うことに成功しなかったので、処理は、ステップ１０５４に進む。
【０１００】
ステップ１０５０において、detail.taken９１８の高位ビットが設定されているかどうかのチェックが行われる。detail.taken９１８の高位ビットが設定されている場合、スレッド（次のロック・オーナ）８０４は、ロックの請求に成功しており、処理は、ステップ１０５２に移る。detail.taken９１８が次のロック要求者、すなわち、スレッド（次のロック・オーナ）８０４と一致し（ステップ１０４８においてチェックされる）、detail.taken９１８の高位ビットが設定されている（ステップ１０５０においてチェックされる）場合、処理は、ステップ１０５２に到達し、それは、このスレッドがロックの請求に成功したことを意味する。ステップ１０５２において、タイムアウト・チェッキングが、使用不可にされる。次のオーナが、ロックの請求に成功した場合、次のオーナは、現在の所有スレッド（現在のロック・オーナ）８０２がロックを解放したときに、ロックの獲得が完了するのを待機しながらループを続行する。ロック８１０の監視は、停止することができる。
【０１０１】
detail.taken９１８の高位ビットが設定されていない場合、次のロック・オーナ８０４は、ロック８１０をまだ請求しておらず、処理は、ステップ１０５４に移る。detail.taken９１８が次のロック要求者と一致せず（ステップ１０４８においてチェックされる）、またはdetail.taken９１８の高位ビットが設定されていない（ステップ１０５０においてチェックされる）場合、処理は、ステップ１０５４に到達し、それは、次のオーナがロックの請求に成功していないことを意味する。ステップ１０５４において、detail.taken９１８が予想外の値を有するかどうかに関するチェックが行われる。detail.taken９１８が予想外の値を有する場合、処理は、接続子「Ｆ」を通って、図１４のステップ１０５６に進む。detail.taken９１８が予想外の値を有しない場合、処理は、接続子「Ｇ」を通って、図１４のステップ１０５８に進む。
【０１０２】
detail.taken９１８が予想外の値を有する場合、処理は、ステップ１０５６に到達する。これは、プリエンプトされたスレッドが、detail.taken９１８に走り書きした、またはもはや現在のものではなく、したがって、正しくないスレッド情報を用いて、上書きしたためである。ロック８１０に走り書きした２つ以上のプリエンプトされたスレッドが、存在し得る。ステップ１０５６において、タイムアウト・チェッキングが、使用不可にされる。やはり、それは、スレッドがロック８１０の獲得を待機しながらまだループしているが、このスレッドの前に他のスレッドが存在することを意味する。スレッドは、今は、ロックの獲得を待機しながら、スレッドのセット内におけるそれの位置を監視することを続ける。
【０１０３】
turn displayカウンタが、例えば、１６ビット整数で提供することができるのと正確に同じロック要求の数、６５５３６の間、スレッドがプリエンプトされ得る、きわめて不都合なケースが存在する。これは、不公平な請求が発生するたびにインクリメントされ、スレッドがプリエンプトされているかどうかを判定するために、読み取りもそれをチェックすることができる、不公平請求カウンタも、turn display／状態ユニオンに含ませることによって、回避することができる。
【０１０４】
ステップ１０５８において、detail.taken９１８が（ターゲット・チケット−１）と一致するかどうか、および高位ビットがクリアされているかどうかに関するチェックが行われる。detail.taken９１８が（ターゲット・チケット−１）と一致し、高位ビットがクリアされている場合、それは、セット内のこのスレッドの直前のスレッドが、ロック８１０を請求するべきであるが、まだそうしていないことを意味する。このスレッドの直前のスレッドは、（ターゲット・チケット−１）のチケット番号を有し、高位ビットを設定することによってロックを請求することをまだ行っていない。
【０１０５】
detail.taken９１８が（ターゲット・チケット−１）と一致しない場合、または高位ビットがクリアされていない場合、スレッドは、今は、ロック８１０の獲得を待機しながら、スレッドのセット内におけるそれの位置を監視することを続ける。処理は、接続子「Ｅ」を通って、図１０のステップ１００６に戻る。
【０１０６】
detail.taken９１８が（ターゲット・チケット−１）と一致し、detail.taken９１８の高位ビットがクリアされている場合、処理は、ステップ１０６２に到達し、それは、次のオーナがロックをまだ請求していないことを意味する。
【０１０７】
ステップ１０６４からステップ１０７４は、距離が先行ロック・オーナの距離と一致し、ロック８１０が取得されていない場合に、スレッド（次のロック・オーナ）８０４が実施するステップを表す。ステップ１０６４において、監視タイムアウトが、デクリメントされる。ステップ１０６６において、監視タイムアウトが経過したかどうかに関するチェックが行われる。監視タイムアウトが経過した場合、処理は、ステップ１０６８に移る。監視タイムアウトが経過していない場合、それは、次のロック・オーナ８０４がロック８１０を請求するための時間をまだ有することを意味する。スレッドは、今は、ロック８１０の獲得を待機しながら、スレッドのセット内におけるそれの位置を監視することを続ける。処理は、接続子「Ｅ」を通って、図１０のステップ１００６に戻る。監視タイムアウトが経過した場合、処理は、ステップ１０６８に到達する。ステップ１０６８において、監視が、使用不可にされる。処理は、接続子「Ｈ」を通って、図１５のステップ１０７０に進む。
【０１０８】
図１５を参照すると、スレッドは、ロック状態を「請求済」に、請求者ｉｄをそれが所有するターゲット・チケットに、detail.turn９２０をそれが所有するターゲット・チケットになるように設定しようと試みる。この操作が成功した場合、スレッド（次のロック・オーナ）８０４は、ロック８１０を不公平に獲得し、プリエンプトされたスレッドを飛び越す。これは、待ち行列を飛び越し、自ら使用中であるとしてロック８１０を印付けることができるようになる前にプリエンプトされた、古い次のスレッドが、動作を今再開しようとしており、潜在的に待ち行列を飛び越し、誤って使用中であるとロック８１０を印付けることがあり得るときに、生じることがあり、それは、衝突をもたらし得る。
【０１０９】
新しいdisplay.block９２２が、ターゲット・チケットになるように設定されたdetail.turn、ターゲット・チケットになるように設定されたdetail.taken９１８、および設定されたdetail.takenの高位ビットを用いて、組み立てられる。新しいdisplay.block９２２は、ローカルdisplay変数内の盗用者のturn、シグネチャ、およびtakenフラグを表す。ステップ１０７２において、新しいdisplay.detail.block.valueが、lock.display.detail.blockとアトミックに比較され、スワップされる。
【０１１０】
アトミック比較およびスワップ命令は、
（ｉ）それが書き込もうと意図するメモリ・ロケーション、
（ｉｉ）それが書き込もうと意図する値、および
（ｉｉｉ）メモリ・ロケーションにおいて見出されることが予想される値
という３つの引数を取る。アトミック比較およびスワップ命令は、その後、
（ｉ）バスをロックし、それによって、他のＣＰＵからのメモリ操作を防止すること、
（ｉｉ）第１の引数で識別されるメモリ・ロケーションから値を読み取ること、および
（ｉｉｉ）それを第３の引数の値と比較すること
に着手する。第１の引数で識別されるメモリ・ロケーションから読み取られた値が、第３の引数の値と一致する場合、第２の引数の値が、第１の引数で識別されるメモリ・ロケーションに書き込まれる。第１の引数で識別されるメモリ・ロケーションから読み取られた値が、第３の引数の値と一致しない場合、第１の引数で識別されるメモリ・ロケーション内の値は、変更されずに残される。最後に、バスが、解放される。命令によって返される結果は、第１の引数で識別されるメモリ・ロケーションから読み取られた古い値である。第１の引数で識別されるメモリ・ロケーションから読み取られた値が第３の引数の値と一致する場合に限って、第２の引数の値が第１の引数で識別されるメモリ・ロケーションに書き込まれるという、本発明の実施形態の意味は、lock.displayユニオン８１６への書き込みは、ロック８１０の状態が未請求の場合にだけ生じるということである。
【０１１１】
ステップ１０７２において、１００６において読み取られたdisplay.blockと一緒にしてステップ１０７０において組み立てられたdisplay.block.valueである、lock.display.blockに対するアトミック比較およびスワップ命令は、単一操作で、スレッドが、lock.displayユニオン８１６を書き換えることを意味する。コストが掛かるアトミック比較およびスワップ命令のここでの使用は、それが不公平なロッキング獲得の間だけ、すなわち、次のロック・オーナ以外のスレッドによって限られた回数だけ実行されるので、アルゴリズムの性能への影響を有しない。ステップ１０７４において、比較およびスワップの結果が古いdisplayと一致するかどうかを調べるためのチェックが行われる。結果が一致しない場合、スレッドは、以下のいずれかを必要とする。
（ｉ）最初から再スタートすること、すなわち、処理が、接続子「Ｄ」を通して、図１０のステップ１００２に戻ること
（ｉｉ）ロックを獲得することをまったく断念することまたは
（ｉｉｉ）ロック８１０の獲得を待機しながら、スレッドのセット内におけるそれの位置を監視することを続けること、すなわち、処理が、接続子「Ｅ」を通して、図１０のステップ１００６に戻ること距離は負であるか、もしくは先の距離よりも大きいので、ステップ１０１０もしくはステップ１０１２において、処理は、その後、図１０のステップ１００２に戻る。
【０１１２】
結果が一致する場合、予想されるロック８１０の次のロック・オーナ８０４は、ステップ１００６とステップ１０７２との間に、ロック８１０を請求しようと試みておらず、スレッドは、それ自らによるロック８１０の請求に成功したと確信することができる。ステップ１０７６において、ロック８１０が、ロック８１０によって制御される共有リソース８１２の操作に着手することができるスレッドによって取得される。処理は、ステップ１０７８において終了する。
【０１１３】
図１６は、図１０から図１５の実施形態において獲得されたロックを解放するための方法の実施形態のフローチャートを示している。方法は、takenインジケータの現在値をturnインジケータの現在値になるように設定し、turnインジケータをインクリメントする。方法は、ステップ１１００において開始する。ステップ１１０２において、lock.displayユニオン８１６が、単一メモリ・アクセスで、ロック８１０からスレッド（次のロック・オーナ）８０４にコピーされる。これは、lock.display.detail.blockが単一操作でdisplay.detail.blockにロードされることによって達成される。ステップ１１０４において、スレッドは、lock.displayユニオン８１６内のdetail.taken９１８をdisplay.detail.turnになるように設定して、ロックが次のロック要求者によって利用可能であることを示す。スレッドは、lock.displayユニオン８１６内のdetail.taken９１８の高位ビットのクリアも行い、ロック８１０が取得されていないことを示す。ステップ１１０６において、display.detail.turnが、インクリメントされる。ステップ１１０８において、lock.displayユニオン８１６が、単一メモリ・アクセスで、スレッド（次のロック・オーナ）８０４からロック８１０にコピーされる。これは、ユニオン書き込みによって達成される。処理は、ステップ１１１０において終了する。
【０１１４】
図１０から図１５の実施形態は、キャンセル不可のビジー・ロックに対応し、それは、スレッドが、図１０から図１５のルーチンに入ると、ロック８１０が獲得されるまで脱出しないことを意味する。別の実施形態では、ロック要求者は、それがプリエンプトされたことを見出した場合は、ロック８１０を獲得することなく、脱出する。この実施形態では、ステップ１０１０、ステップ１０１２、ステップ１０３８、およびステップ１０７４において、ステップ１００２に戻り、ターゲット・チケットを取得する代わりに、エラーが戻され、処理が終了する。
【０１１５】
本発明の実施形態のさらなる利点は、非リスト公平アルゴリズムへの追加である、ＭＣＳまたはＣＬＨアルゴリズムとは異なり、本発明の実施形態は、ホスト環境におけるデータベース・エンジンなど、コンボイおよび欠乏の両方が問題となり得る環境において、本発明の実施形態が、同時係属中の英国特許出願ＧＢ１４０６８３３．２、「A busy lock and a passive lock featuring embedded load managementcapabilities」の実施形態と併せて、どちらに対する変更も行わずに、使用することができることである。他の実施形態では、本発明の実施形態および同時係属中の特許出願の実施形態の各々は、独立して使用することができ、その場合、２つの副作用の一方だけが、問題となる可能性が高い。さらに、本発明の実施形態は、２スレッド・ロック・ピーターソン・アルゴリズム（two thread lock Peterson algorithm）の回復力のあるＬＲＰ実施など、他の非リスト公平ロックにおいても使用することができる。
【０１１６】
図１７は、５０％のＣＰＵ負荷を有する単一ＣＰＵ仮想マシンの形態を取る負荷が加えられたときの第２のテスト・ケース・シナリオにおける、本発明によるアルゴリズムの実施形態についての、テスト・ケース実行時間対スレッドの数についてのグラフを示している。スレッドの数が増加するにつれて、実行時間は、スレッド当たり約７秒だけ増加する。実行時間は、ＣＰＵ仮想マシンが追加された場合も、負荷なしから実質的に変化しない。
【０１１７】
図１８は、利用可能なＣＰＵと同数のロック要求者（このケースでは、６つのスレッド、６つのＣＰＵ）を有し、物理ＣＰＵ時間の５０％を占有する仮想マシンの形態を取る外部負荷の数量を（０から５まで）変化させて実行される場合の、「チケット」、「テスト、セット・アンド・テスト、バックオフ」、および「プリエンプタブル・ロック」アルゴリズムの各々についての実行時間を、本発明によるアルゴリズムの実施形態と一緒に示している。負荷なしの条件下では、本発明の実施形態は、負荷なしのときの最良の実行者である「チケット」アルゴリズムよりも約８％遅い。追加のＣＰＵ仮想マシンが追加された場合も、実行時間は、「プリエンプタブル・ロック」アルゴリズムによく似て、実質的に変化しないままである。追加のＣＰＵ仮想マシンが追加された場合、「テスト、セット・アンド・テスト、バックオフ」アルゴリズムの実行時間は、減少する。しかしながら、本発明の実施形態が、「テスト、セット・アンド・テスト、バックオフ」アルゴリズムよりも悪い性能を見せるのは、１つのＣＰＵを除くすべてが追加の負荷を有してビジーである場合だけであり、その場合でも、約１０％悪くなるにすぎない。
【０１１８】
本発明の実施形態は、非競合ケースでも、「テスト、セット・アンド・テスト、バックオフ」および「チケット」アルゴリズムに一致する実行時間を提供し、それによって、リスト・ロックを上回る明らかな性能上の利点を提供する。実行時間の全体的な改善は、衝突を処理する複雑さに対処することを、価値のある実践にする。
【０１１９】
コンピュータ可読記憶媒体は、命令実行デバイスによって使用するための命令を保持し、記憶することができる、有形なデバイスとすることができる。コンピュータ可読記憶媒体は、例えば、電子記憶デバイス、磁気記憶デバイス、光記憶デバイス、電磁気記憶デバイス、半導体記憶デバイス、または上記のものの任意の適切な組合せとすることができるが、それらに限定されない。コンピュータ可読記憶媒体のより具体的な例の非網羅的なリストは、以下のものを、すなわち、ポータブル・コンピュータ・ディスケット、ハード・ディスク、ランダム・アクセス・メモリ（ＲＡＭ）、リード・オンリー・メモリ（ＲＯＭ）、消去可能プログラマブル・リード・オンリー・メモリ（ＥＰＲＯＭまたはフラッシュ・メモリ）、スタティック・ランダム・アクセス・メモリ（ＳＲＡＭ）、ポータブル・コンパクト・ディスク・リード・オンリー・メモリ（ＣＤ−ＲＯＭ）デジタル多用途ディスク（ＤＶＤ）、メモリ・スティック、フロッピー（Ｒ）・ディスク、パンチ・カードまたは命令が記録された溝内の隆起構造などの機械的に符号化されたデバイス、および上記のものの任意の適切な組合せを含む。コンピュータ可読記憶媒体は、本明細書で使用される場合、電波もしくは他の自由に伝搬する電磁波、導波路もしくは他の伝送媒体を通って伝搬する電磁波（例えば、光ファイバ・ケーブルを通る光パルス）、または電線を通して伝送される電気信号など、一時的信号自体であると解釈されるべきではない。
【０１２０】
本明細書で説明されるコンピュータ可読プログラム命令は、コンピュータ可読記憶媒体からそれぞれのコンピューティング／処理デバイスに、あるいはネットワーク、例えば、インターネット、ローカル・エリア・ネットワーク、ワイド・エリア・ネットワーク、もしくは無線ネットワーク、またはそれらの任意の組合せを介して、外部コンピュータまたは外部記憶デバイスにダウンロードすることができる。ネットワークは、銅伝送ケーブル、光伝送ファイバ、無線伝送、ルータ、ファイアウォール、スイッチ、ゲートウェイ・コンピュータ、またはエッジ・サーバ、あるいはそれらの任意の組合せを備えることができる。各コンピューティング／処理デバイス内のネットワーク・アダプタ・カードまたはネットワーク・インターフェースは、ネットワークからコンピュータ可読プログラム命令を受信し、それぞれのコンピューティング／処理デバイス内のコンピュータ可読記憶媒体内に記憶するために、コンピュータ可読プログラム命令を転送する。
【０１２１】
本発明の操作を実施するためのコンピュータ可読プログラム命令は、アセンブラ命令、命令セット・アーキテクチャ（ＩＳＡ）命令、マシン命令、マシン依存命令、マイクロコード、ファームウェア命令、状態設定データ、またはＳｍａｌｌｔａｌｋ（Ｒ）もしくはＣ＋＋などのオブジェクト指向プログラミング言語、および「Ｃ」プログラミング言語もしくは類似のプログラミング言語などの従来の手続型プログラミング言語を含む、１つもしくは複数のプログラミング言語の任意の組合せで書かれた、ソース・コードもしくはオブジェクト・コードとすることができる。コンピュータ可読プログラム命令は、すべてをユーザのコンピュータ上で、スタンドアロン・ソフトウェア・パッケージとして、一部をユーザのコンピュータ上で、一部をユーザのコンピュータ上で、一部をリモート・コンピュータ上で、またはすべてをリモート・コンピュータもしくはサーバ上で実行することができる。後者のシナリオでは、リモート・コンピュータは、ローカル・エリア・ネットワーク（ＬＡＮ）もしくはワイド・エリア・ネットワーク（ＷＡＮ）を含む任意のタイプのネットワークを通して、ユーザのコンピュータに接続することができ、または接続は、（例えば、インターネット・サービス・プロバイダを使用してインターネットを通して）外部コンピュータに対して行うことができる。いくつかの実施形態では、例えば、プログラマブル論理回路、フィールド・プログラマブル・ゲート・アレイ（ＦＰＧＡ）、またはプログラマブル論理アレイ（ＰＬＡ）を含む、電子回路は、本発明の態様を実行するように、電子回路をカスタマイズするために、コンピュータ可読プログラム命令の状態情報を利用することによって、コンピュータ可読プログラム命令を実行することができる。
【０１２２】
本発明の態様は、本発明の実施形態による方法、装置（システム）、およびコンピュータ・プログラム製品についてのフローチャート図またはブロック図、あるいはその両方を参照して本明細書で説明される。フローチャート図またはブロック図、あるいはその両方の各ブロック、およびフローチャート図またはブロック図、あるいはその両方におけるブロックの組合せは、コンピュータ可読プログラム命令によって実施することができることが理解される。
【０１２３】
これらのコンピュータ可読プログラム命令は、コンピュータまたは他のプログラマブル・データ処理装置のプロセッサを介して実行する命令が、フローチャートまたはブロック図、あるいはその両方の１つまたは複数のブロックにおいて指定される機能／動作を実施するための手段を生成するように、汎用コンピュータ、専用コンピュータ、または他のプログラマブル・データ処理装置のプロセッサに提供されて、マシンを生成するものであってよい。これらのコンピュータ可読プログラム命令は、命令を記憶したコンピュータ可読記憶媒体が、フローチャートまたはブロック図、あるいはその両方の１つまたは複数のブロックにおいて指定される機能／動作の態様を実施する命令を含む製造品を含むように、コンピュータ可読記憶媒体内に記憶され、コンピュータ、プログラマブル・データ処理装置、または他のデバイス、あるいはそれらの任意の組合せに、特定の方法で機能するように指示するものであってもよい。
【０１２４】
コンピュータ可読プログラム命令は、コンピュータ、他のプログラマブル装置、または他のデバイス上で実行される命令が、フローチャートまたはブロック図、あるいはその両方の１つまたは複数のブロックにおいて指定される機能／動作を実装するように、コンピュータ実装プロセスを生成させるべく、コンピュータ、他のプログラマブル・データ処理装置、または他のデバイス上にロードされ、コンピュータ、他のプログラマブル装置、または他のデバイス上で一連の動作ステップを実行させるものであってもよい。
【０１２５】
図におけるフローチャートおよびブロック図は、本発明の様々な実施形態による、システム、方法、およびコンピュータ・プログラム製品の可能な実施についての、アーキテクチャ、機能性、および操作を説明する。この点で、フローチャートまたはブロック図における各ブロックは、指定された論理機能を実施するための１つまたは複数の実行可能命令を含む、命令のモジュール、セグメント、または部分を表すことができる。いくつかの代替的な実施では、ブロックにおいて述べられる機能は、図で述べられる順序とは異なる順序で生じてもよい。例えば、連続して示される２つのブロックは、含まれる機能性に応じて、実際には、実質的に同時に実行されてもよく、またはブロックは、時には逆順で実行されてもよい。ブロック図またはフローチャート図、あるいはその両方の各ブロック、およびブロック図またはフローチャート図、あるいはその両方におけるブロックの組合せは、指定された機能もしくは動作を実行し、または専用ハードウェアおよびコンピュータ命令の組合せを実施する、専用ハードウェア・ベースのシステムによって実施することができることも留意される。
【図１】
0006529586.tif 000002
【図２】
0006529586.tif 000003
【図３】
0006529586.tif 000004
【図４】
0006529586.tif 000005
【図５】
0006529586.tif 000006
【図６】
0006529586.tif 000007
【図７】
0006529586.tif 000008
【図８】
0006529586.tif 000009
【図９】
0006529586.tif 000010
【図１０】
0006529586.tif 000011
【図１１】
0006529586.tif 000012
【図１２】
0006529586.tif 000013
【図１３】
0006529586.tif 000014
【図１４】
0006529586.tif 000015
【図１５】
0006529586.tif 000016
【図１６】
0006529586.tif 000017
【図１７】
0006529586.tif 000018
【図１８】
0006529586.tif 000019