Ignore:
Timestamp:
Jul 23, 2017, 2:29:40 PM (7 years ago)
Author:
coas-nagasima
Message:

SVNプロパティを設定

File:
1 edited

Legend:

Unmodified
Added
Removed
  • rubycfg_asp/trunk/asp_dcre/doc/design.txt

    • Property svn:mime-type changed from text/plain to text/plane; charset=UTF-8
    r313 r315  
    11
    2                 TOPPERS/ASPカーネル
    3                 設計メモ
    4 
    5                 対応バージョン: Release 1.9.3
    6                 最終更新: 2014å¹´4月15日(作成中)
    7 
    8 ã“のドキュメントは,TOPPERS/ASPカーネルの設計メモである.作成途中のもの
    9 ã§ã‚り,網ç¾
    10 çš„ではない.
     2                TOPPERS/ASPカーネル
     3                設計メモ
     4
     5                対応バージョン: Release 1.9.3
     6                最終更新: 2014年4月15日(作成中)
     7
     8このドキュメントは,TOPPERS/ASPカーネルの設計メモである.作成途中のもの
     9であり,網羅的ではない.
    1110
    1211----------------------------------------------------------------------
     
    1817             Graduate School of Information Science, Nagoya Univ., JAPAN
    1918 
    20  ä¸Šè¨˜è‘—作権è€
    21 ã¯ï¼Œä»¥ä¸‹ã®(1)~(4)の条件を満たす場合に限り,本ソフトウェ
    22  ã‚¢ï¼ˆæœ¬ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã‚’改変したものを含む.以下同じ)を使用・複製・改
    23  å¤‰ãƒ»å†é
    24 å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
    25  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
    26      æ¨©è¡¨ç¤ºï¼Œã“の利用条件および下記の無保証規定が,そのままの形でソー
    27      ã‚¹ã‚³ãƒ¼ãƒ‰ä¸­ã«å«ã¾ã‚Œã¦ã„ること.
    28  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
    29      ç”¨ã§ãã‚‹å½¢ã§å†é
    30 å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é
    31 å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
    32      è€
    33 ãƒžãƒ‹ãƒ¥ã‚¢ãƒ«ãªã©ï¼‰ã«ï¼Œä¸Šè¨˜ã®è‘—作権表示,この利用条件および下記
    34      ã®ç„¡ä¿è¨¼è¦å®šã‚’掲載すること.
    35  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
    36      ç”¨ã§ããªã„形で再é
    37 å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
    38      ã¨ï¼Ž
    39    (a) 再é
    40 å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€
    41 ãƒžãƒ‹ãƒ¥ã‚¢ãƒ«ãªã©ï¼‰ã«ï¼Œä¸Šè¨˜ã®è‘—
    42        ä½œæ¨©è¡¨ç¤ºï¼Œã“の利用条件および下記の無保証規定を掲載すること.
    43    (b) 再é
    44 å¸ƒã®å½¢æ
    45 ‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
    46        å ±å‘Šã™ã‚‹ã“と.
    47  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
    48      å®³ã‹ã‚‰ã‚‚,上記著作権è€
    49 ãŠã‚ˆã³TOPPERSプロジェクトをå
    50 è²¬ã™ã‚‹ã“と.
    51      ã¾ãŸï¼Œæœ¬ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã®ãƒ¦ãƒ¼ã‚¶ã¾ãŸã¯ã‚¨ãƒ³ãƒ‰ãƒ¦ãƒ¼ã‚¶ã‹ã‚‰ã®ã„かなる理
    52      ç”±ã«åŸºã¥ãè«‹æ±‚からも,上記著作権è€
    53 ãŠã‚ˆã³TOPPERSプロジェクトを
    54      å
    55 è²¬ã™ã‚‹ã“と.
     19 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
     20 ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
     21 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
     22 (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
     23     権表示,この利用条件および下記の無保証規定が,そのままの形でソー
     24     スコード中に含まれていること.
     25 (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
     26     用できる形で再配布する場合には,再配布に伴うドキュメント(利用
     27     者マニュアルなど)に,上記の著作権表示,この利用条件および下記
     28     の無保証規定を掲載すること.
     29 (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
     30     用できない形で再配布する場合には,次のいずれかの条件を満たすこ
     31     と.
     32   (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
     33       作権表示,この利用条件および下記の無保証規定を掲載すること.
     34   (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
     35       報告すること.
     36 (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
     37     害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
     38     また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
     39     由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
     40     免責すること.
    5641 
    57  æœ¬ã‚½ãƒ•ãƒˆã‚¦ã‚§ã‚¢ã¯ï¼Œç„¡ä¿è¨¼ã§æä¾›ã•ã‚Œã¦ã„るものである.上記著作権è€
    58 ãŠ
    59  ã‚ˆã³TOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
    60  ã«å¯¾ã™ã‚‹é©åˆæ€§ã‚‚含めて,いかなる保証も行わない.また,本ソフトウェ
    61  ã‚¢ã®åˆ©ç”¨ã«ã‚ˆã‚Šç›´æŽ¥çš„または間接的に生じたいかなる損害に関しても,そ
    62  ã®è²¬ä»»ã‚’負わない.
     42 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
     43 よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
     44 に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
     45 アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
     46 の責任を負わない.
    6347 
    6448 $Id$
    6549----------------------------------------------------------------------
    6650
    67 â—‹ç›®æ¬¡
    68 
    69 ãƒ»TOPPERS/ASPカーネルの実è£
    70 è¨­è¨ˆæ–¹é‡
    71 ãƒ»ã‚·ã‚¹ãƒ†ãƒ çŠ¶æ
    72 ‹ã¨ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®å®Ÿè£
    73 
    74         - カーネル動作状æ
    75 ‹ã¨éžå‹•ä½œçŠ¶æ
    76 ‹
    77         - タスクコンテキストと非タスクコンテキスト
    78         - å
    79 ¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ
    80 ‹ã¨å
    81 ¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯è§£é™¤çŠ¶æ
    82 ‹
    83         - CPUロック状æ
    84 ‹ã¨CPUロック解除状æ
    85 ‹
    86         - 割込み優å
    87 ˆåº¦ãƒžã‚¹ã‚¯
    88         - ディスパッチ禁止状æ
    89 ‹ã¨ãƒ‡ã‚£ã‚¹ãƒ‘ッチ許可状æ
    90 ‹
    91         - ディスパッチ保留状æ
    92 ‹
    93 ãƒ»ã‚¿ã‚¹ã‚¯çŠ¶æ
    94 ‹ã®ç®¡ç†ã¨ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒªãƒ³ã‚°
    95         - タスク状æ
    96 ‹ã®ç®¡ç†
    97         - タスクスケジューラ
    98 ãƒ»ã‚¿ã‚¹ã‚¯ãƒ‡ã‚£ã‚¹ãƒ‘ッチ処理の実è£
    99 
    100         - タスクディスパッチ処理のå¿
    101 è¦ãªã‚¿ã‚¤ãƒŸãƒ³ã‚°
    102         - タスクディスパッチャの構造
    103         - タスクの終了時のタスクディスパッチ
    104         - reqflgの導å
    105 ¥ç†ç”±
    106 ãƒ»ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理機能の実è£
    107 
    108         - タスク例外処理ルーチンの実行開始条件とシステム状æ
    109 ‹ï¼ˆä»•æ§˜ã®ç¢ºèªï¼‰
    110         - タスク例外処理ルーチンの呼出し処理
    111         - タスク例外処理ルーチンの実行開始がå¿
    112 è¦ãªã‚¿ã‚¤ãƒŸãƒ³ã‚°
    113         - タスク例外処理ルーチンの実行開始処理
    114         - call_texrtnからdispatchを呼び出す処理について
    115 ãƒ»ã‚¨ãƒ©ãƒ¼ã®ãƒã‚§ãƒƒã‚¯é †åº
    116         - エラーの3分類
    117         - 静的エラーのチェック順序
    118         - 準静的エラーのチェック順序
    119 ãƒ»CHECKマクロとgoto文の使用
    120         - CHECKマクロの定義とその使用法
    121         - 設計意図
    122         - CHECKマクロを使用してよい条件
    123         - 問題を生じることがない根拠
    124 ãƒ»ext_tsk,ext_kerの返り値
    125 ãƒ»ã‚«ãƒ¼ãƒãƒ«ã®ãƒ‡ãƒ¼ã‚¿æ§‹é€ ã«å¯¾ã™ã‚‹volatile宣言について
    126 ãƒ»åž‹ã‚­ãƒ£ã‚¹ãƒˆã«ä¼´ã†è­¦å‘Šãƒ¡ãƒƒã‚»ãƒ¼ã‚¸
    127 ãƒ»æ€§èƒ½è©•ä¾¡ç”¨ã‚·ã‚¹ãƒ†ãƒ æ™‚刻参ç
    128 §æ©Ÿèƒ½
    129         - å¿
    130 è¦æ€§ã¨ä½¿é€”
    131         - API仕様
    132         - 実è£
    133 
    134 ãƒ»ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理禁止フラグをenatexで実è£
    135 ã—ている理由
    136 
    137 
    138 â—‹TOPPERS/ASPカーネルの実è£
    139 è¨­è¨ˆæ–¹é‡
    140 
    141 TOPPERS/ASPカーネル(以下,ASPカーネル)は,TOPPERS新世代カーネルの出発
    142 ç‚¹ã¨ãªã‚‹ãƒªã‚¢ãƒ«ã‚¿ã‚¤ãƒ ã‚«ãƒ¼ãƒãƒ«ã§ã‚る.TOPPERS新世代カーネル仕様の設計方針
    143 ã¨ï¼ŒASPカーネルの適用対象領域と設計方針については,TOPPERS新世代カーネ
    144 ãƒ«çµ±åˆä»•æ§˜æ›¸ã«è¿°ã¹ã‚‰ã‚Œã¦ã„る.
    145 
    146 ä»¥ä¸‹ã§ã¯ï¼ŒASPカーネルの実è£
    147 è¨­è¨ˆæ–¹é‡ã«ã¤ã„て述べるが,仕様設計方針とも関
    148 é€£ã—ており,明確に分離できない部分もある.
    149 
    150 TOPPERS/ASPカーネルの実è£
    151 è¨­è¨ˆã‚’行うにあたり,次の方針を設定する.
    152 
    153 (1) ソースコードの読みやすさ・改造しやすさを重視する
    154 
    155 ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ãŒèª­ã¿ã‚„すいことは,オープンソースソフトウェアの品質を向上
    156 ã•ã›ã‚‹ä¸Šã§æœ€ã‚‚重要な特性である.ソースコードを理解している技術è€
    157 ãŒå¢—え
    158 ã‚‹ã“とで,問題を早期に発見することができ,サポート体制もå
    159 
    160 å®Ÿã•ã›ã‚‹ã“と
    161 ãŒã§ãã‚‹ï¼Žã¾ãŸï¼Œã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ãŒèª­ã¿ã‚„すいことは,シンプルな設計がされて
    162 ã„ることも意味しており,信頼性向上にもつながる.さらに,技術è€
    163 æ•™è‚²ã®ãŸ
    164 ã‚ã®æ•™æã¨ã™ã‚‹è¦³ç‚¹ã‹ã‚‰ã‚‚,ソースコードが読みやすいことは重要となる.
    165 
    166 æ”¹é€ ã—やすいことは,システム毎の要求にあわせたチューニングが行いやすい
    167 ã“とを意味しており,擦り合わせ型の開発を支援する性質である.また,ASPカー
    168 ãƒãƒ«ã‚’基盤としてTOPPERS新世代カーネルシリーズを開発していく上でも,改造
    169 ã—やすいことはå¿
    170 é ˆã®æ¡ä»¶ã§ã‚る.
    171 
    172 (2) 新しいターゲットシステムへのポーティングが容易な構造とする
    173 
    174 çµ„込みシステムには多様なハードウェアが用いられるため,それらに容易にポー
    175 ãƒ†ã‚£ãƒ³ã‚°ã§ãã‚‹ã“とは重要な性質である.そのために,実行性能にé
    176 æ
    177 ®ã—つつ
    178 ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã‚’抽象化し,ターゲットシステムに依存する部分(ターゲット依
    179 å­˜éƒ¨ï¼‰ã¨ä¾å­˜ã—ない部分(ターゲット非依存部)を明確に分離する.また,開
    180 ç™ºç’°å¢ƒï¼ˆã‚³ãƒ³ãƒ‘イラなど)に依存する部分も明確に分離する.
    181 
    182 (3) 検証が容易な構造とする
    183 
    184 ä¿¡é ¼æ€§ã‚’確保するために,検証が容易な構造とする.
    185 
    186 å
    187 ·ä½“的には,サービスコールのほとんどå
    188 ¨ä½“を割込み禁止で実行することとし,
    189 ã‚µãƒ¼ãƒ“スコールの処理途中で割込みを許可しない.この構造は,読みやすく改
    190 é€ ã—やすいソースコードにするためにも有効である.これにより割込み応答性
    191 ãŒçŠ ç‰²ã«ãªã‚‹ãŒï¼Œãã‚Œã«ã‚ˆã£ã¦å•é¡Œã‚’生じるアプリケーションは少数であり,
    192 ã‚„むをえないものと考える.
    193 
    194 ã¾ãŸï¼Œæ¡ä»¶ã‚³ãƒ³ãƒ‘イル等によりコンフィギュレーションできる箇所を増やすと,
    195 ç´°ã‹ãªæœ€é©åŒ–ができる一方で,検証すべき組合せが増えることから,コンフィ
    196 ã‚®ãƒ¥ãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã§ãã‚‹ç®‡æ‰€ã¯å¿
    197 è¦æœ€ä½Žé™ã¨ã™ã‚‹ï¼Ž
    198 
    199 (4) 実行性能とメモリ使用量にé
    200 æ
    201 ®ã™ã‚‹
    202 
    203 ä¸Šè¨˜ã®æ–¹é‡ã‚’満たした上で,高い実行性能と小さいメモリ使用量を達成できる
    204 ã‚ˆã†ãªå®Ÿè£
    205 ã‚’行う.実行性能を向上させる際には,平均性能の向上よりも,最
    206 æ‚ªæ™‚性能の向上を重視する.
    207 
    208 ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã®èª­ã¿ã‚„すさを重視すると言っても,実行性能の悪いアルゴリズ
    209 ãƒ ã‚’安易に採用することはせず,高い実行性能を達成できるアルゴリズムを用
    210 ã„る.ただし,新しいターゲットシステムへのポーティングを容易にするため
    211 ã«å¤§éƒ¨åˆ†ã‚’C言語で実è£
    212 ã—ており,すべてをアセンブリ言語で記述した場合に比
    213 ã¹ã¦å®Ÿè¡Œæ€§èƒ½ãŒè½ã¡ã‚‹ã®ã¯ã‚„むをえない.
    214 
    215 ãƒ¡ãƒ¢ãƒªä½¿ç”¨é‡ã«ã¤ã„ては,RAMの使用量を削減することに重点を置いた設計を行
    216 ã†ãŒï¼Œä¸Šè¨˜ã®æ–¹é‡ãŠã‚ˆã³å®Ÿè¡Œæ€§èƒ½ã¨ã®ãƒˆãƒ¬ãƒ¼ãƒ‰ã‚ªãƒ•ã‚’考æ
    217 ®ã—,ぎりぎりまでの
    218 å‰Šæ¸›ã¯è¡Œã‚ãªã„.
    219 
    220 (5) スケーラビリティにé
    221 æ
    222 ®ã™ã‚‹
    223 
    224 æ§˜ã€
    225 ãªè¦æ¨¡ã®ã‚·ã‚¹ãƒ†ãƒ ã«é©ç”¨ã§ãã‚‹ã‚¹ã‚±ãƒ¼ãƒ©ãƒ“リティをもった構造とする.特
    226 ã«ï¼Œå°è¦æ¨¡ãªã‚·ã‚¹ãƒ†ãƒ ã«é©ç”¨ã™ã‚‹éš›ã«ï¼Œä½¿ç”¨ã—ない機能をカーネルが持ってい
    227 ã‚‹ã“とによるメモリ使用量の増加が最小限になるようにé
    228 æ
    229 ®ã™ã‚‹ï¼Ž
    230 
    231 å
    232 ·ä½“的には,アプリケーションとカーネルを1つのロードモジュールにリンクす
    233 ã‚‹æ–¹æ³•ï¼ˆ1リンクモデル)を想定し,カーネルを関数単位でライブラリ化して,
    234 ä½¿ç”¨ã™ã‚‹é–¢æ•°ã®ã¿ã‚’リンクできる構造とする.これは一種のコンフィギュレー
    235 ã‚·ãƒ§ãƒ³ã§ã‚るが,この方法は,条件コンパイルによるコンフィギュレーション
    236 ã¨ã¯é•ã„,検証工数に与える影響が小さい.
    237 
    238 ã¾ãŸï¼Œå›ºå®šçš„に使用するRAM領域を減らし,スタックに置けるæƒ
    239 å ±ã¯ã§ãã‚‹é™ã‚Š
    240 ã‚¹ã‚¿ãƒƒã‚¯ä¸Šã«ç½®ãï¼Ž
    241 
    242 
    243 â—‹ã‚·ã‚¹ãƒ†ãƒ çŠ¶æ
    244 ‹ã¨ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®å®Ÿè£
    245 
    246 
    247 ã“の章では,「TOPPERS新世代カーネル統合仕様書」の「2.5 システム状æ
    248 ‹ã¨ã‚³
    249 ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã€ã®ç¯€ã«è¦å®šã•ã‚Œã¦ã„るシステム状æ
    250 ‹ã¨ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®å®Ÿè£
    251 æ–¹æ³•ã«
    252 ã¤ã„て記述する.
    253 
    254 â—ã‚«ãƒ¼ãƒãƒ«å‹•ä½œçŠ¶æ
    255 ‹ã¨éžå‹•ä½œçŠ¶æ
    256 ‹
    257 
    258 ã‚«ãƒ¼ãƒãƒ«ã®å‹•ä½œçŠ¶æ
    259 ‹ã‚’管理するために,カーネル動作状æ
    260 ‹ãƒ•ãƒ©ã‚°ï¼ˆkerflg)を
    261 ç”¨æ„ã™ã‚‹ï¼Žkerflgは,スタートアップモジュールでfalse(=0)に初期化する.
    262 ã¾ãŸï¼Œã‚«ãƒ¼ãƒãƒ«å‹•ä½œã®é–‹å§‹æ™‚にtrueにし,カーネル動作の終了時にfalseにする.
     51○目次
     52
     53・TOPPERS/ASPカーネルの実装設計方針
     54・システム状態とコンテキストの実装
     55        - カーネル動作状態と非動作状態
     56        - タスクコンテキストと非タスクコンテキスト
     57        - 全割込みロック状態と全割込みロック解除状態
     58        - CPUロック状態とCPUロック解除状態
     59        - 割込み優先度マスク
     60        - ディスパッチ禁止状態とディスパッチ許可状態
     61        - ディスパッチ保留状態
     62・タスク状態の管理とスケジューリング
     63        - タスク状態の管理
     64        - タスクスケジューラ
     65・タスクディスパッチ処理の実装
     66        - タスクディスパッチ処理の必要なタイミング
     67        - タスクディスパッチャの構造
     68        - タスクの終了時のタスクディスパッチ
     69        - reqflgの導入理由
     70・タスク例外処理機能の実装
     71        - タスク例外処理ルーチンの実行開始条件とシステム状態(仕様の確認)
     72        - タスク例外処理ルーチンの呼出し処理
     73        - タスク例外処理ルーチンの実行開始が必要なタイミング
     74        - タスク例外処理ルーチンの実行開始処理
     75        - call_texrtnからdispatchを呼び出す処理について
     76・エラーのチェック順序
     77        - エラーの3分類
     78        - 静的エラーのチェック順序
     79        - 準静的エラーのチェック順序
     80・CHECKマクロとgoto文の使用
     81        - CHECKマクロの定義とその使用法
     82        - 設計意図
     83        - CHECKマクロを使用してよい条件
     84        - 問題を生じることがない根拠
     85・ext_tsk,ext_kerの返り値
     86・カーネルのデータ構造に対するvolatile宣言について
     87・型キャストに伴う警告メッセージ
     88・性能評価用システム時刻参照機能
     89        - 必要性と使途
     90        - API仕様
     91        - 実装
     92・タスク例外処理禁止フラグをenatexで実装している理由
     93
     94
     95○TOPPERS/ASPカーネルの実装設計方針
     96
     97TOPPERS/ASPカーネル(以下,ASPカーネル)は,TOPPERS新世代カーネルの出発
     98点となるリアルタイムカーネルである.TOPPERS新世代カーネル仕様の設計方針
     99と,ASPカーネルの適用対象領域と設計方針については,TOPPERS新世代カーネ
     100ル統合仕様書に述べられている.
     101
     102以下では,ASPカーネルの実装設計方針について述べるが,仕様設計方針とも関
     103連しており,明確に分離できない部分もある.
     104
     105TOPPERS/ASPカーネルの実装設計を行うにあたり,次の方針を設定する.
     106
     107(1) ソースコードの読みやすさ・改造しやすさを重視する
     108
     109ソースコードが読みやすいことは,オープンソースソフトウェアの品質を向上
     110させる上で最も重要な特性である.ソースコードを理解している技術者が増え
     111ることで,問題を早期に発見することができ,サポート体制も充実させること
     112ができる.また,ソースコードが読みやすいことは,シンプルな設計がされて
     113いることも意味しており,信頼性向上にもつながる.さらに,技術者教育のた
     114めの教材とする観点からも,ソースコードが読みやすいことは重要となる.
     115
     116改造しやすいことは,システム毎の要求にあわせたチューニングが行いやすい
     117ことを意味しており,擦り合わせ型の開発を支援する性質である.また,ASPカー
     118ネルを基盤としてTOPPERS新世代カーネルシリーズを開発していく上でも,改造
     119しやすいことは必須の条件である.
     120
     121(2) 新しいターゲットシステムへのポーティングが容易な構造とする
     122
     123組込みシステムには多様なハードウェアが用いられるため,それらに容易にポー
     124ティングできることは重要な性質である.そのために,実行性能に配慮しつつ
     125ハードウェアを抽象化し,ターゲットシステムに依存する部分(ターゲット依
     126存部)と依存しない部分(ターゲット非依存部)を明確に分離する.また,開
     127発環境(コンパイラなど)に依存する部分も明確に分離する.
     128
     129(3) 検証が容易な構造とする
     130
     131信頼性を確保するために,検証が容易な構造とする.
     132
     133具体的には,サービスコールのほとんど全体を割込み禁止で実行することとし,
     134サービスコールの処理途中で割込みを許可しない.この構造は,読みやすく改
     135造しやすいソースコードにするためにも有効である.これにより割込み応答性
     136が犠牲になるが,それによって問題を生じるアプリケーションは少数であり,
     137やむをえないものと考える.
     138
     139また,条件コンパイル等によりコンフィギュレーションできる箇所を増やすと,
     140細かな最適化ができる一方で,検証すべき組合せが増えることから,コンフィ
     141ギュレーションできる箇所は必要最低限とする.
     142
     143(4) 実行性能とメモリ使用量に配慮する
     144
     145上記の方針を満たした上で,高い実行性能と小さいメモリ使用量を達成できる
     146ような実装を行う.実行性能を向上させる際には,平均性能の向上よりも,最
     147悪時性能の向上を重視する.
     148
     149ソースコードの読みやすさを重視すると言っても,実行性能の悪いアルゴリズ
     150ムを安易に採用することはせず,高い実行性能を達成できるアルゴリズムを用
     151いる.ただし,新しいターゲットシステムへのポーティングを容易にするため
     152に大部分をC言語で実装しており,すべてをアセンブリ言語で記述した場合に比
     153べて実行性能が落ちるのはやむをえない.
     154
     155メモリ使用量については,RAMの使用量を削減することに重点を置いた設計を行
     156うが,上記の方針および実行性能とのトレードオフを考慮し,ぎりぎりまでの
     157削減は行わない.
     158
     159(5) スケーラビリティに配慮する
     160
     161様々な規模のシステムに適用できるスケーラビリティをもった構造とする.特
     162に,小規模なシステムに適用する際に,使用しない機能をカーネルが持ってい
     163ることによるメモリ使用量の増加が最小限になるように配慮する.
     164
     165具体的には,アプリケーションとカーネルを1つのロードモジュールにリンクす
     166る方法(1リンクモデル)を想定し,カーネルを関数単位でライブラリ化して,
     167使用する関数のみをリンクできる構造とする.これは一種のコンフィギュレー
     168ションであるが,この方法は,条件コンパイルによるコンフィギュレーション
     169とは違い,検証工数に与える影響が小さい.
     170
     171また,固定的に使用するRAM領域を減らし,スタックに置ける情報はできる限り
     172スタック上に置く.
     173
     174
     175○システム状態とコンテキストの実装
     176
     177この章では,「TOPPERS新世代カーネル統合仕様書」の「2.5 システム状態とコ
     178ンテキスト」の節に規定されているシステム状態とコンテキストの実装方法に
     179ついて記述する.
     180
     181●カーネル動作状態と非動作状態
     182
     183カーネルの動作状態を管理するために,カーネル動作状態フラグ(kerflg)を
     184用意する.kerflgは,スタートアップモジュールでfalse(=0)に初期化する.
     185また,カーネル動作の開始時にtrueにし,カーネル動作の終了時にfalseにする.
    263186
    264187----------------------------------------
     
    266189----------------------------------------
    267190
    268 kerflgは,sns_kerで参ç
    269 §ã™ã‚‹ï¼Žã‚«ãƒ¼ãƒãƒ«éžå‹•ä½œçŠ¶æ
    270 ‹ã§sns_ker以外のサービス
    271 ã‚³ãƒ¼ãƒ«ã‚’呼び出した場合の動作は保証するå¿
    272 è¦ãŒãªã„ため,他のサービスコー
    273 ãƒ«ã§ã¯kerflgを参ç
    274 §ã—ない.
    275 
    276 â—ã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã¨éžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆ
    277 
    278 ã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã¨éžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®åˆ‡æ›ãˆã¯ï¼Œã‚¿ãƒ¼ã‚²ãƒƒãƒˆãƒãƒ¼ãƒ‰ã‚¦ã‚§
    279 ã‚¢ãŠã‚ˆã³ã‚¿ãƒ¼ã‚²ãƒƒãƒˆä¾å­˜éƒ¨ã«å§”ねる.また,どちらのコンテキストで実行中で
    280 ã‚るかを判別する関数(sense_context)も,ターゲット依存部で用意すること
    281 ã¨ã™ã‚‹ï¼Ž
    282 
    283 â—å
    284 ¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ
    285 ‹ã¨å
    286 ¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯è§£é™¤çŠ¶æ
    287 ‹
    288 
    289 å
    290 ¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯ãƒ•ãƒ©ã‚°ã®ç®¡ç†ã¯ã‚¿ãƒ¼ã‚²ãƒƒãƒˆä¾å­˜éƒ¨ã«å§”ね,å
    291 ¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ
    292 ‹
    293 ã«é·ç§»ã•ã›ã‚‹ãƒžã‚¯ãƒ­ï¼ˆSIL_LOC_INT)と,å
    294 ƒã®çŠ¶æ
    295 ‹ã«æˆ»ã™ãƒžã‚¯ãƒ­ï¼ˆSIL_UNL_INT)
    296 ã¯ï¼ŒSILのターゲット依存部で用意することとする.å
    297 ¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ
    298 ‹ã§ã‚ã‚‹
    299 ã‹å¦ã‹ã‚’判別する機能は,å¿
    300 è¦ãŒãªã„ために用意していない.
    301 
    302 å
    303 ¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ
    304 ‹ã§sns_kerとext_ker以外のサービスコールを呼び出した場
    305 åˆã®å‹•ä½œã¯ä¿è¨¼ã™ã‚‹å¿
    306 è¦ãŒãªã„ため,サービスコール中でå
    307 ¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ
    308 ‹
    309 ã§ã‚ることを判別するå¿
    310 è¦ã¯ãªã„.
    311 
    312 â—CPUロック状æ
    313 ‹ã¨CPUロック解除状æ
    314 ‹
    315 
    316 CPUロックフラグの管理はターゲット依存部に委ね,CPUロック状æ
    317 ‹ã«é·ç§»ã•ã›
    318 ã‚‹é–¢æ•°ï¼ˆt_lock_cpu/i_lock_cpu/x_lock_cpu)と,CPUロック解除状æ
    319 ‹ã«é·ç§»
    320 ã•ã›ã‚‹é–¢æ•°ï¼ˆt_unlock_cpu/i_unlock_cpu/x_unlock_cpu)は,ターゲット依
    321 å­˜éƒ¨ã§ç”¨æ„ã™ã‚‹ã“ととする.また,CPUロック状æ
    322 ‹ã§ã‚るか否かを判別する関数
    323 ï¼ˆt_sense_lock/i_sense_lock/x_sense_lock)も,ターゲット依存部で用意
    324 ã™ã‚‹ã“ととする.
    325 
    326 â—å‰²è¾¼ã¿å„ªå
    327 ˆåº¦ãƒžã‚¹ã‚¯
    328 
    329 å‰²è¾¼ã¿å„ªå
    330 ˆåº¦ãƒžã‚¹ã‚¯ã®ç®¡ç†ã¯ã‚¿ãƒ¼ã‚²ãƒƒãƒˆä¾å­˜éƒ¨ã«å§”ね,割込み優å
    331 ˆåº¦ãƒžã‚¹ã‚¯ã‚’
    332 è¨­å®šã™ã‚‹é–¢æ•°ï¼ˆt_set_ipm/i_set_ipm/x_set_ipm)と,それを参ç
    333 §ã™ã‚‹é–¢æ•°
    334 ï¼ˆt_get_ipm/i_get_ipm/x_get_ipm)は,ターゲット依存部で用意することと
    335 ã™ã‚‹ï¼Ž
    336 
    337 ãŸã ã—,タスクコンテキストの実行中に,割込み優å
    338 ˆåº¦ãƒžã‚¹ã‚¯å
    339 ¨è§£é™¤çŠ¶æ
    340 ‹ã§ã‚
    341 ã‚‹ã“とを効率的に判断するために,割込み優å
    342 ˆåº¦ãƒžã‚¹ã‚¯å
    343 ¨è§£é™¤çŠ¶æ
    344 ‹ã§ã‚ること
    345 ã‚’示すフラグ(ipmflg)を用意する.
    346 
    347 ipmflgは,カーネルの初期化時にfalseに初期化する.非タスクコンテキストで
    348 ã¯ï¼Œå‰²è¾¼ã¿å„ªå
    349 ˆåº¦ãƒžã‚¹ã‚¯å
    350 ¨è§£é™¤çŠ¶æ
    351 ‹ã«ãªã‚‹ã“とはないため,このフラグを用い
    352 ã‚‹å¿
    353 è¦ã¯ãªãï¼Œãƒ•ãƒ©ã‚°ã®æ›´æ–°ã‚‚行わない.
     191kerflgは,sns_kerで参照する.カーネル非動作状態でsns_ker以外のサービス
     192コールを呼び出した場合の動作は保証する必要がないため,他のサービスコー
     193ルではkerflgを参照しない.
     194
     195●タスクコンテキストと非タスクコンテキスト
     196
     197タスクコンテキストと非タスクコンテキストの切換えは,ターゲットハードウェ
     198アおよびターゲット依存部に委ねる.また,どちらのコンテキストで実行中で
     199あるかを判別する関数(sense_context)も,ターゲット依存部で用意すること
     200とする.
     201
     202●全割込みロック状態と全割込みロック解除状態
     203
     204全割込みロックフラグの管理はターゲット依存部に委ね,全割込みロック状態
     205に遷移させるマクロ(SIL_LOC_INT)と,元の状態に戻すマクロ(SIL_UNL_INT)
     206は,SILのターゲット依存部で用意することとする.全割込みロック状態である
     207か否かを判別する機能は,必要がないために用意していない.
     208
     209全割込みロック状態でsns_kerとext_ker以外のサービスコールを呼び出した場
     210合の動作は保証する必要がないため,サービスコール中で全割込みロック状態
     211であることを判別する必要はない.
     212
     213●CPUロック状態とCPUロック解除状態
     214
     215CPUロックフラグの管理はターゲット依存部に委ね,CPUロック状態に遷移させ
     216る関数(t_lock_cpu/i_lock_cpu/x_lock_cpu)と,CPUロック解除状態に遷移
     217させる関数(t_unlock_cpu/i_unlock_cpu/x_unlock_cpu)は,ターゲット依
     218存部で用意することとする.また,CPUロック状態であるか否かを判別する関数
     219(t_sense_lock/i_sense_lock/x_sense_lock)も,ターゲット依存部で用意
     220することとする.
     221
     222●割込み優先度マスク
     223
     224割込み優先度マスクの管理はターゲット依存部に委ね,割込み優先度マスクを
     225設定する関数(t_set_ipm/i_set_ipm/x_set_ipm)と,それを参照する関数
     226(t_get_ipm/i_get_ipm/x_get_ipm)は,ターゲット依存部で用意することと
     227する.
     228
     229ただし,タスクコンテキストの実行中に,割込み優先度マスク全解除状態であ
     230ることを効率的に判断するために,割込み優先度マスク全解除状態であること
     231を示すフラグ(ipmflg)を用意する.
     232
     233ipmflgは,カーネルの初期化時にfalseに初期化する.非タスクコンテキストで
     234は,割込み優先度マスク全解除状態になることはないため,このフラグを用い
     235る必要はなく,フラグの更新も行わない.
    354236
    355237----------------------------------------
     
    357239----------------------------------------
    358240
    359 â—ãƒ‡ã‚£ã‚¹ãƒ‘ッチ禁止状æ
    360 ‹ã¨ãƒ‡ã‚£ã‚¹ãƒ‘ッチ許可状æ
    361 ‹
    362 
    363 ãƒ‡ã‚£ã‚¹ãƒ‘ッチ禁止フラグを管理するために,フラグ(disdsp)を用意する.
    364 disdspは,カーネルの初期化時にfalseに初期化する.
     241●ディスパッチ禁止状態とディスパッチ許可状態
     242
     243ディスパッチ禁止フラグを管理するために,フラグ(disdsp)を用意する.
     244disdspは,カーネルの初期化時にfalseに初期化する.
    365245
    366246----------------------------------------
     
    368248----------------------------------------
    369249
    370 â€» disdspではなく,それを論理反転したenadspを用意した方が,ipmflgや
    371 dspflgとの整合性の観点からは良かった.
    372 
    373 â—ãƒ‡ã‚£ã‚¹ãƒ‘ッチ保留状æ
    374 ‹
    375 
    376 ãƒ‡ã‚£ã‚¹ãƒ‘ッチ保留状æ
    377 ‹ã¯ï¼Œéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®å®Ÿè¡Œä¸­ï¼ŒCPUロック状æ
    378 ‹ï¼Œå‰²
    379 è¾¼ã¿å„ªå
    380 ˆåº¦ãƒžã‚¹ã‚¯ãŒå
    381 ¨è§£é™¤ã§ãªã„状æ
    382 ‹ï¼Œãƒ‡ã‚£ã‚¹ãƒ‘ッチ禁止状æ
    383 ‹ã®ã„ずれか(ま
    384 ãŸã¯ï¼Œãã‚Œã‚‰ãŒé‡ãªã£ãŸçŠ¶æ
    385 ‹ï¼‰ã§ã‚る.
    386 
    387 ã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®å®Ÿè¡Œä¸­ã«ï¼Œãƒ‡ã‚£ã‚¹ãƒ‘ッチ保留状æ
    388 ‹ã§ãªã„こと(つまり,
    389 ãƒ‡ã‚£ã‚¹ãƒ‘ッチできる状æ
    390 ‹ã§ã‚ること)を効率的に判別するために,割込み優å
    391 ˆ
    392 åº¦ãƒžã‚¹ã‚¯å
    393 ¨è§£é™¤çŠ¶æ
    394 ‹ã§ã‚り,ディスパッチ許可状æ
    395 ‹ã§ã‚る(ディスパッチ禁止
    396 çŠ¶æ
    397 ‹ã§ãªã„)ことを示すフラグ(dspflg)を用意する.すなわち,常に
    398 ã€Œdspflg == (ipmflg && !disdsp)」に設定する.
    399 
    400 dspflgは,カーネルの初期化時にtrueに初期化する.また,タスクコンテキス
    401 ãƒˆã«ãŠã„て割込み優å
    402 ˆåº¦ãƒžã‚¹ã‚¯ã®å€¤ãŒå¤‰æ›´ã•ã‚Œã‚‹ã‹ï¼Œå‰²è¾¼ã¿ç¦æ­¢ãƒ•ãƒ©ã‚°ãŒå¤‰æ›´
    403 ã•ã‚Œã‚‹åº¦ã«æ›´æ–°ã™ã‚‹ï¼Žéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã§ã¯ï¼Œå¸¸ã«ãƒ‡ã‚£ã‚¹ãƒ‘ッチ保留状æ
    404 ‹
    405 ã§ã‚るため,このフラグを用いるå¿
    406 è¦ã¯ãªãï¼Œãƒ•ãƒ©ã‚°ã®æ›´æ–°ã‚‚行わない.
     250※ disdspではなく,それを論理反転したenadspを用意した方が,ipmflgや
     251dspflgとの整合性の観点からは良かった.
     252
     253●ディスパッチ保留状態
     254
     255ディスパッチ保留状態は,非タスクコンテキストの実行中,CPUロック状態,割
     256込み優先度マスクが全解除でない状態,ディスパッチ禁止状態のいずれか(ま
     257たは,それらが重なった状態)である.
     258
     259タスクコンテキストの実行中に,ディスパッチ保留状態でないこと(つまり,
     260ディスパッチできる状態であること)を効率的に判別するために,割込み優先
     261度マスク全解除状態であり,ディスパッチ許可状態である(ディスパッチ禁止
     262状態でない)ことを示すフラグ(dspflg)を用意する.すなわち,常に
     263「dspflg == (ipmflg && !disdsp)」に設定する.
     264
     265dspflgは,カーネルの初期化時にtrueに初期化する.また,タスクコンテキス
     266トにおいて割込み優先度マスクの値が変更されるか,割込み禁止フラグが変更
     267される度に更新する.非タスクコンテキストでは,常にディスパッチ保留状態
     268であるため,このフラグを用いる必要はなく,フラグの更新も行わない.
    407269
    408270----------------------------------------
     
    411273
    412274
    413 â—‹ã‚¿ã‚¹ã‚¯çŠ¶æ
    414 ‹ã®ç®¡ç†ã¨ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒªãƒ³ã‚°
     275○タスク状態の管理とスケジューリング
    415276       
    416 â—ã‚¿ã‚¹ã‚¯çŠ¶æ
    417 ‹ã®ç®¡ç†
    418 
    419 ã‚¿ã‚¹ã‚¯ç®¡ç†ãƒ–ロック(TCB)中のタスク状æ
    420 ‹ã‚’管理するフィールド(tstat)で
    421 ã¯ï¼Œã‚¿ã‚¹ã‚¯çŠ¶æ
    422 ‹ãŒæ¬¡ã®ã„ずれであるかを管理する.
    423 
    424 ã€€ãƒ»å®Ÿè¡Œã§ãã‚‹çŠ¶æ
    425 ‹
    426 ã€€ãƒ»ä¼‘止状æ
    427 ‹
    428 ã€€ãƒ»ï¼ˆç‹­ç¾©ã®ï¼‰å¾
    429 ã¡çŠ¶æ
    430 ‹
    431 ã€€ãƒ»å¼·åˆ¶å¾
    432 ã¡çŠ¶æ
    433 ‹
    434 ã€€ãƒ»äºŒé‡å¾
    435 ã¡çŠ¶æ
    436 ‹
    437 
    438 ã‚¿ã‚¹ã‚¯ãŒå®Ÿè¡Œã§ãã‚‹çŠ¶æ
    439 ‹ã®æ™‚に,実行状æ
    440 ‹ã§ã‚るか実行可能状æ
    441 ‹ã§ã‚るかは,
    442 ã“のフィールドでは管理せず,実行状æ
    443 ‹ã®ã‚¿ã‚¹ã‚¯ã®TCBを指すポインタ変数
    444 ï¼ˆp_runtsk)によって判別する.実行状æ
    445 ‹ã®ã‚¿ã‚¹ã‚¯ãŒãªã„場合は,p_runtskは
    446 NULLにする.
     277●タスク状態の管理
     278
     279タスク管理ブロック(TCB)中のタスク状態を管理するフィールド(tstat)で
     280は,タスク状態が次のいずれであるかを管理する.
     281
     282 ・実行できる状態
     283 ・休止状態
     284 ・(狭義の)待ち状態
     285 ・強制待ち状態
     286 ・二重待ち状態
     287
     288タスクが実行できる状態の時に,実行状態であるか実行可能状態であるかは,
     289このフィールドでは管理せず,実行状態のタスクのTCBを指すポインタ変数
     290(p_runtsk)によって判別する.実行状態のタスクがない場合は,p_runtskは
     291NULLにする.
    447292
    448293----------------------------------------
     
    450295----------------------------------------
    451296
    452 p_runtskは,カーネルの初期化時にNULLに初期化し,ディスパッチャにおいて
    453 æ›´æ–°ã™ã‚‹ï¼Žã‚µãƒ¼ãƒ“スコールの処理の中で自タスクに関するæƒ
    454 å ±ã‚’参ç
    455 §ã™ã‚‹å ´åˆ
    456 ã¯ï¼Œp_runtskを用いる.
    457 
    458 â—ã‚¿ã‚¹ã‚¯ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ©
    459 
    460 ã‚¿ã‚¹ã‚¯ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ©ã¯ï¼Œå®Ÿè¡Œã§ãã‚‹çŠ¶æ
    461 ‹ã®ã‚¿ã‚¹ã‚¯ã®ä¸­ã‹ã‚‰ï¼Œæœ€ã‚‚優å
    462 ˆé †ä½ãŒé«˜
    463 ã„タスク(これを,最高優å
    464 ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ã¨å‘¼ã¶ï¼‰ã‚’決定し,そのタスクの
    465 TCBを指すポインタ変数(p_schedtsk)を設定する.
     297p_runtskは,カーネルの初期化時にNULLに初期化し,ディスパッチャにおいて
     298更新する.サービスコールの処理の中で自タスクに関する情報を参照する場合
     299は,p_runtskを用いる.
     300
     301●タスクスケジューラ
     302
     303タスクスケジューラは,実行できる状態のタスクの中から,最も優先順位が高
     304いタスク(これを,最高優先順位のタスクと呼ぶ)を決定し,そのタスクの
     305TCBを指すポインタ変数(p_schedtsk)を設定する.
    466306
    467307----------------------------------------
     
    469309----------------------------------------
    470310
    471 ã‚¿ã‚¹ã‚¯ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ©ã«å¯¾ã—ては,どのタスクが実行できる状æ
    472 ‹ã§ã‚るかを知ら
    473 ã›ã‚‹å¿
    474 è¦ãŒã‚る.そのため,タスクスケジューラは,次の2つの関数を用意する.
    475 
    476 ã€€ãƒ»ã‚¿ã‚¹ã‚¯ãŒå®Ÿè¡Œã§ãã‚‹çŠ¶æ
    477 ‹ã«é·ç§»ã—たことを知らせる関数(make_runnable)
    478 ã€€ãƒ»ã‚¿ã‚¹ã‚¯ãŒå®Ÿè¡Œã§ãã‚‹çŠ¶æ
    479 ‹ã‹ã‚‰ä»–の状æ
    480 ‹ã¸é·ç§»ã—たことを知らせる関数
    481         (make_non_runnable)
    482 
    483 ã¾ãŸï¼Œå‡¦ç†ã®åŠ¹çŽ‡åŒ–のために,上の2つの関数を用いずにレディキューを直接操
    484 ä½œã—てタスクスケジュールを行う関数として,次の2つの関数を用意する.
    485 
    486 ã€€ãƒ»ã‚¿ã‚¹ã‚¯ã®å„ªå
    487 ˆåº¦ã®å¤‰æ›´ï¼ˆchange_priority)
    488 ã€€ãƒ»ãƒ¬ãƒ‡ã‚£ã‚­ãƒ¥ãƒ¼ã®å›žè»¢ï¼ˆrotate_ready_queue)
    489 
    490 
    491 â—‹ã‚¿ã‚¹ã‚¯ãƒ‡ã‚£ã‚¹ãƒ‘ッチ処理の実è£
    492 
    493 
    494 â—ã‚¿ã‚¹ã‚¯ãƒ‡ã‚£ã‚¹ãƒ‘ッチ処理のå¿
    495 è¦ãªã‚¿ã‚¤ãƒŸãƒ³ã‚°
    496 
    497 ã‚¿ã‚¹ã‚¯ãƒ‡ã‚£ã‚¹ãƒ‘ッチは,実行状æ
    498 ‹ã®ã‚¿ã‚¹ã‚¯ï¼ˆp_runtsk)と最高優å
    499 ˆé †ä½ã®ã‚¿ã‚¹
    500 ã‚¯ï¼ˆp_schedtsk)が一致しておらず,ディスパッチ保留状æ
    501 ‹ã§ãªã„場合に行う.
    502 ã“のことから,タスクディスパッチ処理を行うå¿
    503 è¦ãŒã‚るのは,次の3つの場合
    504 ã§ã‚る.
    505 
    506 (1) 実行状æ
    507 ‹ã®ã‚¿ã‚¹ã‚¯ãŒå®Ÿè¡Œã§ãã‚‹çŠ¶æ
    508 ‹ã§ãªããªã‚‹
    509 
    510 è‡ªã‚¿ã‚¹ã‚¯ã‚’広義のå¾
    511 ã¡çŠ¶æ
    512 ‹ã«é·ç§»ã•ã›ã‚‹ã‚µãƒ¼ãƒ“スコールや,自タスクを終了さ
    513 ã›ã‚‹ã‚µãƒ¼ãƒ“スコールにおいて,タスクディスパッチ処理を行うå¿
    514 è¦ãŒã‚る.
    515 
    516 (2) 最高優å
    517 ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ãŒå¤‰åŒ–する
    518 
    519 ã‚¿ã‚¹ã‚¯ã®èµ·å‹•ï¼Œã‚¿ã‚¹ã‚¯ã®å¾
    520 ã¡è§£é™¤ï¼Œã‚¿ã‚¹ã‚¯ã®å¼·åˆ¶å¾
    521 ã¡ã‹ã‚‰ã®å†é–‹ï¼Œã‚¿ã‚¹ã‚¯ã®å„ª
    522 å
    523 ˆåº¦ã®å¤‰æ›´ï¼Œã‚¿ã‚¹ã‚¯ã®å„ªå
    524 ˆé †ä½ã®å›žè»¢ã‚’行うサービスコールにおいて,最高優
    525 å
    526 ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ãŒå¤‰åŒ–し,ディスパッチ保留状æ
    527 ‹ã§ãªã„場合には,タスクディ
    528 ã‚¹ãƒ‘ッチ処理を行うå¿
    529 è¦ãŒã‚る.
    530 
    531 (3) ディスパッチ保留状æ
    532 ‹ãŒè§£é™¤ã•ã‚Œã‚‹
    533 
    534 ãƒ‡ã‚£ã‚¹ãƒ‘ッチ保留状æ
    535 ‹ã¨ã¯ï¼Œéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®å®Ÿè¡Œä¸­ï¼ŒCPUロック状æ
    536 ‹ï¼Œ
    537 å‰²è¾¼ã¿å„ªå
    538 ˆåº¦ãƒžã‚¹ã‚¯ãŒå
    539 ¨è§£é™¤ã§ãªã„状æ
    540 ‹ï¼Œãƒ‡ã‚£ã‚¹ãƒ‘ッチ禁止状æ
    541 ‹ã®ç·ç§°ã§ã‚ã‚‹
    542 ãŸã‚ï¼Œã“れらの状æ
    543 ‹ã®ã„ずれかが遷移するタイミングで,タスクディスパッチ
    544 å‡¦ç†ã‚’行うå¿
    545 è¦ãŒã‚る.å
    546 ·ä½“的には,次のタイミングが該当する.
    547 
    548 (3-1) 非タスクコンテキストからタスクコンテキストに遷移する
    549 
    550 å‰²è¾¼ã¿ãƒãƒ³ãƒ‰ãƒ©ã¾ãŸã¯CPU例外ハンドラからタスクにリターンする際に,タスク
    551 ãƒ‡ã‚£ã‚¹ãƒ‘ッチ処理を行うå¿
    552 è¦ãŒã‚る.
    553 
    554 (3-2) CPUロック状æ
    555 ‹ãŒè§£é™¤ã•ã‚Œã‚‹
    556 
    557 CPUロック状æ
    558 ‹ã«ãŠã„ては,上記の(1)や(2)の状況を作り出すサービスコールを
    559 å‘¼ã³å‡ºã™ã“とができない.そのため,CPUロック状æ
    560 ‹ã®è§£é™¤æ™‚には,タスクディ
    561 ã‚¹ãƒ‘ッチ処理を行うå¿
    562 è¦ãŒãªã„.
    563 
    564 (3-3) 割込み優å
    565 ˆåº¦ãƒžã‚¹ã‚¯ãŒå
    566 ¨è§£é™¤ã•ã‚Œã‚‹
    567 
    568 å‰²è¾¼ã¿å„ªå
    569 ˆåº¦ãƒžã‚¹ã‚¯ã®å¤‰æ›´ï¼ˆchg_ipm)により割込み優å
    570 ˆåº¦ãƒžã‚¹ã‚¯ãŒå
    571 ¨è§£é™¤ã•ã‚Œ
    572 ã‚‹å ´åˆã«ï¼Œã‚¿ã‚¹ã‚¯ãƒ‡ã‚£ã‚¹ãƒ‘ッチ処理を行うå¿
    573 è¦ãŒã‚る.
    574 
    575 ã¾ãŸï¼Œã‚¿ã‚¹ã‚¯ã®çµ‚了,タスク例外処理ルーチンからのリターン,割込みハンド
    576 ãƒ©ã‹ã‚‰ã®ãƒªã‚¿ãƒ¼ãƒ³ï¼Œå‰²è¾¼ã¿ã‚µãƒ¼ãƒ“スルーチンからのリターン,タイムイベント
    577 ãƒãƒ³ãƒ‰ãƒ©ã‹ã‚‰ã®ãƒªã‚¿ãƒ¼ãƒ³ï¼ŒCPU例外ハンドラからのリターンによって,割込み優
    578 å
    579 ˆåº¦ãƒžã‚¹ã‚¯ãŒå
    580 ¨è§£é™¤ã•ã‚Œã‚‹å ´åˆãŒã‚り,その場合には,タスクディスパッチ処
    581 ç†ã‚’行うå¿
    582 è¦ãŒã‚る.ただし,割込みサービスルーチンおよびタイムイベント
    583 ãƒãƒ³ãƒ‰ãƒ©ã‹ã‚‰ã®ãƒªã‚¿ãƒ¼ãƒ³ã«ã¤ã„ては,リターン後も非タスクコンテキストであ
    584 ã‚Šï¼Œã‚¿ã‚¹ã‚¯ãƒ‡ã‚£ã‚¹ãƒ‘ッチ保留状æ
    585 ‹ãŒç¶™ç¶šã™ã‚‹ã“とから,タスクディスパッチ処
    586 ç†ã‚’行うå¿
    587 è¦ãŒãªã„.
    588 
    589 (3-4) ディスパッチ許可状æ
    590 ‹ã«ãªã‚‹
    591 
    592 ãƒ‡ã‚£ã‚¹ãƒ‘ッチの許可(ena_dsp)において,タスクディスパッチ処理を行うå¿
    593 è¦
    594 ãŒã‚る.
    595 
    596 ã¾ãŸï¼Œã‚¿ã‚¹ã‚¯ã®çµ‚了とタスク例外処理ルーチンからのリターンによって,ディ
    597 ã‚¹ãƒ‘ッチ許可状æ
    598 ‹ã«ãªã‚‹å ´åˆãŒã‚り,その場合には,タスクディスパッチ処理
    599 ã‚’行うå¿
    600 è¦ãŒã‚る.
    601 
    602 ä»¥ä¸Šã«åŠ ãˆã¦ï¼Œã‚«ãƒ¼ãƒãƒ«ã®å‹•ä½œé–‹å§‹æ™‚にも,タスクディスパッチ処理を呼び出
    603 ã™ï¼Ž
    604 
    605 â—ã‚¿ã‚¹ã‚¯ãƒ‡ã‚£ã‚¹ãƒ‘ッチャの構造
    606 
    607 ã‚¿ã‚¹ã‚¯ãƒ‡ã‚£ã‚¹ãƒ‘ッチャの主な機能は,切換え前のタスクのコンテキスト(プロ
    608 ã‚»ãƒƒã‚µã®æ±Žç”¨ãƒ¬ã‚¸ã‚¹ã‚¿ç­‰ï¼‰ã‚’メモリ上に保存し,切換え後のタスクのコンテキ
    609 ã‚¹ãƒˆã‚’メモリ上から復帰することである.ここで,保存/復帰しなければなら
    610 ãªã„レジスタは,タスクディスパッチャが実行される状況によって,次のよう
    611 ãªé•ã„がある.
    612 
    613 ãƒ»ã‚¿ã‚¹ã‚¯ãŒå‰²è¾¼ã¿ï¼ˆã¾ãŸã¯ï¼ŒCPU例外)によりプリエンプトされる場合には,す
    614 ã€€ã¹ã¦ã®ãƒ¬ã‚¸ã‚¹ã‚¿ã‚’保存しなければならない.また,その状æ
    615 ‹ã‹ã‚‰å®Ÿè¡Œå†é–‹ã™
    616 ã€€ã‚‹å ´åˆã«ã¯ï¼Œã™ã¹ã¦ã®ãƒ¬ã‚¸ã‚¹ã‚¿ã‚’復帰しなければならない.
    617 
    618 ãƒ»ã‚¿ã‚¹ã‚¯ãŒè‡ªç™ºçš„にタスクディスパッチャを呼び出す場合には,スクラッチレ
    619 ã€€ã‚¸ã‚¹ã‚¿ï¼ˆcaller saved register)以外のレジスタを保存すればよい.また,
    620 ã€€ãã®çŠ¶æ
    621 ‹ã‹ã‚‰å®Ÿè¡Œå†é–‹ã™ã‚‹å ´åˆã«ã¯ï¼Œã‚¹ã‚¯ãƒ©ãƒƒãƒãƒ¬ã‚¸ã‚¹ã‚¿ä»¥å¤–のレジスタを
    622 ã€€å¾©å¸°ã™ã‚Œã°ã‚ˆã„.
    623 
    624 ãƒ»ã‚¿ã‚¹ã‚¯ãŒçµ‚了する場合には,どのレジスタも保存するå¿
    625 è¦ãŒãªã„.
    626 
    627 ãƒ»ã‚¿ã‚¹ã‚¯ãŒå®Ÿè¡Œé–‹å§‹ã™ã‚‹å ´åˆã«ã¯ï¼Œã©ã®ãƒ¬ã‚¸ã‚¹ã‚¿ã‚‚復帰するå¿
    628 è¦ãŒãªã„.
    629 
    630 ãã“で,それぞれの状況でå¿
    631 è¦æœ€ä½Žé™ã®ãƒ¬ã‚¸ã‚¹ã‚¿ã®ã¿ã‚’保存/復帰するために,
    632 ã‚¿ã‚¹ã‚¯ãƒ‡ã‚£ã‚¹ãƒ‘ッチ処理を,(a) コンテキストの保存処理,(b) 実行するタス
    633 ã‚¯ã®é¸æŠžå‡¦ç†ï¼Œ(c) コンテキストの復帰処理の3つのステップで構成し,(a)と
    634 (c)のステップについては,タスクディスパッチャが実行される状況毎に用意す
    635 ã‚‹ï¼Žå
    636 ·ä½“的には,次の各処理を行うルーチンを用意する.
    637 
    638 (a) コンテキストの保存処理
    639         (a-1) タスクが自発的に呼び出した場合の保存処理(dispatch)
    640         (a-2) 割込みハンドラの出口で呼び出された場合の保存処理(ret_int)
    641         (a-3) CPU例外ハンドラの出口で呼び出された場合の保存処理(ret_exc)
    642         (a-4) タスクの終了時の処理(exit_and_dispatch)
    643         (a-5) カーネルの動作開始時の処理(start_dispatch)
    644 (b) 実行するタスクの選択(ディスパッチャ本体,dispatcher)
    645 (c) コンテキストの復帰処理
    646         (c-1) タスクが自発的に呼び出した場合の復帰処理(dispatch_r)
    647         (c-2) 割込みハンドラの出口で呼び出された場合の復帰処理(ret_int_r)
    648         (c-3) CPU例外ハンドラの出口で呼び出された場合の復帰処理(ret_exc_r)
    649         (c-4) タスクの実行開始時の処理(start_r)
    650 
    651 â—ã‚¿ã‚¹ã‚¯ã®çµ‚了時のタスクディスパッチ
    652 
    653 ext_tskによるタスクの終了時に,起動要求がキューイングされていると,同じ
    654 ã‚¿ã‚¹ã‚¯ãŒã™ãã«èµ·å‹•ã•ã‚Œã‚‹ï¼Žã“の場合,タスクディスパッチャにとっては,同
    655 ã˜ã‚¿ã‚¹ã‚¯ã¸ã®åˆ‡æ›ãˆã«è¦‹ãˆï¼Œã‚¿ã‚¹ã‚¯ãƒ‡ã‚£ã‚¹ãƒ‘ッチ処理をスキップ可能に思える
    656 ãŒï¼Œå®Ÿéš›ã«ã¯ï¼ŒåŒã˜ã‚¿ã‚¹ã‚¯ã®ç•°ãªã‚‹ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã¸ã®åˆ‡æ›ãˆã§ã‚るため,タス
    657 ã‚¯ãƒ‡ã‚£ã‚¹ãƒ‘ッチ処理をスキップしてはならない.
    658 
    659 ä¸Šè¿°ã®ã‚¿ã‚¹ã‚¯ãƒ‡ã‚£ã‚¹ãƒ‘ッチャの構造により,タスクの終了時には,それ専用の
    660 å‡¦ç†ï¼ˆexit_and_dispatch)を呼び出す.この処理では,実行状æ
    661 ‹ã®ã‚¿ã‚¹ã‚¯ã‚’参
    662 ç
    663 §ã›ãšï¼Œã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®ä¿å­˜ã‚‚行わずに,次に事é 
    664 ã™ã‚‹ã‚¿ã‚¹ã‚¯ã®é¸æŠžå‡¦ç†ã‚’è¡Œ
    665 ã†ãŸã‚ï¼Œã‚¿ã‚¹ã‚¯ãƒ‡ã‚£ã‚¹ãƒ‘ッチ処理がスキップされることはない.
    666 
    667 ãªãŠï¼Œter_tskによって実行状æ
    668 ‹ã®ã‚¿ã‚¹ã‚¯ã‚’終了させることはできないため,
    669 ter_tskではこのような状況は起こらない.
    670 
    671 â—reqflgの導å
    672 ¥ç†ç”±
    673 
    674 å‰²è¾¼ã¿ãƒãƒ³ãƒ‰ãƒ©ï¼CPU例外ハンドラの出口処理に,タスクディスパッチまたはタ
    675 ã‚¹ã‚¯ä¾‹å¤–処理ルーチンの実行開始を要求することを示すフラグとして,reqflg
    676 ã‚’用意している.非タスクコンテキストにおいて,タスクディスパッチがå¿
    677 è¦
    678 ã«ãªã£ãŸå ´åˆã‚„,タスク例外処理ルーチンの実行開始がå¿
    679 è¦ã«ãªã£ãŸå ´åˆã«ã¯ï¼Œ
    680 ã“のフラグをセットする.
    681 
    682 reqflgを導å
    683 ¥ã—た理由は,割込みハンドラ/CPU例外ハンドラの出口処理のå
    684 ¸åž‹
    685 çš„なケース(タスクディスパッチもタスク例外処理ルーチンの実行開始もå¿
    686 è¦
    687 ãªã„場合)を高速化するためである.また,ディスパッチャ本体(dispatcher)
    688 ã®ã‚¢ã‚¤ãƒ‰ãƒ«å‡¦ç†ã‚‚高速化できる.
    689 
    690 ã—かし,割込みハンドラ/CPU例外ハンドラの出口処理å
    691 ¨ä½“のオーバヘッドを考
    692 ãˆã‚‹ã¨ï¼Œreqflgによる高速化の効果はそれほど大きくないものと思われる.
    693 
    694 
    695 â—‹ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理機能の実è£
    696 
    697 
    698 â—ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンの実行開始条件とシステム状æ
    699 ‹ï¼ˆä»•æ§˜ã®ç¢ºèªï¼‰
    700 
    701 ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンは,次の6つの条件が揃った場合に実行が開始される.
    702 
    703 ã€€ãƒ»ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理許可状æ
    704 ‹ã§ã‚ã‚‹
    705 ã€€ãƒ»ä¿ç•™ä¾‹å¤–要因が0でない
    706 ã€€ãƒ»ã‚¿ã‚¹ã‚¯ãŒå®Ÿè¡ŒçŠ¶æ
    707 ‹ã§ã‚ã‚‹
    708 ã€€ãƒ»ã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãŒå®Ÿè¡Œã•ã‚Œã¦ã„ã‚‹
    709 ã€€ãƒ»å‰²è¾¼ã¿å„ªå
    710 ˆåº¦ãƒžã‚¹ã‚¯å
    711 ¨è§£é™¤çŠ¶æ
    712 ‹ã§ã‚ã‚‹
    713 ã€€ãƒ»CPUロック状æ
    714 ‹ã§ãªã„
    715 
    716 ã¾ãŸï¼Œã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンの実行開始/リターン時のシステム状æ
    717 ‹ã«é–¢ã™
    718 ã‚‹ä»•æ§˜ã¯æ¬¡ã®é€šã‚Šã§ã‚る.
    719 
    720                                 CPUロック            割込み優å
    721 ˆåº¦    ディスパッチ
    722                                 フラグ                       ãƒžã‚¹ã‚¯                       ç¦æ­¢ãƒ•ãƒ©ã‚°
     311タスクスケジューラに対しては,どのタスクが実行できる状態であるかを知ら
     312せる必要がある.そのため,タスクスケジューラは,次の2つの関数を用意する.
     313
     314 ・タスクが実行できる状態に遷移したことを知らせる関数(make_runnable)
     315 ・タスクが実行できる状態から他の状態へ遷移したことを知らせる関数
     316        (make_non_runnable)
     317
     318また,処理の効率化のために,上の2つの関数を用いずにレディキューを直接操
     319作してタスクスケジュールを行う関数として,次の2つの関数を用意する.
     320
     321 ・タスクの優先度の変更(change_priority)
     322 ・レディキューの回転(rotate_ready_queue)
     323
     324
     325○タスクディスパッチ処理の実装
     326
     327●タスクディスパッチ処理の必要なタイミング
     328
     329タスクディスパッチは,実行状態のタスク(p_runtsk)と最高優先順位のタス
     330ク(p_schedtsk)が一致しておらず,ディスパッチ保留状態でない場合に行う.
     331このことから,タスクディスパッチ処理を行う必要があるのは,次の3つの場合
     332である.
     333
     334(1) 実行状態のタスクが実行できる状態でなくなる
     335
     336自タスクを広義の待ち状態に遷移させるサービスコールや,自タスクを終了さ
     337せるサービスコールにおいて,タスクディスパッチ処理を行う必要がある.
     338
     339(2) 最高優先順位のタスクが変化する
     340
     341タスクの起動,タスクの待ち解除,タスクの強制待ちからの再開,タスクの優
     342先度の変更,タスクの優先順位の回転を行うサービスコールにおいて,最高優
     343先順位のタスクが変化し,ディスパッチ保留状態でない場合には,タスクディ
     344スパッチ処理を行う必要がある.
     345
     346(3) ディスパッチ保留状態が解除される
     347
     348ディスパッチ保留状態とは,非タスクコンテキストの実行中,CPUロック状態,
     349割込み優先度マスクが全解除でない状態,ディスパッチ禁止状態の総称である
     350ため,これらの状態のいずれかが遷移するタイミングで,タスクディスパッチ
     351処理を行う必要がある.具体的には,次のタイミングが該当する.
     352
     353(3-1) 非タスクコンテキストからタスクコンテキストに遷移する
     354
     355割込みハンドラまたはCPU例外ハンドラからタスクにリターンする際に,タスク
     356ディスパッチ処理を行う必要がある.
     357
     358(3-2) CPUロック状態が解除される
     359
     360CPUロック状態においては,上記の(1)や(2)の状況を作り出すサービスコールを
     361呼び出すことができない.そのため,CPUロック状態の解除時には,タスクディ
     362スパッチ処理を行う必要がない.
     363
     364(3-3) 割込み優先度マスクが全解除される
     365
     366割込み優先度マスクの変更(chg_ipm)により割込み優先度マスクが全解除され
     367る場合に,タスクディスパッチ処理を行う必要がある.
     368
     369また,タスクの終了,タスク例外処理ルーチンからのリターン,割込みハンド
     370ラからのリターン,割込みサービスルーチンからのリターン,タイムイベント
     371ハンドラからのリターン,CPU例外ハンドラからのリターンによって,割込み優
     372先度マスクが全解除される場合があり,その場合には,タスクディスパッチ処
     373理を行う必要がある.ただし,割込みサービスルーチンおよびタイムイベント
     374ハンドラからのリターンについては,リターン後も非タスクコンテキストであ
     375り,タスクディスパッチ保留状態が継続することから,タスクディスパッチ処
     376理を行う必要がない.
     377
     378(3-4) ディスパッチ許可状態になる
     379
     380ディスパッチの許可(ena_dsp)において,タスクディスパッチ処理を行う必要
     381がある.
     382
     383また,タスクの終了とタスク例外処理ルーチンからのリターンによって,ディ
     384スパッチ許可状態になる場合があり,その場合には,タスクディスパッチ処理
     385を行う必要がある.
     386
     387以上に加えて,カーネルの動作開始時にも,タスクディスパッチ処理を呼び出
     388す.
     389
     390●タスクディスパッチャの構造
     391
     392タスクディスパッチャの主な機能は,切換え前のタスクのコンテキスト(プロ
     393セッサの汎用レジスタ等)をメモリ上に保存し,切換え後のタスクのコンテキ
     394ストをメモリ上から復帰することである.ここで,保存/復帰しなければなら
     395ないレジスタは,タスクディスパッチャが実行される状況によって,次のよう
     396な違いがある.
     397
     398・タスクが割込み(または,CPU例外)によりプリエンプトされる場合には,す
     399 べてのレジスタを保存しなければならない.また,その状態から実行再開す
     400 る場合には,すべてのレジスタを復帰しなければならない.
     401
     402・タスクが自発的にタスクディスパッチャを呼び出す場合には,スクラッチレ
     403 ジスタ(caller saved register)以外のレジスタを保存すればよい.また,
     404 その状態から実行再開する場合には,スクラッチレジスタ以外のレジスタを
     405 復帰すればよい.
     406
     407・タスクが終了する場合には,どのレジスタも保存する必要がない.
     408
     409・タスクが実行開始する場合には,どのレジスタも復帰する必要がない.
     410
     411そこで,それぞれの状況で必要最低限のレジスタのみを保存/復帰するために,
     412タスクディスパッチ処理を,(a) コンテキストの保存処理,(b) 実行するタス
     413クの選択処理,(c) コンテキストの復帰処理の3つのステップで構成し,(a)と
     414(c)のステップについては,タスクディスパッチャが実行される状況毎に用意す
     415る.具体的には,次の各処理を行うルーチンを用意する.
     416
     417(a) コンテキストの保存処理
     418        (a-1) タスクが自発的に呼び出した場合の保存処理(dispatch)
     419        (a-2) 割込みハンドラの出口で呼び出された場合の保存処理(ret_int)
     420        (a-3) CPU例外ハンドラの出口で呼び出された場合の保存処理(ret_exc)
     421        (a-4) タスクの終了時の処理(exit_and_dispatch)
     422        (a-5) カーネルの動作開始時の処理(start_dispatch)
     423(b) 実行するタスクの選択(ディスパッチャ本体,dispatcher)
     424(c) コンテキストの復帰処理
     425        (c-1) タスクが自発的に呼び出した場合の復帰処理(dispatch_r)
     426        (c-2) 割込みハンドラの出口で呼び出された場合の復帰処理(ret_int_r)
     427        (c-3) CPU例外ハンドラの出口で呼び出された場合の復帰処理(ret_exc_r)
     428        (c-4) タスクの実行開始時の処理(start_r)
     429
     430●タスクの終了時のタスクディスパッチ
     431
     432ext_tskによるタスクの終了時に,起動要求がキューイングされていると,同じ
     433タスクがすぐに起動される.この場合,タスクディスパッチャにとっては,同
     434じタスクへの切換えに見え,タスクディスパッチ処理をスキップ可能に思える
     435が,実際には,同じタスクの異なるインスタンスへの切換えであるため,タス
     436クディスパッチ処理をスキップしてはならない.
     437
     438上述のタスクディスパッチャの構造により,タスクの終了時には,それ専用の
     439処理(exit_and_dispatch)を呼び出す.この処理では,実行状態のタスクを参
     440照せず,コンテキストの保存も行わずに,次に事項するタスクの選択処理を行
     441うため,タスクディスパッチ処理がスキップされることはない.
     442
     443なお,ter_tskによって実行状態のタスクを終了させることはできないため,
     444ter_tskではこのような状況は起こらない.
     445
     446●reqflgの導入理由
     447
     448割込みハンドラ/CPU例外ハンドラの出口処理に,タスクディスパッチまたはタ
     449スク例外処理ルーチンの実行開始を要求することを示すフラグとして,reqflg
     450を用意している.非タスクコンテキストにおいて,タスクディスパッチが必要
     451になった場合や,タスク例外処理ルーチンの実行開始が必要になった場合には,
     452このフラグをセットする.
     453
     454reqflgを導入した理由は,割込みハンドラ/CPU例外ハンドラの出口処理の典型
     455的なケース(タスクディスパッチもタスク例外処理ルーチンの実行開始も必要
     456ない場合)を高速化するためである.また,ディスパッチャ本体(dispatcher)
     457のアイドル処理も高速化できる.
     458
     459しかし,割込みハンドラ/CPU例外ハンドラの出口処理全体のオーバヘッドを考
     460えると,reqflgによる高速化の効果はそれほど大きくないものと思われる.
     461
     462
     463○タスク例外処理機能の実装
     464
     465●タスク例外処理ルーチンの実行開始条件とシステム状態(仕様の確認)
     466
     467タスク例外処理ルーチンは,次の6つの条件が揃った場合に実行が開始される.
     468
     469 ・タスク例外処理許可状態である
     470 ・保留例外要因が0でない
     471 ・タスクが実行状態である
     472 ・タスクコンテキストが実行されている
     473 ・割込み優先度マスク全解除状態である
     474 ・CPUロック状態でない
     475
     476また,タスク例外処理ルーチンの実行開始/リターン時のシステム状態に関す
     477る仕様は次の通りである.
     478
     479                                CPUロック          割込み優先度  ディスパッチ
     480                                フラグ                     マスク                     禁止フラグ
    723481------------------------------------------------------------
    724 ã€ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチン】
    725 å®Ÿè¡Œé–‹å§‹æ¡ä»¶      解除                  å
    726 ¨è§£é™¤                 ä»»æ„
    727 å®Ÿè¡Œé–‹å§‹æ™‚処理   ãã®ã¾ã¾            そのまま            そのまま
    728 ãƒªã‚¿ãƒ¼ãƒ³å‰         åŽŸå‰‡è§£é™¤(*1)        原則å
    729 ¨è§£é™¤(*1)     å
    730 ƒã«æˆ»ã™
    731 ãƒªã‚¿ãƒ¼ãƒ³æ™‚処理   è§£é™¤ã™ã‚‹            å
    732 ¨è§£é™¤ã™ã‚‹           å
    733 ƒã«æˆ»ã™(*4)
     482【タスク例外処理ルーチン】
     483実行開始条件  解除                      全解除                     任意
     484実行開始時処理 そのまま            そのまま            そのまま
     485リターン前           原則解除(*1)        原則全解除(*1)       元に戻す
     486リターン時処理 解除する            全解除する           元に戻す(*4)
    734487------------------------------------------------------------
    735488
    736 â—ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンの呼出し処理
    737 
    738 ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンを呼び出す処理は,次の流れとなる.この関数は,
    739 CPUロック状æ
    740 ‹ã§å‘¼ã³å‡ºã™ã“とを想定している.
     489●タスク例外処理ルーチンの呼出し処理
     490
     491タスク例外処理ルーチンを呼び出す処理は,次の流れとなる.この関数は,
     492CPUロック状態で呼び出すことを想定している.
    741493
    742494----------------------------------------
     
    749501        p_runtsk->texptn = 0U;
    750502
    751         タスク例外処理禁止状æ
    752 ‹ã«ã™ã‚‹
    753         ディスパッチ禁止フラグを保存する
    754 
    755         CPUロック解除状æ
    756 ‹ã«ã™ã‚‹
    757         タスク例外処理ルーチンを呼び出す
    758         CPUロック状æ
    759 ‹ã«ã™ã‚‹
    760 
    761         割込み優å
    762 ˆåº¦ãƒžã‚¹ã‚¯å
    763 ¨è§£é™¤çŠ¶æ
    764 ‹ã«ã™ã‚‹
    765         ディスパッチ禁止フラグをå
    766 ƒã«æˆ»ã™
    767         タスク例外処理禁止状æ
    768 ‹ã«ã™ã‚‹ … (*2)
    769 
    770         å¿
    771 è¦ãªå ´åˆã«ã¯ãƒ‡ã‚£ã‚¹ãƒ‘ッチを行う … (*1)
    772 
    773         タスク例外処理許可状æ
    774 ‹ã«ã™ã‚‹
     503        タスク例外処理禁止状態にする
     504        ディスパッチ禁止フラグを保存する
     505
     506        CPUロック解除状態にする
     507        タスク例外処理ルーチンを呼び出す
     508        CPUロック状態にする
     509
     510        割込み優先度マスク全解除状態にする
     511        ディスパッチ禁止フラグを元に戻す
     512        タスク例外処理禁止状態にする … (*2)
     513
     514        必要な場合にはディスパッチを行う … (*1)
     515
     516        タスク例外処理許可状態にする
    775517}
    776518----------------------------------------
    777519
    778 (*1)において,å¿
    779 è¦ãªå ´åˆã«ã‚¿ã‚¹ã‚¯åˆ‡æ›ãˆã‚’行うのは,割込み優å
    780 ˆåº¦ãƒžã‚¹ã‚¯ã‚’
    781 å
    782 ¨è§£é™¤ã«ã—,ディスパッチ禁止フラグをå
    783 ƒã«æˆ»ã—た結果,ディスパッチ保留状
    784 æ
    785 ‹ãŒè§£é™¤ã•ã‚Œï¼Œãƒ‡ã‚£ã‚¹ãƒ‘ッチがå¿
    786 è¦ã«ãªã‚‹å ´åˆãŒã‚るためである.
    787 
    788 ã¾ãŸï¼Œãƒ‡ã‚£ã‚¹ãƒ‘ッチを行う前にタスク例外処理禁止状æ
    789 ‹ã«ã™ã‚‹(*2)理由につい
    790 ã¦ã¯ï¼Œã€Œcall_texrtnからdispatchを呼び出す処理について」の節を参ç
    791 §ã™ã‚‹ã“
    792 ã¨ï¼Ž
    793 
    794 â—ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンの実行開始がå¿
    795 è¦ãªã‚¿ã‚¤ãƒŸãƒ³ã‚°
    796 
    797 ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンは,前述の6つの条件が揃った場合に実行開始すべきで
    798 ã‚るため,6つの条件のいずれかを新たに満たすようになる可能性のあるタイミ
    799 ãƒ³ã‚°ã§ï¼Œã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンの実行開始がå¿
    800 è¦ã«ãªã‚‹ï¼Ž
    801 
    802 ä»¥ä¸‹ã§ã¯ï¼Œ6つの条件のいずれかを新たに満たすようになるタイミングについて
    803 æ¤œè¨Žã™ã‚‹ï¼Ž
    804 
    805 (1) タスク例外処理許可状æ
    806 ‹ã§ã‚ã‚‹
    807 
    808 ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理の許可(ena_tex)によって,タスク例外処理許可状æ
    809 ‹ã«ãªã‚‹ï¼Ž
    810 ã¾ãŸï¼Œã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンからのリターンによっても,タスク例外処理許
    811 å¯çŠ¶æ
    812 ‹ã«ãªã‚‹ï¼Ž
    813 
    814 (2) 保留例外要因が0でない
    815 
    816 ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理の要求(ras_tex,iras_tex)によって,タスクの保留例外要因
    817 ãŒ0でなくなる.ただし,非タスクコンテキストからのタスク例外処理の要求
    818 ï¼ˆiras_tex)では,(4)の条件が満たされないため,タスク例外処理ルーチンの
    819 å®Ÿè¡Œé–‹å§‹ã¯å¿
    820 è¦ãªã„.
    821 
    822 (3) タスクが実行状æ
    823 ‹ã§ã‚ã‚‹
    824 
    825 ã‚¿ã‚¹ã‚¯ãƒ‡ã‚£ã‚¹ãƒ‘ッチャにより,切換え後のタスクが実行状æ
    826 ‹ã«ãªã‚‹ï¼Ž
    827 
    828 (4) タスクコンテキストが実行されている
    829 
    830 å‰²è¾¼ã¿ãƒãƒ³ãƒ‰ãƒ©ãŠã‚ˆã³CPU例外ハンドラからのリターンによって,タスクコンテ
    831 ã‚­ã‚¹ãƒˆã«æˆ»ã‚‹å ´åˆãŒã‚る.
    832 
    833 (5) 割込み優å
    834 ˆåº¦ãƒžã‚¹ã‚¯å
    835 ¨è§£é™¤çŠ¶æ
    836 ‹ã§ã‚ã‚‹
    837 
    838 å‰²è¾¼ã¿å„ªå
    839 ˆåº¦ãƒžã‚¹ã‚¯ã®å¤‰æ›´ï¼ˆchg_ipm)によって,割込み優å
    840 ˆåº¦ãƒžã‚¹ã‚¯ãŒå
    841 ¨è§£é™¤
    842 ã«ãªã‚‹ï¼Ž
    843 
    844 ã¾ãŸï¼Œã‚¿ã‚¹ã‚¯ã®çµ‚了,タスク例外処理ルーチンからのリターン,割込みハンド
    845 ãƒ©ã‹ã‚‰ã®ãƒªã‚¿ãƒ¼ãƒ³ï¼ŒCPU例外ハンドラからのリターンによっても,割込み優å
    846 ˆåº¦
    847 ãƒžã‚¹ã‚¯ãŒå
    848 ¨è§£é™¤ã•ã‚Œã‚‹å ´åˆã‚‚ある.
    849 
    850 ãŸã ã—,タスクの終了時については,タスクの終了後は別のタスクへ切り換わ
    851 ã‚‹ãŸã‚ï¼Œåˆ‡ã‚Šæ›ã‚ã£ãŸå¾Œã®ã‚¿ã‚¹ã‚¯ã«å¯¾ã™ã‚‹ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンの実行開始
    852 ã‚’,タスクディスパッチ後の処理で行えばよい.
    853 
    854 (6) CPUロック状æ
    855 ‹ã§ãªã„
    856 
    857 CPUロック状æ
    858 ‹ã®è§£é™¤ï¼ˆunl_cpu,iunl_cpu)によって,CPUロック状æ
    859 ‹ã§ãªããª
    860 ã‚‹ï¼ŽãŸã ã—,非タスクコンテキストでのCPUロック状æ
    861 ‹ã®è§£é™¤ï¼ˆiunl_cpu)では,
    862 (4)の条件が満たされないため,タスク例外処理ルーチンの実行開始はå¿
    863 è¦ãªã„.
    864 
    865 ã¾ãŸï¼Œã‚¿ã‚¹ã‚¯ã®çµ‚了,タスク例外処理ルーチンからのリターン,割込みハンド
    866 ãƒ©ã‹ã‚‰ã®ãƒªã‚¿ãƒ¼ãƒ³ï¼Œå‰²è¾¼ã¿ã‚µãƒ¼ãƒ“スルーチンからのリターン,タイムイベント
    867 ãƒãƒ³ãƒ‰ãƒ©ã‹ã‚‰ã®ãƒªã‚¿ãƒ¼ãƒ³ï¼ŒCPU例外ハンドラからのリターンによって,CPUロッ
    868 ã‚¯çŠ¶æ
    869 ‹ã§ãªããªã‚‹å ´åˆã‚‚ある.
    870 
    871 ãŸã ã—,割込みサービスルーチンおよびタイムイベントハンドラからのリター
    872 ãƒ³ã«ã¤ã„ては,リターン後も非タスクコンテキストの実行が続き,(4)の条件が
    873 æº€ãŸã•ã‚Œãªã„ため,タスク例外処理ルーチンの実行開始はå¿
    874 è¦ãªã„.
    875 
    876 ã‚¿ã‚¹ã‚¯ã®çµ‚了時については,タスクの終了後は別のタスクへ切り換わるため,
    877 åˆ‡ã‚Šæ›ã‚ã£ãŸå¾Œã®ã‚¿ã‚¹ã‚¯ã«å¯¾ã™ã‚‹ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンの実行開始を,タス
    878 ã‚¯ãƒ‡ã‚£ã‚¹ãƒ‘ッチ後の処理で行えばよい.
    879 
    880 ä»¥ä¸Šã‚ˆã‚Šï¼Œé‡è¤‡ã™ã‚‹ã‚±ãƒ¼ã‚¹ã‚’考æ
    881 ®ã™ã‚‹ã¨ï¼Œã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンの実行開始
    882 ãŒå¿
    883 è¦ã«ãªã‚‹å¯èƒ½æ€§ãŒã‚るのは,以下の処理である.
    884 
    885 (a) タスク例外処理の許可(ena_tex)… (1)
    886 (b) タスク例外処理ルーチンの出口処理 … (1)(5)(6)
    887 (c) タスク例外処理の要求(ras_tex)… (2)
    888 (d) タスクディスパッチ後の処理 … (3)(5)(6)
     520(*1)において,必要な場合にタスク切換えを行うのは,割込み優先度マスクを
     521全解除にし,ディスパッチ禁止フラグを元に戻した結果,ディスパッチ保留状
     522態が解除され,ディスパッチが必要になる場合があるためである.
     523
     524また,ディスパッチを行う前にタスク例外処理禁止状態にする(*2)理由につい
     525ては,「call_texrtnからdispatchを呼び出す処理について」の節を参照するこ
     526と.
     527
     528●タスク例外処理ルーチンの実行開始が必要なタイミング
     529
     530タスク例外処理ルーチンは,前述の6つの条件が揃った場合に実行開始すべきで
     531あるため,6つの条件のいずれかを新たに満たすようになる可能性のあるタイミ
     532ングで,タスク例外処理ルーチンの実行開始が必要になる.
     533
     534以下では,6つの条件のいずれかを新たに満たすようになるタイミングについて
     535検討する.
     536
     537(1) タスク例外処理許可状態である
     538
     539タスク例外処理の許可(ena_tex)によって,タスク例外処理許可状態になる.
     540また,タスク例外処理ルーチンからのリターンによっても,タスク例外処理許
     541可状態になる.
     542
     543(2) 保留例外要因が0でない
     544
     545タスク例外処理の要求(ras_tex,iras_tex)によって,タスクの保留例外要因
     546が0でなくなる.ただし,非タスクコンテキストからのタスク例外処理の要求
     547(iras_tex)では,(4)の条件が満たされないため,タスク例外処理ルーチンの
     548実行開始は必要ない.
     549
     550(3) タスクが実行状態である
     551
     552タスクディスパッチャにより,切換え後のタスクが実行状態になる.
     553
     554(4) タスクコンテキストが実行されている
     555
     556割込みハンドラおよびCPU例外ハンドラからのリターンによって,タスクコンテ
     557キストに戻る場合がある.
     558
     559(5) 割込み優先度マスク全解除状態である
     560
     561割込み優先度マスクの変更(chg_ipm)によって,割込み優先度マスクが全解除
     562になる.
     563
     564また,タスクの終了,タスク例外処理ルーチンからのリターン,割込みハンド
     565ラからのリターン,CPU例外ハンドラからのリターンによっても,割込み優先度
     566マスクが全解除される場合もある.
     567
     568ただし,タスクの終了時については,タスクの終了後は別のタスクへ切り換わ
     569るため,切り換わった後のタスクに対するタスク例外処理ルーチンの実行開始
     570を,タスクディスパッチ後の処理で行えばよい.
     571
     572(6) CPUロック状態でない
     573
     574CPUロック状態の解除(unl_cpu,iunl_cpu)によって,CPUロック状態でなくな
     575る.ただし,非タスクコンテキストでのCPUロック状態の解除(iunl_cpu)では,
     576(4)の条件が満たされないため,タスク例外処理ルーチンの実行開始は必要ない.
     577
     578また,タスクの終了,タスク例外処理ルーチンからのリターン,割込みハンド
     579ラからのリターン,割込みサービスルーチンからのリターン,タイムイベント
     580ハンドラからのリターン,CPU例外ハンドラからのリターンによって,CPUロッ
     581ク状態でなくなる場合もある.
     582
     583ただし,割込みサービスルーチンおよびタイムイベントハンドラからのリター
     584ンについては,リターン後も非タスクコンテキストの実行が続き,(4)の条件が
     585満たされないため,タスク例外処理ルーチンの実行開始は必要ない.
     586
     587タスクの終了時については,タスクの終了後は別のタスクへ切り換わるため,
     588切り換わった後のタスクに対するタスク例外処理ルーチンの実行開始を,タス
     589クディスパッチ後の処理で行えばよい.
     590
     591以上より,重複するケースを考慮すると,タスク例外処理ルーチンの実行開始
     592が必要になる可能性があるのは,以下の処理である.
     593
     594(a) タスク例外処理の許可(ena_tex)… (1)
     595(b) タスク例外処理ルーチンの出口処理 … (1)(5)(6)
     596(c) タスク例外処理の要求(ras_tex)… (2)
     597(d) タスクディスパッチ後の処理 … (3)(5)(6)
    889598        (d-1) dispatch_r
    890599        (d-2) ret_int_r
    891600        (d-3) ret_exc_r
    892601        (d-4) start_r
    893 (e) 割込みハンドラの出口処理 … (4)(5)(6)
    894 (f) CPU例外ハンドラの出口処理 … (4)(5)(6)
    895 (g) 割込み優å
    896 ˆåº¦ãƒžã‚¹ã‚¯ã®å¤‰æ›´ï¼ˆchg_ipm)… (5)
    897 (h) CPUロック状æ
    898 ‹ã®è§£é™¤ï¼ˆunl_cpu)… (6)
    899 
    900 ã“の中で(d-4)に関しては,タスクの実行開始直後はタスク例外処理禁止状æ
    901 ‹ã§
    902 ã‚り(自タスクがena_texするまでは,タスク例外が許可されない),(1)の条
    903 ä»¶ãŒæº€ãŸã•ã‚Œãªã„ため,タスク例外処理ルーチンの実行開始はå¿
    904 è¦ãªã„.
    905 
    906 ã¾ãŸ(h)に関しては,次に述べる理由により,CPUロック状æ
    907 ‹ãŒç¶™ç¶šã—ている間
    908 ã«ä»–の5つの条件が新たに満たされることはないため,タスク例外処理ルーチン
    909 ã®å®Ÿè¡Œé–‹å§‹ã¯å¿
    910 è¦ãªã„.
    911 
    912 CPUロック状æ
    913 ‹ã§ã¯ï¼Œã¾ãšï¼Œã‚¿ã‚¹ã‚¯ä¾‹å¤–処理の許可(ena_tex),タスク例外処
    914 ç†ã®è¦æ±‚(ras_tex,iras_tex),割込み優å
    915 ˆåº¦ãƒžã‚¹ã‚¯ã®å¤‰æ›´ï¼ˆchg_ipm)を行
    916 ã†ã“とはできず,タスクディスパッチも起こらない.CPUロック状æ
    917 ‹ã§ã‚¿ã‚¹ã‚¯ä¾‹
    918 å¤–処理ルーチンからリターンすることはできるが,この場合はCPUロック状æ
    919 ‹ã‚‚
    920 è§£é™¤ã•ã‚Œï¼ŒCPUロック状æ
    921 ‹ãŒç¶™ç¶šã—ない.CPUロック状æ
    922 ‹ã§å‰²è¾¼ã¿ãƒãƒ³ãƒ‰ãƒ©ã‹ã‚‰
    923 ãƒªã‚¿ãƒ¼ãƒ³ã—た場合も,これと同様である.
    924 
    925 æœ€å¾Œã«ï¼ŒCPUロック状æ
    926 ‹ã§CPU例外ハンドラからリターンした場合が問題になる.
    927 ã“れについては,CPU例外が発生した時に,CPUロック状æ
    928 ‹ã§ã‚った場合と,
    929 CPUロック解除状æ
    930 ‹ã§ã‚った場合に分けて考える.CPUロック解除状æ
    931 ‹ã§ã‚った
    932 å ´åˆã«ã¯ï¼ŒCPU例外ハンドラからのリターンにより,CPUロック状æ
    933 ‹ãŒè§£é™¤ã•ã‚Œ
    934 ã‚‹ãŸã‚ï¼Œå‰²è¾¼ã¿ãƒãƒ³ãƒ‰ãƒ©ã‹ã‚‰ãƒªã‚¿ãƒ¼ãƒ³ã—た場合と同様である.CPUロック状æ
    935 ‹ã§
    936 ã‚った場合には,起動されるCPU例外ハンドラはカーネル管理外のCPU例外ハン
    937 ãƒ‰ãƒ©ã§ã‚るため,その中で(1)~(3)と(5)の条件が新たに満たされることはない.
    938 CPU例外ハンドラの実行前後で(4)の条件は保存されることから,CPU例外ハンド
    939 ãƒ©ã‹ã‚‰ã®ãƒªã‚¿ãƒ¼ãƒ³ã«ã‚ˆã£ã¦ï¼Œ(1)~(5)の条件はCPU例外の発生前に戻り,新たに
    940 æº€ãŸã•ã‚Œã‚‹ã“とはない.
    941 
    942 â—ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンの実行開始処理
    943 
    944 ã“こでは,前の節で検討したタスク例外処理ルーチンの実行開始がå¿
    945 è¦ãªã‚¿ã‚¤
    946 ãƒŸãƒ³ã‚°ã®ãã‚Œãžã‚Œã«ã¤ã„て,実行開始処理の実è£
    947 æ–¹æ³•ã«ã¤ã„て述べる.
    948 
    949 (a) タスク例外処理の許可(ena_tex)
    950 
    951 ena_texがタスクから呼び出された場合には,自タスクに対して「タスクが実行
    952 çŠ¶æ
    953 ‹ã§ã‚る」「タスクコンテキストが実行されている」の2条件は満たされてお
    954 ã‚Šï¼Œã€Œã‚¿ã‚¹ã‚¯ä¾‹å¤–処理許可状æ
    955 ‹ã§ã‚る」の条件はena_texの処理により満たされ
    956 ã‚‹ï¼Žã¾ãŸï¼Œã€ŒCPUロック状æ
    957 ‹ã§ãªã„」の条件はena_texのå
    958 ¥å£ã§ãƒã‚§ãƒƒã‚¯ã—てい
    959 ã‚‹ï¼Žãã®ãŸã‚ï¼Œã€Œä¿ç•™ä¾‹å¤–要因が0でない」と「割込み優å
    960 ˆåº¦ãƒžã‚¹ã‚¯å
    961 ¨è§£é™¤çŠ¶æ
    962 ‹
    963 ã§ã‚る」の2条件が満たされている場合には,タスク例外処理ルーチンを呼び出
    964 ã™ï¼Ž
    965 
    966 ena_texの本体の処理(エラー処理を除く)は次の通り.
     602(e) 割込みハンドラの出口処理 … (4)(5)(6)
     603(f) CPU例外ハンドラの出口処理 … (4)(5)(6)
     604(g) 割込み優先度マスクの変更(chg_ipm)… (5)
     605(h) CPUロック状態の解除(unl_cpu)… (6)
     606
     607この中で(d-4)に関しては,タスクの実行開始直後はタスク例外処理禁止状態で
     608あり(自タスクがena_texするまでは,タスク例外が許可されない),(1)の条
     609件が満たされないため,タスク例外処理ルーチンの実行開始は必要ない.
     610
     611また(h)に関しては,次に述べる理由により,CPUロック状態が継続している間
     612に他の5つの条件が新たに満たされることはないため,タスク例外処理ルーチン
     613の実行開始は必要ない.
     614
     615CPUロック状態では,まず,タスク例外処理の許可(ena_tex),タスク例外処
     616理の要求(ras_tex,iras_tex),割込み優先度マスクの変更(chg_ipm)を行
     617うことはできず,タスクディスパッチも起こらない.CPUロック状態でタスク例
     618外処理ルーチンからリターンすることはできるが,この場合はCPUロック状態も
     619解除され,CPUロック状態が継続しない.CPUロック状態で割込みハンドラから
     620リターンした場合も,これと同様である.
     621
     622最後に,CPUロック状態でCPU例外ハンドラからリターンした場合が問題になる.
     623これについては,CPU例外が発生した時に,CPUロック状態であった場合と,
     624CPUロック解除状態であった場合に分けて考える.CPUロック解除状態であった
     625場合には,CPU例外ハンドラからのリターンにより,CPUロック状態が解除され
     626るため,割込みハンドラからリターンした場合と同様である.CPUロック状態で
     627あった場合には,起動されるCPU例外ハンドラはカーネル管理外のCPU例外ハン
     628ドラであるため,その中で(1)~(3)と(5)の条件が新たに満たされることはない.
     629CPU例外ハンドラの実行前後で(4)の条件は保存されることから,CPU例外ハンド
     630ラからのリターンによって,(1)~(5)の条件はCPU例外の発生前に戻り,新たに
     631満たされることはない.
     632
     633●タスク例外処理ルーチンの実行開始処理
     634
     635ここでは,前の節で検討したタスク例外処理ルーチンの実行開始が必要なタイ
     636ミングのそれぞれについて,実行開始処理の実装方法について述べる.
     637
     638(a) タスク例外処理の許可(ena_tex)
     639
     640ena_texがタスクから呼び出された場合には,自タスクに対して「タスクが実行
     641状態である」「タスクコンテキストが実行されている」の2条件は満たされてお
     642り,「タスク例外処理許可状態である」の条件はena_texの処理により満たされ
     643る.また,「CPUロック状態でない」の条件はena_texの入口でチェックしてい
     644る.そのため,「保留例外要因が0でない」と「割込み優先度マスク全解除状態
     645である」の2条件が満たされている場合には,タスク例外処理ルーチンを呼び出
     646す.
     647
     648ena_texの本体の処理(エラー処理を除く)は次の通り.
    967649
    968650----------------------------------------
     
    973655----------------------------------------
    974656
    975 (b) タスク例外処理ルーチンの出口処理
    976 
    977 ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンの出口処理(call_texrtnの後半)では,自タスクに対
    978 ã—て「タスクが実行状æ
    979 ‹ã§ã‚る」「タスクコンテキストが実行されている」の
    980 2条件は満たされており,「タスク例外処理許可状æ
    981 ‹ã§ã‚る」「割込み優å
    982 ˆåº¦ãƒž
    983 ã‚¹ã‚¯å
    984 ¨è§£é™¤çŠ¶æ
    985 ‹ã§ã‚る」「CPUロック状æ
    986 ‹ã§ãªã„」の3条件が出口処理で満たさ
    987 ã‚Œã‚‹ï¼Žãã®ãŸã‚ï¼Œã€Œä¿ç•™ä¾‹å¤–要因が0でない」が満たされている場合には,タス
    988 ã‚¯ä¾‹å¤–処理ルーチンを呼び出すå¿
    989 è¦ãŒã‚る.
    990 
    991 ãŸã ã—,タスク例外処理ルーチンの出口処理で単純にcall_texrtnを呼び出すと,
    992 call_texrtnの中からcall_texrtnを呼び出すことになり,タスク例外処理が繰
    993 ã‚Šè¿”し要求された場合に,スタックの使用量に上限がなくなる.そこで,タス
    994 ã‚¯ä¾‹å¤–処理ルーチンの出口処理で「保留例外要因が0でない」場合には,
    995 call_texrtnの中でループさせる.
    996 
    997 ä¿®æ­£ã—たcall_texrtnの流れは次の通り.
     657(b) タスク例外処理ルーチンの出口処理
     658
     659タスク例外処理ルーチンの出口処理(call_texrtnの後半)では,自タスクに対
     660して「タスクが実行状態である」「タスクコンテキストが実行されている」の
     6612条件は満たされており,「タスク例外処理許可状態である」「割込み優先度マ
     662スク全解除状態である」「CPUロック状態でない」の3条件が出口処理で満たさ
     663れる.そのため,「保留例外要因が0でない」が満たされている場合には,タス
     664ク例外処理ルーチンを呼び出す必要がある.
     665
     666ただし,タスク例外処理ルーチンの出口処理で単純にcall_texrtnを呼び出すと,
     667call_texrtnの中からcall_texrtnを呼び出すことになり,タスク例外処理が繰
     668り返し要求された場合に,スタックの使用量に上限がなくなる.そこで,タス
     669ク例外処理ルーチンの出口処理で「保留例外要因が0でない」場合には,
     670call_texrtnの中でループさせる.
     671
     672修正したcall_texrtnの流れは次の通り.
    998673
    999674----------------------------------------
     
    1003678        TEXPTN  texptn;
    1004679
    1005         ディスパッチ禁止フラグを保存する … (*3)
    1006         タスク例外処理禁止状æ
    1007 ‹ã«ã™ã‚‹ … (*6)
     680        ディスパッチ禁止フラグを保存する … (*3)
     681        タスク例外処理禁止状態にする … (*6)
    1008682
    1009683        do {
     
    1011685                p_runtsk->texptn = 0U;
    1012686
    1013                 CPUロック解除状æ
    1014 ‹ã«ã™ã‚‹
    1015                 タスク例外処理ルーチンを呼び出す
    1016                 CPUロック状æ
    1017 ‹ã«ã™ã‚‹
    1018 
    1019                 割込み優å
    1020 ˆåº¦ãƒžã‚¹ã‚¯å
    1021 ¨è§£é™¤çŠ¶æ
    1022 ‹ã«ã™ã‚‹
    1023                 ディスパッチ禁止フラグをå
    1024 ƒã«æˆ»ã™ … (*4)
    1025                 タスク例外処理禁止状æ
    1026 ‹ã«ã™ã‚‹ … (*2)
    1027 
    1028                 å¿
    1029 è¦ãªå ´åˆã«ã¯ãƒ‡ã‚£ã‚¹ãƒ‘ッチを行う … (*1)
     687                CPUロック解除状態にする
     688                タスク例外処理ルーチンを呼び出す
     689                CPUロック状態にする
     690
     691                割込み優先度マスク全解除状態にする
     692                ディスパッチ禁止フラグを元に戻す … (*4)
     693                タスク例外処理禁止状態にする … (*2)
     694
     695                必要な場合にはディスパッチを行う … (*1)
    1030696        }  while (p_runtsk->texptn != 0U);
    1031697
    1032         タスク例外処理許可状æ
    1033 ‹ã«ã™ã‚‹ … (*5)
     698        タスク例外処理許可状態にする … (*5)
    1034699}
    1035700----------------------------------------
    1036701
    1037 ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンの呼出し前にディスパッチ禁止フラグを保存する処理
    1038 ã¯ï¼Œ(*4)においてå
    1039 ƒã®çŠ¶æ
    1040 ‹ã«æˆ»ã™ã“とから,ループの外(*3)で行うのが効率が
    1041 ã‚ˆã„.
    1042 
    1043 ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンの呼出し前にタスク例外処理禁止状æ
    1044 ‹ã«ã™ã‚‹å‡¦ç†ã¯ï¼Œ
    1045 (*2)においてタスク例外処理禁止状æ
    1046 ‹ã«ã™ã‚‹ã“とから,ループ外(*6)で行うの
    1047 ãŒåŠ¹çŽ‡ãŒã‚ˆã„.また,タスク例外処理ルーチンの呼出し後にタスク例外処理許
    1048 å¯çŠ¶æ
    1049 ‹ã«ã™ã‚‹å‡¦ç†ã‚‚,ループの外(*5)で行う方が効率がよい.
    1050 
    1051 (c) タスク例外処理の要求(ras_tex)
    1052 
    1053 ras_texがタスクから呼び出された場合で,対象タスクが自タスクの場合には,
    1054 è‡ªã‚¿ã‚¹ã‚¯ã«å¯¾ã—て「タスクが実行状æ
    1055 ‹ã§ã‚る」「タスクコンテキストが実行さ
    1056 ã‚Œã¦ã„る」の2条件は満たされており,「保留例外要因が0でない」の条件は
    1057 ras_texの処理により満たされる(ras_texのパラメータrasptnが0の場合はエラー
    1058 ã¨ãªã‚‹ãŸã‚ï¼‰ï¼Žã¾ãŸï¼Œã€ŒCPUロック状æ
    1059 ‹ã§ãªã„」の条件はras_texのå
    1060 ¥å£ã§ãƒã‚§ãƒƒ
    1061 ã‚¯ã—ている.そのため,対象タスクが自タスクであり,「タスク例外処理許可
    1062 çŠ¶æ
    1063 ‹ã§ã‚る」と「割込み優å
    1064 ˆåº¦ãƒžã‚¹ã‚¯å
    1065 ¨è§£é™¤çŠ¶æ
    1066 ‹ã§ã‚る」の2条件が満たされて
    1067 ã„る場合には,タスク例外処理ルーチンを呼び出す.
    1068 
    1069 ras_texの本体の処理(エラー処理を除く)は次の通り.
     702タスク例外処理ルーチンの呼出し前にディスパッチ禁止フラグを保存する処理
     703は,(*4)において元の状態に戻すことから,ループの外(*3)で行うのが効率が
     704よい.
     705
     706タスク例外処理ルーチンの呼出し前にタスク例外処理禁止状態にする処理は,
     707(*2)においてタスク例外処理禁止状態にすることから,ループ外(*6)で行うの
     708が効率がよい.また,タスク例外処理ルーチンの呼出し後にタスク例外処理許
     709可状態にする処理も,ループの外(*5)で行う方が効率がよい.
     710
     711(c) タスク例外処理の要求(ras_tex)
     712
     713ras_texがタスクから呼び出された場合で,対象タスクが自タスクの場合には,
     714自タスクに対して「タスクが実行状態である」「タスクコンテキストが実行さ
     715れている」の2条件は満たされており,「保留例外要因が0でない」の条件は
     716ras_texの処理により満たされる(ras_texのパラメータrasptnが0の場合はエラー
     717となるため).また,「CPUロック状態でない」の条件はras_texの入口でチェッ
     718クしている.そのため,対象タスクが自タスクであり,「タスク例外処理許可
     719状態である」と「割込み優先度マスク全解除状態である」の2条件が満たされて
     720いる場合には,タスク例外処理ルーチンを呼び出す.
     721
     722ras_texの本体の処理(エラー処理を除く)は次の通り.
    1070723
    1071724----------------------------------------
     
    1078731(d-1) dispatch_r
    1079732
    1080 dispatch_rにおいては,dispatch_rからのリターンå
    1081 ˆã®ã‚¿ã‚¹ã‚¯ã«å¯¾ã—て,「タ
    1082 ã‚¹ã‚¯ãŒå®Ÿè¡ŒçŠ¶æ
    1083 ‹ã§ã‚る」「タスクコンテキストが実行されている」の2条件は満
    1084 ãŸã•ã‚Œã¦ã„る.また,CPUロック状æ
    1085 ‹ã§dispatch_rに来ることはないため,
    1086 ã€ŒCPUロック状æ
    1087 ‹ã§ãªã„」の条件も成立している.そのため,「タスク例外処理
    1088 è¨±å¯çŠ¶æ
    1089 ‹ã§ã‚る」「保留例外要因が0でない」「割込み優å
    1090 ˆåº¦ãƒžã‚¹ã‚¯å
    1091 ¨è§£é™¤çŠ¶æ
    1092 ‹
    1093 ã§ã‚る」の3条件が満たされている場合には,タスク例外処理ルーチンを呼び出
    1094 ã™å¿
    1095 è¦ãŒã‚る.
    1096 
    1097 ã“れを実現するために,タスクコンテキストからのディスパッチ処理を次のよ
    1098 ã†ã«ä¿®æ­£ã™ã‚‹ï¼Ž
     733dispatch_rにおいては,dispatch_rからのリターン先のタスクに対して,「タ
     734スクが実行状態である」「タスクコンテキストが実行されている」の2条件は満
     735たされている.また,CPUロック状態でdispatch_rに来ることはないため,
     736「CPUロック状態でない」の条件も成立している.そのため,「タスク例外処理
     737許可状態である」「保留例外要因が0でない」「割込み優先度マスク全解除状態
     738である」の3条件が満たされている場合には,タスク例外処理ルーチンを呼び出
     739す必要がある.
     740
     741これを実現するために,タスクコンテキストからのディスパッチ処理を次のよ
     742うに修正する.
    1099743
    1100744----------------------------------------
     
    1102746dispatch(void)
    1103747{
    1104         ………
     748        ………
    1105749
    1106750  dispatch_r:
    1107         スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
     751        スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
    1108752        calltex();
    1109753}
    1110754----------------------------------------
    1111755
    1112 ã“こでcalltexは,「タスク例外処理許可状æ
    1113 ‹ã§ã‚る」「保留例外要因が0でな
    1114 ã„」「割込み優å
    1115 ˆåº¦ãƒžã‚¹ã‚¯å
    1116 ¨è§£é™¤çŠ¶æ
    1117 ‹ã§ã‚る」の3条件が満たされている場合に
    1118 call_texrtnを呼び出す関数である.
     756ここでcalltexは,「タスク例外処理許可状態である」「保留例外要因が0でな
     757い」「割込み優先度マスク全解除状態である」の3条件が満たされている場合に
     758call_texrtnを呼び出す関数である.
    1119759
    1120760----------------------------------------
     
    1130770(d-2) ret_int_r
    1131771
    1132 ret_int_rは,割込みハンドラの出口処理でディスパッチを行ったタスクが,実
    1133 è¡Œã‚’再開する際の処理である.そのため,ret_int_rからのリターンå
    1134 ˆã®ã‚¿ã‚¹ã‚¯
    1135 ã«å¯¾ã—て,「タスクが実行状æ
    1136 ‹ã§ã‚る」「タスクコンテキストが実行されてい
    1137 ã‚‹ã€ã®2条件は満たされている.また,CPUロック状æ
    1138 ‹ã§ret_int_rに来ることは
    1139 ãªã„ため,「CPUロック状æ
    1140 ‹ã§ãªã„」の条件も成立している.そのため,「タス
    1141 ã‚¯ä¾‹å¤–処理許可状æ
    1142 ‹ã§ã‚る」「保留例外要因が0でない」「(割込みハンドラか
    1143 ã‚‰ã®ãƒªã‚¿ãƒ¼ãƒ³å¾Œã«ï¼‰å‰²è¾¼ã¿å„ªå
    1144 ˆåº¦ãƒžã‚¹ã‚¯å
    1145 ¨è§£é™¤çŠ¶æ
    1146 ‹ã§ã‚る」の3条件が満たされ
    1147 ã¦ã„る場合には,タスク例外処理ルーチンを呼び出すå¿
    1148 è¦ãŒã‚る.
    1149 
    1150 ã“れを実現するために,割込みハンドラの出å
    1151 ¥å£å‡¦ç†ã‚’次のように修正する.
     772ret_int_rは,割込みハンドラの出口処理でディスパッチを行ったタスクが,実
     773行を再開する際の処理である.そのため,ret_int_rからのリターン先のタスク
     774に対して,「タスクが実行状態である」「タスクコンテキストが実行されてい
     775る」の2条件は満たされている.また,CPUロック状態でret_int_rに来ることは
     776ないため,「CPUロック状態でない」の条件も成立している.そのため,「タス
     777ク例外処理許可状態である」「保留例外要因が0でない」「(割込みハンドラか
     778らのリターン後に)割込み優先度マスク全解除状態である」の3条件が満たされ
     779ている場合には,タスク例外処理ルーチンを呼び出す必要がある.
     780
     781これを実現するために,割込みハンドラの出入口処理を次のように修正する.
    1152782
    1153783----------------------------------------
    1154784void
    1155 <割込みの出å
    1156 ¥å£å‡¦ç†>(void)
     785<割込みの出入口処理>(void)
    1157786{
    1158                 ………
     787                ………
    1159788
    1160789                          ret_int_r:
    1161                                 スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
     790                                スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
    1162791                                calltex();
    1163792                        }
    1164                 ………
     793                ………
    1165794}
    1166795----------------------------------------
     
    1168797(d-3) ret_exc_r
    1169798
    1170 ret_exc_rは,CPU例外ハンドラの出口処理でディスパッチを行ったタスクが,
    1171 å®Ÿè¡Œã‚’再開する際の処理である.
    1172 
    1173 ã‚«ãƒ¼ãƒãƒ«ç®¡ç†ã®CPU例外ハンドラの出口処理(ret_exc)は,割込みハンドラの
    1174 å‡ºå£å‡¦ç†ï¼ˆret_int)と同様である.これは,CPUロック状æ
    1175 ‹ã§CPU例外が発生し
    1176 ãŸå ´åˆã«ã¯ï¼Œã‚«ãƒ¼ãƒãƒ«ç®¡ç†å¤–のCPU例外ハンドラとなり,CPU例外ハンドラの出
    1177 å£å‡¦ç†ã§ãƒ‡ã‚£ã‚¹ãƒ‘ッチを行うことはなく,ret_excにも来ないためである.その
    1178 ãŸã‚ï¼Œret_exc_rからのリターンå
    1179 ˆã®ã‚¿ã‚¹ã‚¯ã«å¯¾ã—て,「CPUロック状æ
    1180 ‹ã§ãªã„」
    1181 ã®æ¡ä»¶ãŒæˆç«‹ã—ている.
    1182 
    1183 ã“のことから,CPU例外ハンドラの出å
    1184 ¥å£å‡¦ç†ã«ã¤ã„ても,割込みハンドラの出
    1185 å
    1186 ¥å£å‡¦ç†ã¨åŒæ§˜ã«ï¼Œæ¬¡ã®ã‚ˆã†ã«ä¿®æ­£ã™ã‚Œã°ã‚ˆã„.
     799ret_exc_rは,CPU例外ハンドラの出口処理でディスパッチを行ったタスクが,
     800実行を再開する際の処理である.
     801
     802カーネル管理のCPU例外ハンドラの出口処理(ret_exc)は,割込みハンドラの
     803出口処理(ret_int)と同様である.これは,CPUロック状態でCPU例外が発生し
     804た場合には,カーネル管理外のCPU例外ハンドラとなり,CPU例外ハンドラの出
     805口処理でディスパッチを行うことはなく,ret_excにも来ないためである.その
     806ため,ret_exc_rからのリターン先のタスクに対して,「CPUロック状態でない」
     807の条件が成立している.
     808
     809このことから,CPU例外ハンドラの出入口処理についても,割込みハンドラの出
     810入口処理と同様に,次のように修正すればよい.
    1187811
    1188812----------------------------------------
    1189813void
    1190 <CPU例外の出å
    1191 ¥å£å‡¦ç†>(void)
     814<CPU例外の出入口処理>(void)
    1192815{
    1193                         ………
     816                        ………
    1194817
    1195818                                  ret_exc_r:
    1196                                         スクラッチレジスタを除くすべてのレジスタを
    1197                                                                                                 スタックから復帰する
     819                                        スクラッチレジスタを除くすべてのレジスタを
     820                                                                                                スタックから復帰する
    1198821                                        calltex();
    1199822                                }
    1200                         ………
     823                        ………
    1201824}
    1202825----------------------------------------
    1203826
    1204 (e) 割込みハンドラの出口処理
    1205 
    1206 å‰²è¾¼ã¿ãƒãƒ³ãƒ‰ãƒ©ã‹ã‚‰ã‚¿ã‚¹ã‚¯ã¸ãƒªã‚¿ãƒ¼ãƒ³ã™ã‚‹å ´åˆã«ã¯ï¼Œãƒªã‚¿ãƒ¼ãƒ³å
    1207 ˆã®ã‚¿ã‚¹ã‚¯ã«å¯¾
    1208 ã—て,「タスクが実行状æ
    1209 ‹ã§ã‚る」「タスクコンテキストが実行されている」
    1210 ã®2条件は満たされている.また,CPUロック状æ
    1211 ‹ã§å‰²è¾¼ã¿ãƒãƒ³ãƒ‰ãƒ©ãŒå®Ÿè¡Œã•ã‚Œ
    1212 ã‚‹ã“とはないため,「CPUロック状æ
    1213 ‹ã§ãªã„」の条件も成立している.そのため,
    1214 ã€Œã‚¿ã‚¹ã‚¯ä¾‹å¤–処理許可状æ
    1215 ‹ã§ã‚る」「保留例外要因が0でない」「(割込みハン
    1216 ãƒ‰ãƒ©ã‹ã‚‰ã®ãƒªã‚¿ãƒ¼ãƒ³å¾Œã«ï¼‰å‰²è¾¼ã¿å„ªå
    1217 ˆåº¦ãƒžã‚¹ã‚¯å
    1218 ¨è§£é™¤çŠ¶æ
    1219 ‹ã§ã‚る」の3条件が満
    1220 ãŸã•ã‚Œã¦ã„る場合には,タスク例外処理ルーチンを呼び出すå¿
    1221 è¦ãŒã‚る.
    1222 
    1223 å‰²è¾¼ã¿ãƒãƒ³ãƒ‰ãƒ©ã®å‘¼å‡ºã—前と呼出し後でこれらの条件が変化するのは,実行状
    1224 æ
    1225 ‹ã®ã‚¿ã‚¹ã‚¯ãŒå¤‰åŒ–した時と,割込みハンドラ中でiras_texが呼び出された場合
    1226 ã§ã‚る.割込みハンドラからはena_texとchg_ipmは呼び出せないため,「タス
    1227 ã‚¯ä¾‹å¤–処理許可状æ
    1228 ‹ã§ã‚る」と「(割込みハンドラからのリターン後に)割込
    1229 ã¿å„ªå
    1230 ˆåº¦ãƒžã‚¹ã‚¯å
    1231 ¨è§£é™¤çŠ¶æ
    1232 ‹ã§ã‚る」の2条件が変化することはない.
    1233 
    1234 ã“の2つの状況のå†
    1235 ï¼Œå®Ÿè¡ŒçŠ¶æ
    1236 ‹ã®ã‚¿ã‚¹ã‚¯ãŒå¤‰åŒ–するケースは,ret_int_rで考æ
    1237 ®
    1238 æ¸ˆã¿ã§ã‚る.割込みハンドラ中でiras_texが呼び出された場合には,reqflgが
    1239 trueになるため,タスク例外処理ルーチンの実行開始処理は,reqflgがtrueの
    1240 æ™‚にのみ行えばよい.
    1241 
    1242 ã“れを実現するために,上で修正した割込みハンドラの出å
    1243 ¥å£å‡¦ç†ã‚’,さらに
    1244 æ¬¡ã®ã‚ˆã†ã«ä¿®æ­£ã™ã‚‹ï¼Ž
     827(e) 割込みハンドラの出口処理
     828
     829割込みハンドラからタスクへリターンする場合には,リターン先のタスクに対
     830して,「タスクが実行状態である」「タスクコンテキストが実行されている」
     831の2条件は満たされている.また,CPUロック状態で割込みハンドラが実行され
     832ることはないため,「CPUロック状態でない」の条件も成立している.そのため,
     833「タスク例外処理許可状態である」「保留例外要因が0でない」「(割込みハン
     834ドラからのリターン後に)割込み優先度マスク全解除状態である」の3条件が満
     835たされている場合には,タスク例外処理ルーチンを呼び出す必要がある.
     836
     837割込みハンドラの呼出し前と呼出し後でこれらの条件が変化するのは,実行状
     838態のタスクが変化した時と,割込みハンドラ中でiras_texが呼び出された場合
     839である.割込みハンドラからはena_texとchg_ipmは呼び出せないため,「タス
     840ク例外処理許可状態である」と「(割込みハンドラからのリターン後に)割込
     841み優先度マスク全解除状態である」の2条件が変化することはない.
     842
     843この2つの状況の内,実行状態のタスクが変化するケースは,ret_int_rで考慮
     844済みである.割込みハンドラ中でiras_texが呼び出された場合には,reqflgが
     845trueになるため,タスク例外処理ルーチンの実行開始処理は,reqflgがtrueの
     846時にのみ行えばよい.
     847
     848これを実現するために,上で修正した割込みハンドラの出入口処理を,さらに
     849次のように修正する.
    1245850
    1246851----------------------------------------
    1247852void
    1248 <割込みの出å
    1249 ¥å£å‡¦ç†>(void)
     853<割込みの出入口処理>(void)
    1250854{
    1251         ………
    1252 
    1253         if (タスクコンテキストで割込み発生) {
    1254                 ………
     855        ………
     856
     857        if (タスクコンテキストで割込み発生) {
     858                ………
    1255859                if (reqflg) {
    1256                         ………
     860                        ………
    1257861
    1258862                          ret_int_r:
    1259                                 スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
     863                                スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
    1260864                        }
    1261865                        calltex();
    1262866                }
    1263867        }
    1264         ………
     868        ………
    1265869}
    1266870----------------------------------------
    1267871
    1268 (f) CPU例外ハンドラの出口処理
    1269 
    1270 ã‚«ãƒ¼ãƒãƒ«ç®¡ç†ã®CPU例外ハンドラの出口処理は,割込みハンドラの出口処理と同
    1271 æ§˜ã§ã‚る.
    1272 
    1273 ã‚«ãƒ¼ãƒãƒ«ç®¡ç†å¤–のCPU例外ハンドラの中では,実行状æ
    1274 ‹ã®ã‚¿ã‚¹ã‚¯ãŒå¤‰åŒ–すること
    1275 ã¯ãªãï¼Œiras_texやena_texを呼び出すこともできないため,タスク例外処理ルー
    1276 ãƒãƒ³ã®å®Ÿè¡Œé–‹å§‹æ¡ä»¶ãŒæ–°ãŸã«æº€ãŸã•ã‚Œã‚‹ã“とはなく,タスク例外処理ルーチン
    1277 ã®å®Ÿè¡Œé–‹å§‹ã¯å¿
    1278 è¦ãªã„.
    1279 
    1280 ã“のことから,CPU例外ハンドラの出å
    1281 ¥å£å‡¦ç†ã«ã¤ã„ても,割込みハンドラの出
    1282 å
    1283 ¥å£å‡¦ç†ã¨åŒæ§˜ã«ï¼Œæ¬¡ã®ã‚ˆã†ã«ä¿®æ­£ã™ã‚Œã°ã‚ˆã„.
     872(f) CPU例外ハンドラの出口処理
     873
     874カーネル管理のCPU例外ハンドラの出口処理は,割込みハンドラの出口処理と同
     875様である.
     876
     877カーネル管理外のCPU例外ハンドラの中では,実行状態のタスクが変化すること
     878はなく,iras_texやena_texを呼び出すこともできないため,タスク例外処理ルー
     879チンの実行開始条件が新たに満たされることはなく,タスク例外処理ルーチン
     880の実行開始は必要ない.
     881
     882このことから,CPU例外ハンドラの出入口処理についても,割込みハンドラの出
     883入口処理と同様に,次のように修正すればよい.
    1284884
    1285885----------------------------------------
    1286886void
    1287 <CPU例外の出å
    1288 ¥å£å‡¦ç†>(void)
     887<CPU例外の出入口処理>(void)
    1289888{
    1290                 ………
    1291                 if (タスクコンテキストでCPU例外発生) {
    1292                 ………
     889                ………
     890                if (タスクコンテキストでCPU例外発生) {
     891                ………
    1293892                        if (reqflg) {
    1294893
    1295894                                  ret_exc_r:
    1296                                         スクラッチレジスタを除くすべてのレジスタを
    1297                                                                                                 スタックから復帰する
     895                                        スクラッチレジスタを除くすべてのレジスタを
     896                                                                                                スタックから復帰する
    1298897                                }
    1299898                                calltex();
    1300899                        }
    1301900                }
    1302                 ………
     901                ………
    1303902}
    1304903----------------------------------------
    1305904
    1306 (g) 割込み優å
    1307 ˆåº¦ãƒžã‚¹ã‚¯ã®å¤‰æ›´
    1308 
    1309 chg_ipmがタスクから呼び出された場合には,自タスクに対して「タスクが実行
    1310 çŠ¶æ
    1311 ‹ã§ã‚る」「タスクコンテキストが実行されている」の2条件は満たされてい
    1312 ã‚‹ï¼Žã¾ãŸï¼Œã€ŒCPUロック状æ
    1313 ‹ã§ãªã„」の条件はchg_ipmのå
    1314 ¥å£ã§ãƒã‚§ãƒƒã‚¯ã—てい
    1315 ã‚‹ï¼Žãã®ãŸã‚ï¼Œãƒ‘ラメータintpriがTIPM_ENAALLであり,「タスク例外処理許可
    1316 çŠ¶æ
    1317 ‹ã§ã‚る」「保留例外要因が0でない」の2条件が満たされている場合には,
    1318 ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンを呼び出す.
    1319 
    1320 chg_ipmの関連部分の処理は次の通り.
     905(g) 割込み優先度マスクの変更
     906
     907chg_ipmがタスクから呼び出された場合には,自タスクに対して「タスクが実行
     908状態である」「タスクコンテキストが実行されている」の2条件は満たされてい
     909る.また,「CPUロック状態でない」の条件はchg_ipmの入口でチェックしてい
     910る.そのため,パラメータintpriがTIPM_ENAALLであり,「タスク例外処理許可
     911状態である」「保留例外要因が0でない」の2条件が満たされている場合には,
     912タスク例外処理ルーチンを呼び出す.
     913
     914chg_ipmの関連部分の処理は次の通り.
    1321915
    1322916----------------------------------------
     
    1324918        if (intpri == TIPM_ENAALL) {
    1325919                ipmflg = true;
    1326                 ここにタスク切換え処理がå
    1327 ¥ã‚‹
     920                ここにタスク切換え処理が入る
    1328921                if (p_runtsk->enatex && p_runtsk->texptn != 0U) {
    1329922                        call_texrtn();
     
    1332925----------------------------------------
    1333926
    1334 dispatchを呼び出してタスク切換えを行う場合には,dispatchの出口でタスク
    1335 ä¾‹å¤–処理ルーチンを呼び出すためここで呼出し処理を行うå¿
    1336 è¦ã¯ãªã„が,コー
    1337 ãƒ‰ãŒè¤‡é›‘になるため,dispatchを呼び出した場合もここでタスク例外処理ルー
    1338 ãƒãƒ³ã®å‘¼å‡ºã—処理を行っている.
    1339 
    1340 â—call_texrtnからdispatchを呼び出す処理について
    1341 
    1342 dispatch_rから(ターゲットによってはcalltexを経由して)call_texrtnを呼
    1343 ã³å‡ºã—,call_texrtnからdispatchを呼び出すため,この2つの関数は相互再帰
    1344 å‘¼å‡ºã—をしている.ここでは,この実è£
    1345 ã§æ”¯éšœã®ãªã„理由を説明する.
    1346 
    1347 call_texrtnからdispatchを呼び出すのは,ディスパッチが保留されていない状
    1348 æ
    1349 ‹ã§å‘¼ã³å‡ºã•ã‚ŒãŸã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンが,その実行中にディスパッチ保留
    1350 çŠ¶æ
    1351 ‹ã«é·ç§»ã—,さらにタスクディスパッチをå¿
    1352 è¦ã¨ã™ã‚‹å‡¦ç†ã‚’行い,ディスパッ
    1353 ãƒä¿ç•™çŠ¶æ
    1354 ‹ã‚’解除しないままリターンした場合である.この場合,call_texrtn
    1355 ã®ä¸­ã§ãƒ‡ã‚£ã‚¹ãƒ‘ッチ保留状æ
    1356 ‹ã‚’解除した後に,dispatchを呼び出してタスクディ
    1357 ã‚¹ãƒ‘ッチを行う.つまり,call_texrtnからdispatchを呼び出す処理は,タスク
    1358 ä¾‹å¤–処理ルーチンの中でディスパッチ保留状æ
    1359 ‹ã‚’解除すべきであったのを,解
    1360 é™¤ã›ãšã«ãƒªã‚¿ãƒ¼ãƒ³ã—た場合を救済するためのものである.以下,この振舞いを
    1361 ã€Œæ•‘済ケース」と呼ぶ.
    1362 
    1363 ãã“で,比較のために,タスク例外処理ルーチンの最後で,正しくディスパッ
    1364 ãƒä¿ç•™çŠ¶æ
    1365 ‹ã‚’解除してからリターンした場合の振舞いを考える.この場合には,
    1366 ãƒ‡ã‚£ã‚¹ãƒ‘ッチ保留状æ
    1367 ‹ã‚’解除するサービスコール(ena_dsp,chg_ipm)の中で,
    1368 dispatchが呼び出されてタスクディスパッチが起こる.以下,この振舞いを
    1369 ã€Œæ­£å¸¸ã‚±ãƒ¼ã‚¹ã€ã¨å‘¼ã¶ï¼Ž
    1370 
    1371 æ­£å¸¸ã‚±ãƒ¼ã‚¹ã¨æ•‘済ケースを比較すると,call_texrtn→タスク例外処理ルーチン
    1372 â†’サービスコール→dispatchの順でdispatchが呼び出されるか,call_texrtnか
    1373 ã‚‰ç›´æŽ¥dispatchが呼び出されるかの違いということになり,救済ケースの方が
    1374 ã‚¹ã‚¿ãƒƒã‚¯ã®ä½¿ç”¨é‡ã¯å°‘ない.つまり,正常ケースの動きを想定してスタック領
    1375 åŸŸãŒç”¨æ„ã—てあれば,救済ケースでも問題なく動作することになる.
    1376 
    1377 ã“こで,正常ケースと救済ケースで,上記以外に違いがないことが重要である.
    1378 å
    1379 ·ä½“的には,call_texrtnの中で,タスク例外処理許可状æ
    1380 ‹ã«ã™ã‚‹ï¼ˆp_runtsk
    1381 ->enatexをtrueにする)前に,dispatchを呼び出すことが重要である.タスク
    1382 ä¾‹å¤–処理許可状æ
    1383 ‹ã«ã—た後にdispatchを呼び出すと,出口のdispatch_rで,再
    1384 ã³ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンを実行してしまう可能性があり,救済ケースの方が
    1385 ã‚¹ã‚¿ãƒƒã‚¯ã®ä½¿ç”¨é‡ãŒå¢—えてしまう.
    1386 
    1387 ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンの中で,タスク例外処理許可状æ
    1388 ‹ã«ã—たままリターン
    1389 ã—た場合には,call_texrtnから呼び出したdispatchの出口のdispatch_rで再び
    1390 ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理ルーチンを実行してしまう可能性がある.この場合も,タスク
    1391 ä¾‹å¤–処理ルーチンの最後で,ディスパッチ保留状æ
    1392 ‹ã‚’解除してからリターンし
    1393 ãŸå ´åˆã‚ˆã‚Šã¯ã‚¹ã‚¿ãƒƒã‚¯ã®ä½¿ç”¨é‡ãŒå°‘ないが,タスク例外処理禁止状æ
    1394 ‹ã«ã—た後
    1395 ã«ãƒ‡ã‚£ã‚¹ãƒ‘ッチ保留状æ
    1396 ‹ã‚’解除してリターンした場合よりは,スタックの使用
    1397 é‡ãŒå¢—える場合がある.そこで,このような状況が起こらないように,
    1398 dispatchを呼ぶ前にp_runtsk->enatexをfalseにする.
    1399 
    1400 
    1401 â—‹ã‚¨ãƒ©ãƒ¼ã®ãƒã‚§ãƒƒã‚¯é †åº
    1402 
    1403 ã‚µãƒ¼ãƒ“スコールå†
    1404 ã«ãŠã‘るエラーチェックは,以下の順序で行うことを原則と
    1405 ã™ã‚‹ï¼ŽãªãŠï¼Œã“の節には,保護機能対応カーネルに関する記述が含まれている
    1406 ãŒï¼Œãã‚Œã‚‰ã®è¨˜è¿°ã¯å°†æ¥çš„にはより適切なドキュメントに移動する予定である.
    1407 
    1408 â—ã‚¨ãƒ©ãƒ¼ã®3分類
    1409 
    1410 ã‚µãƒ¼ãƒ“スコールのエラーは,大きく以下の3つに分類することができる.
    1411 
    1412 (a) 静的エラー
    1413 
    1414 å¯¾è±¡ã®ã‚«ãƒ¼ãƒãƒ«ã‚ªãƒ–ジェクトが登録されているか否かや,その状æ
    1415 ‹ã«ä¾å­˜ã›ãš
    1416 ã«ï¼Œãƒã‚§ãƒƒã‚¯ã™ã‚‹ã“とができるエラー.
    1417 
    1418 (b) 準静的エラー
    1419 
    1420 å¯¾è±¡ã®ã‚«ãƒ¼ãƒãƒ«ã‚ªãƒ–ジェクトが登録されていれば,その状æ
    1421 ‹ã«ä¾å­˜ã›ãšã«ãƒã‚§ãƒƒ
    1422 ã‚¯ã™ã‚‹ã“とができるエラー.
    1423 
    1424 (c) 動的エラー
    1425 
    1426 å¯¾è±¡ã®ã‚«ãƒ¼ãƒãƒ«ã‚ªãƒ–ジェクトの状æ
    1427 ‹ã«ä¾å­˜ã™ã‚‹ã‚¨ãƒ©ãƒ¼ï¼Ž
    1428 
    1429 ASPカーネルにおいては,(a)と(b)のエラーはクリティカルセクションの外側で,
    1430 ã“の順序でチェックし,(c)のエラーはクリティカルセクションのå†
    1431 å´ã§ãƒã‚§ãƒƒ
    1432 ã‚¯ã™ã‚‹ï¼ŽãŸã ã—,動的生成機能拡張パッケージでは,(b)のエラー(の一部)は
    1433 ã‚¯ãƒªãƒ†ã‚£ã‚«ãƒ«ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã®å†
    1434 å´ã§å®Ÿæ–½ã™ã‚‹å¿
    1435 è¦ãŒã‚る.
    1436 
    1437 â—é™çš„エラーのチェック順序
    1438 
    1439 é™çš„エラーには,実行コンテキストのエラー(ディスパッチ保留状æ
    1440 ‹ã‹ã‚‰ã®å‘¼
    1441 å‡ºã—エラーも含む),パラメータの範囲等のエラー(対象のカーネルオブジェ
    1442 ã‚¯ãƒˆã«ä¾å­˜ã›ãšã«ãƒã‚§ãƒƒã‚¯ã§ãã‚‹ã‚‚の)が含まれる.
    1443 
    1444 ã‚µãƒ¼ãƒ“スコール中では,最初に実行コンテキストのエラーをチェックし,その
    1445 å¾Œï¼Œãƒ‘ラメータの並び順に,範囲等のエラーをチェックする.
    1446 
    1447 ä¿è­·æ©Ÿèƒ½å¯¾å¿œã‚«ãƒ¼ãƒãƒ«ã§ã¯ï¼Œãƒ‘ラメータがポインタである場合に,ポインタの
    1448 æŒ‡ã™ãƒ¡ãƒ¢ãƒªé ˜åŸŸãŒã‚¢ã‚¯ã‚»ã‚¹å¯èƒ½ã§ã‚るかをチェックするå¿
    1449 è¦ãŒã‚るが,メモリ
    1450 é ˜åŸŸã®è¨­å®šãŒé™çš„である場合には,このエラーチェックもここで実施する.た
    1451 ã ã—,メモリ領域の設定が静的でない場合には,このエラーチェックはクリティ
    1452 ã‚«ãƒ«ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã®å†
    1453 å´ã§è¡Œã†å¿
    1454 è¦ãŒã‚る.
    1455 
    1456 â—å‡†é™çš„エラーのチェック順序
    1457 
    1458 å‡†é™çš„エラーのチェックの前に,対象のカーネルオブジェクトの管理ブロック
    1459 ã®å
    1460 ˆé ­ç•ªåœ°ã‚’,ローカル変数に代å
    1461 ¥ã™ã‚‹ï¼Ž
    1462 
    1463 ä¿è­·æ©Ÿèƒ½å¯¾å¿œã‚«ãƒ¼ãƒãƒ«ã§ã¯ï¼Œã“の次に,対象のカーネルオブジェクトがアクセ
    1464 ã‚¹å¯èƒ½ã§ã‚るかをチェックする処理を行う.当該サービスコールの呼出しが,
    1465 ã‚·ã‚¹ãƒ†ãƒ çŠ¶æ
    1466 ‹ã«å¯¾ã™ã‚‹ã‚¢ã‚¯ã‚»ã‚¹è¨±å¯ãƒ™ã‚¯ã‚¿ã§ä¿è­·ã•ã‚Œã¦ã„る場合にも,この段
    1467 éšŽã§ãƒã‚§ãƒƒã‚¯ã‚’実施する.
    1468 
    1469 ãã®å¾Œã§ï¼Œãƒ‘ラメータの範囲等のエラーの中で,対象のカーネルオブジェクト
    1470 ã®ç™»éŒ²æƒ
    1471 å ±ï¼ˆåˆæœŸåŒ–ブロックに含まれているæƒ
    1472 å ±ï¼‰ã«ä¾å­˜ã—てチェックすべき
    1473 ã‚‚ののチェックを,パラメータの並び順で実施する.
    1474 
    1475 
    1476 â—‹CHECKマクロとgoto文の使用
    1477 
    1478 ASPカーネルの実è£
    1479 ã«ãŠã„ては,サービスコールの静的なエラーをチェックする
    1480 ãŸã‚ã«ï¼Œåç§°ãŒ"CHECK_"で始まる一連のマクロ(これらを,CHECKマクロと総称
    1481 ã™ã‚‹ï¼‰ã‚’用いている.
    1482 
    1483 CHECKマクロの定義中にはgoto文を含んでいるが,MISRA-Cなどのコーディング
    1484 ãƒ«ãƒ¼ãƒ«ã§ã¯goto文の使用を禁止しており,goto文を使うべきではないという意
    1485 è¦‹ã‚‚多い.また,マクロの定義中にgoto文を使用することが問題であるという
    1486 æ„è¦‹ã‚‚ある.
    1487 
    1488 ã“こでは,定義中にgoto文を含むCHECKマクロを用いる設計意図とそれを使用し
    1489 ã¦ã‚ˆã„条件,CHECKマクロの使用によりソフトウェアの信頼性に問題が生じるこ
    1490 ã¨ãŒãªã„ことを論証する.
    1491 
    1492 ãªãŠï¼ŒASPカーネルのカーネル本体の実è£
    1493 ã§ã¯ï¼ŒCHECKマクロ以外にgoto文を用
    1494 ã„ている箇所はない(一部のシステムサービスでは,これ以外の方法でgoto文
    1495 ã‚’用いている).
    1496 
    1497 â—CHECKマクロの定義とその使用法
    1498 
    1499 kernel/check.hには,25個のCHECKマクロが定義されているが,いずれも次のパ
    1500 ã‚¿ãƒ¼ãƒ³ã§å®šç¾©ã•ã‚Œã¦ã„る.ここでXXXXXには,チェックしたいエラーの種類を表
    1501 ã™æ–‡å­—列がå
    1502 ¥ã‚‹ï¼Ž
    1503 
    1504 ----------------------------------------
    1505 #define CHECK_XXXXX(<……>) {                         \
    1506         if (<エラー条件>) {                                                \
    1507                 ercd = <エラーコード>;                            \
     927dispatchを呼び出してタスク切換えを行う場合には,dispatchの出口でタスク
     928例外処理ルーチンを呼び出すためここで呼出し処理を行う必要はないが,コー
     929ドが複雑になるため,dispatchを呼び出した場合もここでタスク例外処理ルー
     930チンの呼出し処理を行っている.
     931
     932●call_texrtnからdispatchを呼び出す処理について
     933
     934dispatch_rから(ターゲットによってはcalltexを経由して)call_texrtnを呼
     935び出し,call_texrtnからdispatchを呼び出すため,この2つの関数は相互再帰
     936呼出しをしている.ここでは,この実装で支障のない理由を説明する.
     937
     938call_texrtnからdispatchを呼び出すのは,ディスパッチが保留されていない状
     939態で呼び出されたタスク例外処理ルーチンが,その実行中にディスパッチ保留
     940状態に遷移し,さらにタスクディスパッチを必要とする処理を行い,ディスパッ
     941チ保留状態を解除しないままリターンした場合である.この場合,call_texrtn
     942の中でディスパッチ保留状態を解除した後に,dispatchを呼び出してタスクディ
     943スパッチを行う.つまり,call_texrtnからdispatchを呼び出す処理は,タスク
     944例外処理ルーチンの中でディスパッチ保留状態を解除すべきであったのを,解
     945除せずにリターンした場合を救済するためのものである.以下,この振舞いを
     946「救済ケース」と呼ぶ.
     947
     948そこで,比較のために,タスク例外処理ルーチンの最後で,正しくディスパッ
     949チ保留状態を解除してからリターンした場合の振舞いを考える.この場合には,
     950ディスパッチ保留状態を解除するサービスコール(ena_dsp,chg_ipm)の中で,
     951dispatchが呼び出されてタスクディスパッチが起こる.以下,この振舞いを
     952「正常ケース」と呼ぶ.
     953
     954正常ケースと救済ケースを比較すると,call_texrtn→タスク例外処理ルーチン
     955→サービスコール→dispatchの順でdispatchが呼び出されるか,call_texrtnか
     956ら直接dispatchが呼び出されるかの違いということになり,救済ケースの方が
     957スタックの使用量は少ない.つまり,正常ケースの動きを想定してスタック領
     958域が用意してあれば,救済ケースでも問題なく動作することになる.
     959
     960ここで,正常ケースと救済ケースで,上記以外に違いがないことが重要である.
     961具体的には,call_texrtnの中で,タスク例外処理許可状態にする(p_runtsk
     962->enatexをtrueにする)前に,dispatchを呼び出すことが重要である.タスク
     963例外処理許可状態にした後にdispatchを呼び出すと,出口のdispatch_rで,再
     964びタスク例外処理ルーチンを実行してしまう可能性があり,救済ケースの方が
     965スタックの使用量が増えてしまう.
     966
     967タスク例外処理ルーチンの中で,タスク例外処理許可状態にしたままリターン
     968した場合には,call_texrtnから呼び出したdispatchの出口のdispatch_rで再び
     969タスク例外処理ルーチンを実行してしまう可能性がある.この場合も,タスク
     970例外処理ルーチンの最後で,ディスパッチ保留状態を解除してからリターンし
     971た場合よりはスタックの使用量が少ないが,タスク例外処理禁止状態にした後
     972にディスパッチ保留状態を解除してリターンした場合よりは,スタックの使用
     973量が増える場合がある.そこで,このような状況が起こらないように,
     974dispatchを呼ぶ前にp_runtsk->enatexをfalseにする.
     975
     976
     977○エラーのチェック順序
     978
     979サービスコール内におけるエラーチェックは,以下の順序で行うことを原則と
     980する.なお,この節には,保護機能対応カーネルに関する記述が含まれている
     981が,それらの記述は将来的にはより適切なドキュメントに移動する予定である.
     982
     983●エラーの3分類
     984
     985サービスコールのエラーは,大きく以下の3つに分類することができる.
     986
     987(a) 静的エラー
     988
     989対象のカーネルオブジェクトが登録されているか否かや,その状態に依存せず
     990に,チェックすることができるエラー.
     991
     992(b) 準静的エラー
     993
     994対象のカーネルオブジェクトが登録されていれば,その状態に依存せずにチェッ
     995クすることができるエラー.
     996
     997(c) 動的エラー
     998
     999対象のカーネルオブジェクトの状態に依存するエラー.
     1000
     1001ASPカーネルにおいては,(a)と(b)のエラーはクリティカルセクションの外側で,
     1002この順序でチェックし,(c)のエラーはクリティカルセクションの内側でチェッ
     1003クする.ただし,動的生成機能拡張パッケージでは,(b)のエラー(の一部)は
     1004クリティカルセクションの内側で実施する必要がある.
     1005
     1006●静的エラーのチェック順序
     1007
     1008静的エラーには,実行コンテキストのエラー(ディスパッチ保留状態からの呼
     1009出しエラーも含む),パラメータの範囲等のエラー(対象のカーネルオブジェ
     1010クトに依存せずにチェックできるもの)が含まれる.
     1011
     1012サービスコール中では,最初に実行コンテキストのエラーをチェックし,その
     1013後,パラメータの並び順に,範囲等のエラーをチェックする.
     1014
     1015保護機能対応カーネルでは,パラメータがポインタである場合に,ポインタの
     1016指すメモリ領域がアクセス可能であるかをチェックする必要があるが,メモリ
     1017領域の設定が静的である場合には,このエラーチェックもここで実施する.た
     1018だし,メモリ領域の設定が静的でない場合には,このエラーチェックはクリティ
     1019カルセクションの内側で行う必要がある.
     1020
     1021●准静的エラーのチェック順序
     1022
     1023准静的エラーのチェックの前に,対象のカーネルオブジェクトの管理ブロック
     1024の先頭番地を,ローカル変数に代入する.
     1025
     1026保護機能対応カーネルでは,この次に,対象のカーネルオブジェクトがアクセ
     1027ス可能であるかをチェックする処理を行う.当該サービスコールの呼出しが,
     1028システム状態に対するアクセス許可ベクタで保護されている場合にも,この段
     1029階でチェックを実施する.
     1030
     1031その後で,パラメータの範囲等のエラーの中で,対象のカーネルオブジェクト
     1032の登録情報(初期化ブロックに含まれている情報)に依存してチェックすべき
     1033もののチェックを,パラメータの並び順で実施する.
     1034
     1035
     1036○CHECKマクロとgoto文の使用
     1037
     1038ASPカーネルの実装においては,サービスコールの静的なエラーをチェックする
     1039ために,名称が"CHECK_"で始まる一連のマクロ(これらを,CHECKマクロと総称
     1040する)を用いている.
     1041
     1042CHECKマクロの定義中にはgoto文を含んでいるが,MISRA-Cなどのコーディング
     1043ルールではgoto文の使用を禁止しており,goto文を使うべきではないという意
     1044見も多い.また,マクロの定義中にgoto文を使用することが問題であるという
     1045意見もある.
     1046
     1047ここでは,定義中にgoto文を含むCHECKマクロを用いる設計意図とそれを使用し
     1048てよい条件,CHECKマクロの使用によりソフトウェアの信頼性に問題が生じるこ
     1049とがないことを論証する.
     1050
     1051なお,ASPカーネルのカーネル本体の実装では,CHECKマクロ以外にgoto文を用
     1052いている箇所はない(一部のシステムサービスでは,これ以外の方法でgoto文
     1053を用いている).
     1054
     1055●CHECKマクロの定義とその使用法
     1056
     1057kernel/check.hには,25個のCHECKマクロが定義されているが,いずれも次のパ
     1058ターンで定義されている.ここでXXXXXには,チェックしたいエラーの種類を表
     1059す文字列が入る.
     1060
     1061----------------------------------------
     1062#define CHECK_XXXXX(<……>) {                             \
     1063        if (<エラー条件>) {                                          \
     1064                ercd = <エラーコード>;                                \
    15081065                goto error_exit;                                        \
    15091066        }                                                                               \
     
    15111068----------------------------------------
    15121069
    1513 ã“れらのCHECKマクロは,多くのサービスコールの処理関数中で,次のように使
    1514 ç”¨ã•ã‚Œã¦ã„る.
     1070これらのCHECKマクロは,多くのサービスコールの処理関数中で,次のように使
     1071用されている.
    15151072
    15161073----------------------------------------
    15171074ER
    1518 <サービスコール名>(……)
     1075<サービスコール名>(……)
    15191076{
    1520         <ローカル変数の宣言>
     1077        <ローカル変数の宣言>
    15211078        ER              ercd;
    15221079
    1523         LOG_XXX_YYY_ENTER(……);
    1524         CHECK_XXXXX(……);
    1525         CHECK_YYYYY(……);
    1526 
    1527         <サービスコール処理本体>
     1080        LOG_XXX_YYY_ENTER(……);
     1081        CHECK_XXXXX(……);
     1082        CHECK_YYYYY(……);
     1083
     1084        <サービスコール処理本体>
    15281085
    15291086  error_exit:
    1530         LOG_XXX_YYY_LEAVE(……);
     1087        LOG_XXX_YYY_LEAVE(……);
    15311088        return(ercd);
    15321089}
    15331090----------------------------------------
    15341091
    1535 ã“の例では,CHECKマクロを2つ使用しているが,1つのみ使用している場合もあ
    1536 ã‚Œã°ï¼Œ3つ以上使用している場合もある.また,複数のCHECKマクロの間に,ロー
    1537 ã‚«ãƒ«å¤‰æ•°ã¸ã®ä»£å
    1538 ¥æ–‡ãŒå
    1539 ¥ã‚‹å ´åˆã‚‚ある(例えば,ter_tskの処理関数).
    1540 
    1541 â—è¨­è¨ˆæ„å›³
    1542 
    1543 CHECKマクロを使用する意図は,ほとんどのサービスコールでå¿
    1544 è¦ãªé™çš„エラー
    1545 ã®ãƒã‚§ãƒƒã‚¯ã‚³ãƒ¼ãƒ‰ã‚’パターン化し,ソースコードの簡潔さを保つことで読みや
    1546 ã™ã•ã‚’向上させるとともに,記述ミスの可能性を減らすことである.
    1547 
    1548 ã¡ãªã¿ã«ï¼ŒCHECKマクロを使用しない場合,上に示したサービスコールの処理関
    1549 æ•°ã¯ï¼Œæ¬¡ã®ã‚ˆã†ã«è¨˜è¿°ã™ã‚‹ã“とになる.
     1092この例では,CHECKマクロを2つ使用しているが,1つのみ使用している場合もあ
     1093れば,3つ以上使用している場合もある.また,複数のCHECKマクロの間に,ロー
     1094カル変数への代入文が入る場合もある(例えば,ter_tskの処理関数).
     1095
     1096●設計意図
     1097
     1098CHECKマクロを使用する意図は,ほとんどのサービスコールで必要な静的エラー
     1099のチェックコードをパターン化し,ソースコードの簡潔さを保つことで読みや
     1100すさを向上させるとともに,記述ミスの可能性を減らすことである.
     1101
     1102ちなみに,CHECKマクロを使用しない場合,上に示したサービスコールの処理関
     1103数は,次のように記述することになる.
    15501104
    15511105----------------------------------------
    15521106ER
    1553 <サービスコール名>(……)
     1107<サービスコール名>(……)
    15541108{
    1555         <ローカル変数の宣言>
     1109        <ローカル変数の宣言>
    15561110        ER              ercd;
    15571111
    1558         LOG_XXX_YYY_ENTER(……);
    1559         if (<XXXXXのエラー条件>) {
    1560                 ercd = <XXXXXのエラーコード>;
     1112        LOG_XXX_YYY_ENTER(……);
     1113        if (<XXXXXのエラー条件>) {
     1114                ercd = <XXXXXのエラーコード>;
    15611115        }
    15621116        else {
    1563                 if (<YYYYYのエラー条件>) {
    1564                         ercd = <YYYYYのエラーコード>;
     1117                if (<YYYYYのエラー条件>) {
     1118                        ercd = <YYYYYのエラーコード>;
    15651119                }
    15661120                else {
    15671121
    1568                         <サービスコール処理本体>
     1122                        <サービスコール処理本体>
    15691123
    15701124                }
    15711125        }
    1572         LOG_XXX_YYY_LEAVE(……);
     1126        LOG_XXX_YYY_LEAVE(……);
    15731127        return(ercd);
    15741128}
    15751129----------------------------------------
    15761130
    1577 CHECKマクロのå†
    1578 å®¹ã‚’知っているという前提の下では,å
    1579 ƒã®ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã®æ–¹ãŒ
    1580 èª­ã¿ã‚„すいのは明らかである.
    1581 
    1582 ãªãŠï¼Œã“のようなCHECKマクロの定義には,goto文の使用が不可避である.
    1583 
    1584 â—CHECKマクロを使用してよい条件
    1585 
    1586 CHECKマクロは,次の条件を満たすように使用しなければならない.
    1587 
    1588 (1) CHECKマクロは,サービスコール処理関数のå
    1589 ˆé ­éƒ¨åˆ†ã§ï¼Œã‚µãƒ¼ãƒ“スコールå
    1590 ¥
    1591 ã€€ã€€å£ã®ãƒ­ã‚°ã‚’出した後,クリティカルセクションにå
    1592 ¥ã‚‹å‰ã¾ã§ã«ï¼Œå‡¦ç†é–¢æ•°
    1593 ã€€ã€€ã®ãƒˆãƒƒãƒ—レベルで用いる.
    1594 
    1595 (2) サービスコール処理関数の末尾部分で,クリティカルセクションを抜けた
    1596 ã€€ã€€å¾Œï¼Œã‚µãƒ¼ãƒ“スコール出口のログを出す前に,処理関数のトップレベルに,
    1597 ã€€ã€€error_exitラベルを置く.
    1598 
    1599 â—å•é¡Œã‚’生じることがない根拠
    1600 
    1601 ã“のような方法でgoto文を使用しても,ソフトウェアの信頼性に問題が生じる
    1602 ã“とがないことを主張するには,そもそも,MISRA-Cなどのコーディングルール
    1603 ã§goto文の使用を禁止している根拠,言い換えると,goto文の使用によりソフ
    1604 ãƒˆã‚¦ã‚§ã‚¢ã®ä¿¡é ¼æ€§ã«å•é¡ŒãŒç”Ÿã˜ã‚‹å¯èƒ½æ€§ã®ã‚る理由を明らかにするå¿
    1605 è¦ãŒã‚る.
    1606 
    1607 MISRA-Cのドキュメントでは,goto文の使用を禁止する根拠についてあまり明確
    1608 ã«ãªã£ã¦ãŠã‚‰ãšï¼Œã“こではその根拠を次のように推測する.
    1609 
    1610 ãƒ»å‡¦ç†ã®æµã‚ŒãŒè¤‡é›‘になり,プログラムの意図が読みにくくなる(いわゆる,
    1611 ã€€ã‚¹ãƒ‘ゲッティプログラムになる).
    1612 
    1613 CHECKマクロの場合には,goto文をエラー発生時の強制脱出に用いており,ラベ
    1614 ãƒ«ã‚‚error_exitとするなど,プログラムの意図は明らかである.一方,このよ
    1615 ã†ã«goto文をエラー時の強制脱出に用いる場合には,次の点もgoto文の使用を
    1616 ç¦æ­¢ã™ã‚‹æ ¹æ‹ ã«ãªã‚Šã†ã‚‹ï¼Ž
    1617 
    1618 ãƒ»goto文で強制脱出することにより,脱出時に行わなければならない後処理が
    1619 ã€€é£›ã°ã•ã‚Œã‚‹ãŠãã‚ŒãŒã‚る.
    1620 
    1621 ãŸã ã—この点についても,CHECKマクロを上記の使用条件を満たして使う限りは,
    1622 è„±å‡ºæ™‚に行わなければならない後処理はなく,CHECKマクロの使用によりソフト
    1623 ã‚¦ã‚§ã‚¢ã®ä¿¡é ¼æ€§ã«å•é¡ŒãŒç”Ÿã˜ã‚‹ã“とはない.
    1624 
    1625 å•é¡Œã‚’生じることがないことを論証するもう1つ方法は,コーディングルールに
    1626 åˆè‡´ã—ないプログラムが,コーディングルールに合致したプログラムと等価で
    1627 ã‚ることを示す方法である.
    1628 
    1629 ã™ã§ã«ã€Œè¨­è¨ˆæ„å›³ã€ã®ç¯€ã§è¿°ã¹ãŸã‚ˆã†ã«ï¼ŒCHECKマクロを使用したプログラムは,
    1630 goto文を使用しない等価なプログラムに書き換えることができるが,より一般
    1631 çš„には,次のことが言える.
    1632 
    1633 else部を持たないif文のthen部の最後に,if文より下(前方)にあり,if文と
    1634 åŒã˜ãƒ–ロックå†
    1635 ã®åŒã˜éšŽå±¤ã®ãƒ©ãƒ™ãƒ«ã¸åˆ†å²ã™ã‚‹goto文がある場合には,if文と
    1636 ãƒ©ãƒ™ãƒ«ã®é–“の文をelse部にすることにより,goto文を使わない等価なプログラ
    1637 ãƒ ã«æ›¸ãæ›ãˆã‚‹ã“とができる.
    1638 
    1639 ä¾‹ã¨ã—て,goto文を使った次のプログラムを考える.
     1131CHECKマクロの内容を知っているという前提の下では,元のソースコードの方が
     1132読みやすいのは明らかである.
     1133
     1134なお,このようなCHECKマクロの定義には,goto文の使用が不可避である.
     1135
     1136●CHECKマクロを使用してよい条件
     1137
     1138CHECKマクロは,次の条件を満たすように使用しなければならない.
     1139
     1140(1) CHECKマクロは,サービスコール処理関数の先頭部分で,サービスコール入
     1141  口のログを出した後,クリティカルセクションに入る前までに,処理関数
     1142  のトップレベルで用いる.
     1143
     1144(2) サービスコール処理関数の末尾部分で,クリティカルセクションを抜けた
     1145  後,サービスコール出口のログを出す前に,処理関数のトップレベルに,
     1146  error_exitラベルを置く.
     1147
     1148●問題を生じることがない根拠
     1149
     1150このような方法でgoto文を使用しても,ソフトウェアの信頼性に問題が生じる
     1151ことがないことを主張するには,そもそも,MISRA-Cなどのコーディングルール
     1152でgoto文の使用を禁止している根拠,言い換えると,goto文の使用によりソフ
     1153トウェアの信頼性に問題が生じる可能性のある理由を明らかにする必要がある.
     1154
     1155MISRA-Cのドキュメントでは,goto文の使用を禁止する根拠についてあまり明確
     1156になっておらず,ここではその根拠を次のように推測する.
     1157
     1158・処理の流れが複雑になり,プログラムの意図が読みにくくなる(いわゆる,
     1159 スパゲッティプログラムになる).
     1160
     1161CHECKマクロの場合には,goto文をエラー発生時の強制脱出に用いており,ラベ
     1162ルもerror_exitとするなど,プログラムの意図は明らかである.一方,このよ
     1163うにgoto文をエラー時の強制脱出に用いる場合には,次の点もgoto文の使用を
     1164禁止する根拠になりうる.
     1165
     1166・goto文で強制脱出することにより,脱出時に行わなければならない後処理が
     1167 飛ばされるおそれがある.
     1168
     1169ただしこの点についても,CHECKマクロを上記の使用条件を満たして使う限りは,
     1170脱出時に行わなければならない後処理はなく,CHECKマクロの使用によりソフト
     1171ウェアの信頼性に問題が生じることはない.
     1172
     1173問題を生じることがないことを論証するもう1つ方法は,コーディングルールに
     1174合致しないプログラムが,コーディングルールに合致したプログラムと等価で
     1175あることを示す方法である.
     1176
     1177すでに「設計意図」の節で述べたように,CHECKマクロを使用したプログラムは,
     1178goto文を使用しない等価なプログラムに書き換えることができるが,より一般
     1179的には,次のことが言える.
     1180
     1181else部を持たないif文のthen部の最後に,if文より下(前方)にあり,if文と
     1182同じブロック内の同じ階層のラベルへ分岐するgoto文がある場合には,if文と
     1183ラベルの間の文をelse部にすることにより,goto文を使わない等価なプログラ
     1184ムに書き換えることができる.
     1185
     1186例として,goto文を使った次のプログラムを考える.
    16401187
    16411188----------------------------------------
    16421189        {
    1643                 /* if文の前の文 */
     1190                /* if文の前の文 */
    16441191                if (....) {
    1645                         /* then部の文 */
    1646                         goto <ラベル>;
     1192                        /* then部の文 */
     1193                        goto <ラベル>;
    16471194                }
    1648                 /* if文とラベルの間の文 */
    1649           <ラベル>:
    1650                 /* ラベルより後ろの文 */
     1195                /* if文とラベルの間の文 */
     1196          <ラベル>:
     1197                /* ラベルより後ろの文 */
    16511198        }
    16521199----------------------------------------
    16531200
    1654 ã“のプログラムは,goto文を使わない次のプログラムと等価である.
     1201このプログラムは,goto文を使わない次のプログラムと等価である.
    16551202
    16561203----------------------------------------
    16571204        {
    1658                 /* if文の前の文 */
     1205                /* if文の前の文 */
    16591206                if (....) {
    1660                         /* then部の文 */
     1207                        /* then部の文 */
    16611208                }
    16621209                else {
    1663                         /* if文とラベルの間の文 */
     1210                        /* if文とラベルの間の文 */
    16641211                }
    1665                 /* ラベルより後ろの文 */
     1212                /* ラベルより後ろの文 */
    16661213        }
    16671214----------------------------------------
    16681215
    1669 ã“の条件に合致するgoto文が複数ある場合には,下にあるgoto文から順に上記
    1670 ã®æ–¹æ³•ã«ã‚ˆã£ã¦æ›¸ãæ›ãˆã‚‹ã“とで,goto文を使わない等価なプログラムに書き
    1671 æ›ãˆã‚‹ã“とができる.
    1672 
    1673 CHECKマクロの使用方法は,上記のgoto文の使用方法に合致するため,goto文を
    1674 ä½¿ç”¨ã—ない等価なプログラムに書き換えることができる.よって,このCHECKマ
    1675 ã‚¯ãƒ­ã«ã‚ˆã‚Šå•é¡Œã‚’生じることはない.
    1676 
    1677 
    1678 â—‹ext_tsk,ext_kerの返り値
    1679 
    1680 Î¼ITRON4.0仕様では,ext_tskはリターンすることのないサービスコールとなっ
    1681 ã¦ã„るが,TOPPERS新世代カーネルにおいては,このサービスコールの返り値を
    1682 ER型に変更し,非タスクコンテキストから呼ばれた場合には,E_CTXエラーを返
    1683 ã‚Šå€¤ã¨ã—てリターンすることとする.
    1684 
    1685 ã“の仕様に対するいくつかの対案を検討したが,以下の理由で採用しない.
    1686 
    1687 ãƒ»JSPカーネルのように,危険の可能性を検出しながら実行を継続する方法は,
    1688 ã€€ä¿¡é ¼æ€§ãƒ»å®‰å
    1689 ¨æ€§ã‚’重視するシステムでは望ましくない.信頼性・安å
    1690 ¨æ€§ã‚’重
    1691 ã€€è¦–するシステムでは,危険の可能性を検出したら,早期にリカバリをすべき
    1692 ã€€ã§ã‚る.
    1693 
    1694 ãƒ»ASPカーネルの当初案のカーネルをダウンさせる方法は,アプリケーション側
    1695 ã€€ã§å›žå¾©ã™ã‚‹ä½™åœ°ã‚’なくすという意味で望ましくない.
    1696 
    1697 ãƒ»éŽåŽ»ã®äº’換性を保つために,型をvoidとしたまま,非タスクコンテキストか
    1698 ã€€ã‚‰å‘¼ã°ã‚ŒãŸå ´åˆã«ã¯ãƒªã‚¿ãƒ¼ãƒ³ã™ã‚‹ã¨ã™ã‚‹æ–¹æ³•ã¯ï¼Œã‚«ãƒ¼ãƒãƒ«ã®ä»•æ§˜å¤‰æ›´ã«æ°—づ
    1699 ã€€ãã«ãããªã‚‹ã¨ã„う意味で望ましくない.また,他のエラーコード(例えば
    1700 ã€€E_NOSPT)を返す余地をなくしている.
    1701 
    1702 ãƒ»ä¸€ç¨®ã®CPU例外を呼び出すことにする方法は,カーネル仕様å
    1703 ¨ä½“の整合性を考
    1704 ã€€ãˆã¦æŽ¡ç”¨ã—なかった.ここで一種のCPU例外を導å
    1705 ¥ã™ã‚‹ã‚ˆã‚Šã‚‚,サービスコー
    1706 ã€€ãƒ«ãŒã‚¨ãƒ©ãƒ¼ã‚’返した場合に呼ばれるOSEK/VDX OS仕様のエラーフックに相当す
    1707 ã€€ã‚‹æ©Ÿèƒ½ã‚’å°Žå
    1708 ¥ã—た方が有用性が高いと思われるためである.
    1709 
    1710 ã“の変更により,さらに,CPUロック状æ
    1711 ‹ã‚„ディスパッチ禁止状æ
    1712 ‹ã§ext_tskが
    1713 å‘¼ã°ã‚ŒãŸå ´åˆã«ã‚‚エラーリターンする方法が考えられるが,タスクのメインルー
    1714 ãƒãƒ³ã‹ã‚‰ã®ãƒªã‚¿ãƒ¼ãƒ³ã¨ext_tskが等価にならないため,採用しない.また,他の
    1715 å‡¦ç†å˜ä½ã‹ã‚‰ã®ãƒªã‚¿ãƒ¼ãƒ³æ–¹æ³•ã¨æ•´åˆã•ã›ã‚‹æ„å‘³ã‚‚ある(例えば,割込みハンド
    1716 ãƒ©ã‹ã‚‰CPUロック状æ
    1717 ‹ã®ã¾ã¾ãƒªã‚¿ãƒ¼ãƒ³ã—た場合の扱い).
    1718 
    1719 ã“れにあわせて,ext_kerについても,返り値をER型に変更する.ASPカーネル
    1720 ã§ã¯ï¼Œext_kerがエラーを返すことはないが,HRPカーネルでは,E_OACVエラー
    1721 ã‚’返す場合がある.
    1722 
    1723 ãªãŠï¼ŒÎ¼ITRON4.0仕様では,exd_tskもリターンすることのないサービスコール
    1724 ã¨ãªã£ã¦ã„るが,TOPPERS新世代カーネルでは,exd_tskはサポートしていない.
    1725 
    1726 
    1727 â—‹ã‚«ãƒ¼ãƒãƒ«ã®ãƒ‡ãƒ¼ã‚¿æ§‹é€ ã«å¯¾ã™ã‚‹volatile宣言について(クリティカルセクショ
    1728 ãƒ³ã®å‡ºå
    1729 ¥å‡¦ç†ã®å®Ÿç¾ã«é–¢ã™ã‚‹åˆ¶ç´„)
    1730 
    1731 ã‚«ãƒ¼ãƒãƒ«å†
    1732 ã®ãƒ‡ãƒ¼ã‚¿æ§‹é€ ã¯ï¼Œä¸¦è¡Œå®Ÿè¡Œã•ã‚Œã‚‹ä»–の処理単位(割込みハンドラや
    1733 ã‚¿ã‚¹ã‚¯ï¼‰ã‹ã‚‰ã‚‚アクセスされる可能性があるため,volatile宣言がå¿
    1734 è¦ã§ã¯ãª
    1735 ã„かと考えられる.実際,クリティカルセクションå†
    1736 ã§ã‚«ãƒ¼ãƒãƒ«å¤‰æ•°ã‚’読むコー
    1737 ãƒ‰ãŒï¼Œã‚³ãƒ³ãƒ‘イラの最適化によりクリティカルセクション外に移動され,それ
    1738 ãŒåŽŸå› ã¨ãªã£ãŸå•é¡Œäº‹ä¾‹ã‚‚報告されている.
    1739 
    1740 ã‚«ãƒ¼ãƒãƒ«å†
    1741 ã®ã™ã¹ã¦ã®ãƒ‡ãƒ¼ã‚¿æ§‹é€ ã«volatile宣言をつける方法は,安å
    1742 ¨ã§ã¯ã‚
    1743 ã‚‹ãŒï¼Œæœ€é©åŒ–が抑止されるために,カーネルのサイズや性能には悪影響を与え
    1744 ã‚‹ï¼Žãã“でASPカーネルでは,次の方法でvolatile宣言のå¿
    1745 è¦æ€§ã‚’なくすことと
    1746 ã™ã‚‹ï¼Ž
    1747 
    1748 ASPカーネルにおいては,並行実行される他の処理単位から書き換えられる可能
    1749 æ€§ã®ã‚るデータ構造は,すべて,CPUロック状æ
    1750 ‹ã¾ãŸã¯å
    1751 ¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ
    1752 ‹ã«ã‚ˆ
    1753 ã‚‹ã‚¯ãƒªãƒ†ã‚£ã‚«ãƒ«ã‚»ã‚¯ã‚·ãƒ§ãƒ³å†
    1754 ã§ã‚¢ã‚¯ã‚»ã‚¹ã—ている.クリティカルセクションå†
    1755 
    1756 ã§ã®ãƒ‡ãƒ¼ã‚¿æ§‹é€ ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒï¼Œã‚³ãƒ³ãƒ‘イラの最適化によりクリティカルセクショ
    1757 ãƒ³å¤–に移動されないようにするには,コンパイラに対して,クリティカルセク
    1758 ã‚·ãƒ§ãƒ³ã®å‡ºå
    1759 ¥å‡¦ç†ã«ã‚ˆã‚Šï¼Œãƒ¡ãƒ¢ãƒªä¸Šã®ãƒ‡ãƒ¼ã‚¿æ§‹é€ ãŒæ›¸ãå¤‰ã‚ã‚‹å¯èƒ½æ€§ãŒã‚るこ
    1760 ã¨ã‚’知らせればよい.
    1761 
    1762 å
    1763 ·ä½“的には,クリティカルセクションの出å
    1764 ¥å‡¦ç†ã‚’関数によって実現すれば,
    1765 ã“のような最適化を抑止することができる.しかし,ASPカーネルの多くのター
    1766 ã‚²ãƒƒãƒˆä¾å­˜éƒ¨ã«ãŠã„て,クリティカルセクションの出å
    1767 ¥å‡¦ç†ã¯ãƒžã‚¯ãƒ­ã‚„インラ
    1768 ã‚¤ãƒ³é–¢æ•°ã«ã‚ˆã‚Šå®Ÿè£
    1769 ã•ã‚Œã¦ãŠã‚Šï¼Œä¸Šã®ã‚ˆã†ãªæœ€é©åŒ–を抑止できない.
    1770 
    1771 ãã“で,クリティカルセクションの出å
    1772 ¥å‡¦ç†ã‚’実現する場合には,メモリ上の
    1773 ãƒ‡ãƒ¼ã‚¿æ§‹é€ ãŒæ›¸ãå¤‰ã‚ã‚‹å¯èƒ½æ€§ãŒã‚ることを,何らかの方法でコンパイラに知
    1774 ã‚‰ã›ãªã‘ればならないという制約を設ける.GNU開発環境では,次のいずれかの
    1775 æ–¹æ³•ã§ã“の制約を満たすことができる.
    1776 
    1777 (a) クリティカルセクションの出å
    1778 ¥å‡¦ç†ã®å
    1779 ¨ä½“または出å
    1780 ¥å‡¦ç†ã®æœ¬è³ªçš„な部分
    1781         (å
    1782 ·ä½“的には,割込み禁止/許可する処理)を(インラインでない)通常
    1783         の関数により実現する.
    1784 
    1785 (b) クリティカルセクションの出å
    1786 ¥å‡¦ç†ã®æœ¬è³ªçš„な部分をインラインアセンブ
    1787         ラによって実現している場合には,そのインラインアセンブラのclobber変
    1788         数リストに"memory"を追加する.
    1789 
    1790 (c) クリティカルセクションの出å
    1791 ¥å‡¦ç†ã®æœ¬è³ªçš„な部分が,マクロやインライ
    1792         ン関数呼出しで実現している場合には,クリティカルセクションにå
    1793 ¥ã‚‹å‡¦
    1794         理の最後と出る処理のå
    1795 ˆé ­ã«ï¼ŒAsm("":::"memory")という記述をå
    1796 ¥ã‚Œã‚‹ï¼Ž
    1797 
    1798 ãªãŠï¼Œã“の制約が適用されるクリティカルセクションの出å
    1799 ¥å‡¦ç†ã¯ï¼Œä»¥ä¸‹ã®ã‚‚
    1800 ã®ã§ã‚る.
     1216この条件に合致するgoto文が複数ある場合には,下にあるgoto文から順に上記
     1217の方法によって書き換えることで,goto文を使わない等価なプログラムに書き
     1218換えることができる.
     1219
     1220CHECKマクロの使用方法は,上記のgoto文の使用方法に合致するため,goto文を
     1221使用しない等価なプログラムに書き換えることができる.よって,このCHECKマ
     1222クロにより問題を生じることはない.
     1223
     1224
     1225○ext_tsk,ext_kerの返り値
     1226
     1227μITRON4.0仕様では,ext_tskはリターンすることのないサービスコールとなっ
     1228ているが,TOPPERS新世代カーネルにおいては,このサービスコールの返り値を
     1229ER型に変更し,非タスクコンテキストから呼ばれた場合には,E_CTXエラーを返
     1230り値としてリターンすることとする.
     1231
     1232この仕様に対するいくつかの対案を検討したが,以下の理由で採用しない.
     1233
     1234・JSPカーネルのように,危険の可能性を検出しながら実行を継続する方法は,
     1235 信頼性・安全性を重視するシステムでは望ましくない.信頼性・安全性を重
     1236 視するシステムでは,危険の可能性を検出したら,早期にリカバリをすべき
     1237 である.
     1238
     1239・ASPカーネルの当初案のカーネルをダウンさせる方法は,アプリケーション側
     1240 で回復する余地をなくすという意味で望ましくない.
     1241
     1242・過去の互換性を保つために,型をvoidとしたまま,非タスクコンテキストか
     1243 ら呼ばれた場合にはリターンするとする方法は,カーネルの仕様変更に気づ
     1244 きにくくなるという意味で望ましくない.また,他のエラーコード(例えば
     1245 E_NOSPT)を返す余地をなくしている.
     1246
     1247・一種のCPU例外を呼び出すことにする方法は,カーネル仕様全体の整合性を考
     1248 えて採用しなかった.ここで一種のCPU例外を導入するよりも,サービスコー
     1249 ルがエラーを返した場合に呼ばれるOSEK/VDX OS仕様のエラーフックに相当す
     1250 る機能を導入した方が有用性が高いと思われるためである.
     1251
     1252この変更により,さらに,CPUロック状態やディスパッチ禁止状態でext_tskが
     1253呼ばれた場合にもエラーリターンする方法が考えられるが,タスクのメインルー
     1254チンからのリターンとext_tskが等価にならないため,採用しない.また,他の
     1255処理単位からのリターン方法と整合させる意味もある(例えば,割込みハンド
     1256ラからCPUロック状態のままリターンした場合の扱い).
     1257
     1258これにあわせて,ext_kerについても,返り値をER型に変更する.ASPカーネル
     1259では,ext_kerがエラーを返すことはないが,HRPカーネルでは,E_OACVエラー
     1260を返す場合がある.
     1261
     1262なお,μITRON4.0仕様では,exd_tskもリターンすることのないサービスコール
     1263となっているが,TOPPERS新世代カーネルでは,exd_tskはサポートしていない.
     1264
     1265
     1266○カーネルのデータ構造に対するvolatile宣言について(クリティカルセクショ
     1267ンの出入処理の実現に関する制約)
     1268
     1269カーネル内のデータ構造は,並行実行される他の処理単位(割込みハンドラや
     1270タスク)からもアクセスされる可能性があるため,volatile宣言が必要ではな
     1271いかと考えられる.実際,クリティカルセクション内でカーネル変数を読むコー
     1272ドが,コンパイラの最適化によりクリティカルセクション外に移動され,それ
     1273が原因となった問題事例も報告されている.
     1274
     1275カーネル内のすべてのデータ構造にvolatile宣言をつける方法は,安全ではあ
     1276るが,最適化が抑止されるために,カーネルのサイズや性能には悪影響を与え
     1277る.そこでASPカーネルでは,次の方法でvolatile宣言の必要性をなくすことと
     1278する.
     1279
     1280ASPカーネルにおいては,並行実行される他の処理単位から書き換えられる可能
     1281性のあるデータ構造は,すべて,CPUロック状態または全割込みロック状態によ
     1282るクリティカルセクション内でアクセスしている.クリティカルセクション内
     1283でのデータ構造のアクセスが,コンパイラの最適化によりクリティカルセクショ
     1284ン外に移動されないようにするには,コンパイラに対して,クリティカルセク
     1285ションの出入処理により,メモリ上のデータ構造が書き変わる可能性があるこ
     1286とを知らせればよい.
     1287
     1288具体的には,クリティカルセクションの出入処理を関数によって実現すれば,
     1289このような最適化を抑止することができる.しかし,ASPカーネルの多くのター
     1290ゲット依存部において,クリティカルセクションの出入処理はマクロやインラ
     1291イン関数により実装されており,上のような最適化を抑止できない.
     1292
     1293そこで,クリティカルセクションの出入処理を実現する場合には,メモリ上の
     1294データ構造が書き変わる可能性があることを,何らかの方法でコンパイラに知
     1295らせなければならないという制約を設ける.GNU開発環境では,次のいずれかの
     1296方法でこの制約を満たすことができる.
     1297
     1298(a) クリティカルセクションの出入処理の全体または出入処理の本質的な部分
     1299        (具体的には,割込み禁止/許可する処理)を(インラインでない)通常
     1300        の関数により実現する.
     1301
     1302(b) クリティカルセクションの出入処理の本質的な部分をインラインアセンブ
     1303        ラによって実現している場合には,そのインラインアセンブラのclobber変
     1304        数リストに"memory"を追加する.
     1305
     1306(c) クリティカルセクションの出入処理の本質的な部分が,マクロやインライ
     1307        ン関数呼出しで実現している場合には,クリティカルセクションに入る処
     1308        理の最後と出る処理の先頭に,Asm("":::"memory")という記述を入れる.
     1309
     1310なお,この制約が適用されるクリティカルセクションの出入処理は,以下のも
     1311のである.
    18011312
    18021313        SIL_LOC_INT
     
    18061317
    18071318
    1808 â—‹åž‹ã‚­ãƒ£ã‚¹ãƒˆã«ä¼´ã†è­¦å‘Šãƒ¡ãƒƒã‚»ãƒ¼ã‚¸
    1809 
    1810 GCCで-O2オプションをつけてコンパイルした場合に,カーネルのソースコード
    1811 ä¸­ã®æ•°ç®‡æ‰€ã§ï¼Œæ¬¡ã®è­¦å‘Šãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒå‡ºã‚‹ï¼ˆGCCのバージョンにもよる).
     1319○型キャストに伴う警告メッセージ
     1320
     1321GCCで-O2オプションをつけてコンパイルした場合に,カーネルのソースコード
     1322中の数箇所で,次の警告メッセージが出る(GCCのバージョンにもよる).
    18121323
    18131324warning: dereferencing type-punned pointer will break strict-aliasing rules
    18141325
    1815 ã“れは,GCCに-O2オプションをつけると,コンパイラがC言語のstrict
    1816 aliasing ruleを前提とするためである.コンパイラにstrict aliasing ruleを
    1817 é©ç”¨ã•ã›ãªã„ためには,GCCのオプションに-fno-strict-aliasingを指定すれば
    1818 ã‚ˆã„.これにより,警告メッセージは抑止されるが,strict aliasing ruleを
    1819 å‰æã¨ã—た最適化は行われなくなる.
    1820 
    1821 ASPカーネルに実è£
    1822 ã«ãŠã„ては,strict aliasing ruleを前提とした最適化を行っ
    1823 ã¦ã‚‚よく,この警告メッセージを無視しても差し支えない.以下では,この警
    1824 å‘Šãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’無視しても差し支えない理由を述べる.
    1825 
    1826 è­¦å‘Šãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒå‡ºã‚‹ä¾‹ã¨ã—て,semaphore.c中の次の行について検討する.
     1326これは,GCCに-O2オプションをつけると,コンパイラがC言語のstrict
     1327aliasing ruleを前提とするためである.コンパイラにstrict aliasing ruleを
     1328適用させないためには,GCCのオプションに-fno-strict-aliasingを指定すれば
     1329よい.これにより,警告メッセージは抑止されるが,strict aliasing ruleを
     1330前提とした最適化は行われなくなる.
     1331
     1332ASPカーネルに実装においては,strict aliasing ruleを前提とした最適化を行っ
     1333てもよく,この警告メッセージを無視しても差し支えない.以下では,この警
     1334告メッセージを無視しても差し支えない理由を述べる.
     1335
     1336警告メッセージが出る例として,semaphore.c中の次の行について検討する.
    18271337
    18281338        wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem);
    18291339
    1830 ã“の警告メッセージの原因は,直接的には,&winfo_semを(WINFO_WOBJ *)にキャ
    1831 ã‚¹ãƒˆã—ていることであるが,本質的な原因は,このコードがC言語のstrict
    1832 aliasing ruleに従わない代å
    1833 ¥æ–‡ã®åŽŸå› ã«ãªã‚‹å¯èƒ½æ€§ãŒã‚り,このルールに依存
    1834 ã—た最適化が誤った結果を引き起こす可能性があることである.
    1835 
    1836 C言語のstrict aliasing ruleは,互換性のない異なる型を通して,オーバラッ
    1837 ãƒ—するメモリ領域をアクセスする代å
    1838 ¥æ–‡ã‚’使用してはならないというものであ
    1839 ã‚‹ï¼ˆä½¿ç”¨ã—た場合の振舞いは未定義になる).このケースでは,(WINFO_SEM
    1840 *)型のポインタ経由と(WINFO_WOBJ *)型のポインタ経由で,オーバラップする
    1841 ãƒ¡ãƒ¢ãƒªé ˜åŸŸã‚’アクセスする代å
    1842 ¥æ–‡ã‚’使用してはならないことになる.また,警
    1843 å‘Šãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®åŽŸå› ã«ãªã£ã¦ã¯ã„ないが,(SEMCB *)型のポインタ経由と
    1844 (WOBJCB *)型のポインタ経由で,オーバラップするメモリ領域をアクセスする
    1845 ä»£å
    1846 ¥æ–‡ã‚’使用してはならない.
    1847 
    1848 ASPカーネルの実è£
    1849 ã«ãŠã„ては,semaphore.c中の関数においては,(SEMCB *)型
    1850 ãŠã‚ˆã³(WINFO_SEM *)型のポインタを使用しており,(WOBJCB *)型および
    1851 (WINFO_WOBJ *)型のポインタ経由でメモリ領域をアクセスすることはない.一
    1852 æ–¹ï¼Œãã“から呼び出されるwait.c中の関数においては,(WOBJCB *)型および
    1853 (WINFO_WOBJ *)型のポインタを使用しており,(SEMCB *)型および(WINFO_SEM
    1854 *)型のポインタ経由でメモリ領域をアクセスすることはない.
    1855 
    1856 strict aliasing ruleに従わない代å
    1857 ¥æ–‡ã®å•é¡Œç‚¹ã¯ï¼Œã“のルールに依存した最
    1858 é©åŒ–が誤った結果を引き起こす可能性があることであるが,異なるコンパイル
    1859 å˜ä½ã‚’またいで最適化が行われることはないため,これにより問題が起こるこ
    1860 ã¨ã¯ãªã„と言うことができる.
    1861 
    1862 åŒã˜è­°è«–は,他のソースファイル(eventflag.c,dataqueue.c,pridataq.c,
    1863 mailbox.c,mempfix.c)中の警告メッセージについても,そのまま当てはまる.
    1864 
    1865 
    1866 â—‹æ€§èƒ½è©•ä¾¡ç”¨ã‚·ã‚¹ãƒ†ãƒ æ™‚刻参ç
    1867 §æ©Ÿèƒ½
    1868 
    1869 â—å¿
    1870 è¦æ€§ã¨ä½¿é€”
    1871 
    1872 ASPカーネルには,ASPカーネル上で動作するタスクやASPカーネル自身の性能を
    1873 è¨ˆæ¸¬ã™ã‚‹ãŸã‚ã«ï¼Œã‚·ã‚¹ãƒ†ãƒ æ™‚刻より精度の高い性能評価用システム時刻を読み
    1874 å‡ºã™æ©Ÿèƒ½ã‚’サポートする.性能評価用システム時刻は,マイクロ秒単位で表現
    1875 ã•ã‚Œã‚‹ãŒï¼Œå®Ÿéš›ã®ç²¾åº¦ã¯ã‚¿ãƒ¼ã‚²ãƒƒãƒˆä¾å­˜ã§ã‚る.
    1876 
    1877 ã“の機能を用いてあるプログラムの実行時間を計測するには,その実行直前と
    1878 å®Ÿè¡Œç›´å¾Œã«æ€§èƒ½è©•ä¾¡ç”¨ã‚·ã‚¹ãƒ†ãƒ æ™‚刻を読み出し,その差を求める.そのため,
    1879 æ€§èƒ½è©•ä¾¡ç”¨ã‚·ã‚¹ãƒ†ãƒ æ™‚刻は常に相対値を使用し,性能評価用システム時刻の絶
    1880 å¯¾å€¤ã‚’使用することは想定していない.
    1881 
    1882 â—API仕様
    1883 
    1884 æ€§èƒ½è©•ä¾¡ç”¨ã‚·ã‚¹ãƒ†ãƒ æ™‚刻参ç
    1885 §æ©Ÿèƒ½ã§ã¯ï¼Œæ¬¡ã®ãƒ‡ãƒ¼ã‚¿åž‹ã‚’用いる.
    1886 
    1887         SYSUTM          性能評価用システム時刻(符号無し整数,単位はマイクロ秒,
    1888                                 32ビット以上)
    1889 
    1890 SYSUTM型は,ターゲット非依存部においてulong_t型(すなわち,unsigned
    1891 long型)に定義されており,そのサイズは,32ビット以上で,ターゲット定義
    1892 ã§ã‚る.
    1893 
    1894 æ€§èƒ½è©•ä¾¡ç”¨ã‚·ã‚¹ãƒ†ãƒ æ™‚刻がSYSUTM型で表現できる範囲をè¶
    1895 ãˆãŸï¼ˆã¤ã¾ã‚Šï¼Œã‚ªãƒ¼
    1896 ãƒãƒ•ãƒ­ãƒ¼ã—た)場合,性能評価用システム時刻は0に戻る.評価対象プログラム
    1897 ã®å®Ÿè¡Œå‰å¾Œã®æ€§èƒ½è©•ä¾¡ç”¨ã‚·ã‚¹ãƒ†ãƒ æ™‚刻の差を求める場合には,計測する時間が
    1898 SYSUTM型で表現できる範囲である限り,0に戻ることを特別に考æ
    1899 ®ã™ã‚‹å¿
    1900 è¦ã¯ãª
    1901 ã„.
    1902 
    1903 SYSUTM型が32ビットの場合,性能評価用システム時刻は約71分でオーバフロー
    1904 ã™ã‚‹ï¼Žãã®ãŸã‚ï¼Œã“の機能を71分を越える時間の測定に使った場合の動作は保
    1905 è¨¼ã•ã‚Œãªã„.
    1906 
    1907 æ€§èƒ½è©•ä¾¡ç”¨ã‚·ã‚¹ãƒ†ãƒ æ™‚刻参ç
    1908 §æ©Ÿèƒ½ã®ãŸã‚ã®ã‚µãƒ¼ãƒ“スコールの仕様については,
    1909 ã€ŒTOPPERS新世代カーネル統合仕様書」の「4.6.1 システム時刻管理」の節を参
    1910 ç
    1911 §ã™ã‚‹ã“と.
    1912 
    1913 â—å®Ÿè£
    1914 
    1915 
    1916 æ™‚刻をマイクロ秒単位で取得するために,周期的なタイムティックを供給する
    1917 ã‚¿ã‚¤ãƒžã®ç¾åœ¨å€¤ï¼ˆã‚¿ã‚¤ãƒžã¯ã‚«ã‚¦ãƒ³ãƒˆã‚¢ãƒƒãƒ—するものと仮定する)を読み出し,
    1918 ãã‚Œã‚’マイクロ秒単位に換算した値に,現在のシステム時刻(ミリ秒単位で表
    1919 ç¾ã•ã‚Œã‚‹ï¼‰ã‚’1000倍した値を加えたものを性能評価用システム時刻とする.現
    1920 åœ¨ã®ã‚·ã‚¹ãƒ†ãƒ æ™‚刻を1000倍する際に,オーバフローが発生する可能性があるが,
    1921 ç„¡è¦–してかまわない.
    1922 
    1923 ãŸã ã—,システム時刻の現在値とタイマの現在値を一貫した状æ
    1924 ‹ã§èª­ã¿å‡ºã™ã®
    1925 ã¯å®¹æ˜“ではない.両方の値を順に読み出すと,読出しの間にタイマがオーバフ
    1926 ãƒ­ãƒ¼ã—て割込み要求が発生した場合に,片方はオーバフロー前の値,もう片方
    1927 ã¯ã‚ªãƒ¼ãƒãƒ•ãƒ­ãƒ¼å¾Œã®å€¤ã‚’読んでしまい,誤った性能評価用システム時刻を取得
    1928 ã—てしまう.
    1929 
    1930 ã“の問題を解決する方法はいくつか考えられるが,どの方法を採用するの決定
    1931 ã«ã‚たり,次の要求事é 
    1932 ã‚’設定した.
    1933 
    1934 (1) 多くのターゲットシステムで実現できること.
    1935 
    1936 (2) サービスコールの実行時間が可能な限り一定となること.言い換えると,
    1937     条件によってサービスコールの実行時間が大きく変動しないこと.
    1938 
    1939 (3) サービスコール中の可能な限り同じタイミングの時刻を返すこと.言い換
    1940     えると,条件によって時刻を読み取るタイミングが変動しないこと.
    1941 
    1942 (4) 調整するå¿
    1943 è¦ã®ã‚るパラメータを最小限とすること.
    1944 
    1945 ã“れらの要求事é 
    1946 ã‚’満たす方法として,次の方法を用いることにした.
    1947 
    1948 ã¾ãšï¼ŒNMIを除くすべての割込みを禁止した状æ
    1949 ‹ã§ï¼Œã‚·ã‚¹ãƒ†ãƒ æ™‚刻の現在値,タ
    1950 ã‚¤ãƒžã®ç¾åœ¨å€¤ï¼ˆ1回目),タイマ割込み要求の有無,タイマの現在値(2回目)
    1951 ã‚’,この順で読み出す.割込みを禁止しているため,この間にシステム時刻の
    1952 ç¾åœ¨å€¤ãŒå¤‰åŒ–することはなく,システム時刻の現在値を読み出す順番はどこで
    1953 ã‚‚よい.また,タイマの現在値の2回目の読出しは,タイマ割込み要求があった
    1954 å ´åˆã«ã®ã¿å¿
    1955 è¦ã¨ãªã‚‹ãŒï¼Œ(2)の要求から,タイマ割込み要求の有無によらず読
    1956 ã¿å‡ºã™ã“ととする.
    1957 
    1958 ã“れらの値を読み出した後,割込み禁止を解除し,次の処理を行う.まず,タ
    1959 ã‚¤ãƒžå‰²è¾¼ã¿è¦æ±‚がなかった場合には,システム時刻の現在値と,1回目に読んだ
    1960 ã‚¿ã‚¤ãƒžã®ç¾åœ¨å€¤ã¯ä¸€è²«ã—た値であることが保証できるため,これらの値から性
    1961 èƒ½è©•ä¾¡ç”¨ã‚·ã‚¹ãƒ†ãƒ æ™‚刻の現在値を求める.
    1962 
    1963 æ¬¡ã«ã‚¿ã‚¤ãƒžå‰²è¾¼ã¿è¦æ±‚があった場合には,1回目に読んだタイマの現在値が,タ
    1964 ã‚¤ãƒžå‰²è¾¼ã¿è¦æ±‚発生前の値(オーバフロー前の値)である場合と,発生後の値
    1965 ï¼ˆã‚ªãƒ¼ãƒãƒ•ãƒ­ãƒ¼å¾Œã®å€¤ï¼‰ã§ã‚る場合の両方の可能性が考えられる.このどちら
    1966 ã®å ´åˆã§ã‚ったかを,2回目に読んだタイマの現在値を使って,次のように決定
    1967 ã™ã‚‹ï¼Ž2回目の値は,タイマ割込み要求発生後の値(オーバフロー後の値)であ
    1968 ã‚‹ã“とが保証できるため,1回目の値が2回目の値よりも大きい場合には,その
    1969 é–“にオーバフローがあったものと推測できる.つまり,1回目の値はオーバフロー
    1970 å‰ã®å€¤ã¨ã„うことになり,システム時刻の現在値と一貫した値であるとして性
    1971 èƒ½è©•ä¾¡ç”¨ã‚·ã‚¹ãƒ†ãƒ æ™‚刻の現在値を求める.逆に,1回目の値が2回目の値と同じ
    1972 ã‹ãã‚Œã‚ˆã‚Šå°ã•ã„場合には,1回目の値はオーバフロー後の値であると推測でき
    1973 ã‚‹ï¼Žã“の場合には,次のタイムティックのシステム時刻を求め,その値と1回目
    1974 ã®å€¤ãŒä¸€è²«ã—た値であるとして性能評価用システム時刻の現在値を求める.
    1975 
    1976 ã“こで,タイマ割込み要求があった場合には,2回目に読んだタイマの現在値を
    1977 ç”¨ã„る方法が考えられるが,(3)の要求を満たさなくなるために採用しなかった.
    1978 ã¾ãŸï¼ŒJSPカーネルと同様の方法は,(4)の要求を満たさないために採用しなかっ
    1979 ãŸï¼Ž
    1980 
    1981 ä¸Šã§ã€ŒæŽ¨æ¸¬ã§ãã‚‹ã€ã¨ã—たのは,この推測が成り立たなくなるケースがあるた
    1982 ã‚ã§ã‚る.この推測が成り立たなくなるケースは,次の2つの場合に分けて分析
    1983 ã™ã‚‹ã“とができる.
    1984 
    1985 (a) 1回目の値がオーバフロー後の値であるにもかかわらず,1回目の値が2回目
    1986     の値よりも大きくなる場合
    1987 
    1988 ã“のようなケースは,タイマ割込みが要求されているにもかかわらずサービス
    1989 ã•ã‚Œãªã„状æ
    1990 ‹ãŒé•·æ™‚間続くか,タイマの現在値を1回目に読んでから2回目に読
    1991 ã‚€ã¾ã§ã®é–“に長い時間がかかった結果,その間に(再度)オーバフローが発生
    1992 ã—た場合に起こる.つまり,タイマ割込みがサービスされない時間が,タイム
    1993 ãƒ†ã‚£ãƒƒã‚¯ã®å‘¨æœŸã‚ˆã‚Šã‚‚長くなった場合である.このような場合には,システム
    1994 æ™‚刻の更新も正しく行われなくなる.
    1995 
    1996 (b) 1回目の値がオーバフロー前の値であるにもかかわらず,1回目の値が2回目
    1997     の値と同じかそれよりも小さくなる場合
    1998 
    1999 ã“のようなケースは,タイマの現在値を1回目に読んでから2回目に読むまでの
    2000 é–“に,タイマがほぼ1周分カウントアップした場合に起こる.この場合も,タイ
    2001 ãƒžå‰²è¾¼ã¿ãŒç¦æ­¢ã•ã‚Œã¦ã„る時間が,タイムティックの周期よりも長かったこと
    2002 ã«ãªã‚Šï¼Œã‚·ã‚¹ãƒ†ãƒ æ™‚刻の更新が正しく行えなくなる.
    2003 
    2004 ã„ずれのケースも,タイマ割込みが長時間禁止されている,タイマ割込みより
    2005 ã‚‚優å
    2006 ˆåº¦ã®é«˜ã„割込み処理が長時間続けて実行された,シミュレーション環境
    2007 ã«ãŠã„てシミュレータのプロセスが長時間スケジュールされなかったなどの理
    2008 ç”±ã§ï¼Œã‚·ã‚¹ãƒ†ãƒ æ™‚刻の更新が正しく行えない状況に相当する.そこでこの状況
    2009 ã‚’,サービスコール使用上の注意事é 
    2010 ã«ç››ã‚Šè¾¼ã‚€ï¼Ž
    2011 
    2012 å®Ÿéš›ã®ã‚³ãƒ¼ãƒ‰ã«ãŠã„ては,システム時刻の現在値は変数に保持されていないた
    2013 ã‚ï¼ˆä¸Šä½æ¡ã¯current_timeに保持されているが,下位桁を保持する変数がな
    2014 ã„),次のタイムティックのシステム時刻を用いて計算している.そのため,
    2015 ã‚¿ã‚¤ãƒžã®ç¾åœ¨å€¤ãŒã‚ªãƒ¼ãƒãƒ•ãƒ­ãƒ¼å¾Œã®å€¤ã§ã‚ると判断した場合を除いては,タイ
    2016 ãƒ ãƒ†ã‚£ãƒƒã‚¯ã®å‘¨æœŸæ™‚間を,求めた性能評価用システム時刻から減算する.この
    2017 å‡¦ç†ã«ã‚ˆã‚Šï¼Œã‚µãƒ¼ãƒ“スコールの実行時間が変動することになるが,if文のå†
    2018 å®¹
    2019 ãŒï¼ˆã‚³ãƒ³ãƒ‘イラの最適化を仮定すると)定数値の減算1回なので,変動はわずか
    2020 ã§ã‚る.
    2021 
    2022 ã“のサービスコールは,任意の状æ
    2023 ‹ã‹ã‚‰å‘¼ã³å‡ºã™ã“とができるため,SILのå
    2024 ¨å‰²
    2025 è¾¼ã¿ãƒ­ãƒƒã‚¯æ©Ÿèƒ½ã‚’用いて,サービスコールå†
    2026 éƒ¨ã®ã‚¯ãƒªãƒ†ã‚£ã‚«ãƒ«ã‚»ã‚¯ã‚·ãƒ§ãƒ³ã‚’実
    2027 ç¾ã™ã‚‹ï¼Ž
    2028 
    2029 
    2030 â—‹ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理禁止フラグをenatexで実è£
    2031 ã—ている理由
    2032 
    2033 ã‚¿ã‚¹ã‚¯ä¾‹å¤–処理禁止フラグは,TCB中のenatexフィールド(タスク例外処理許可
    2034 çŠ¶æ
    2035 ‹ã§ã‚ることを示す)の形で保持している.このフィールドをdistexとせず
    2036 enatexとしたのは,JSPカーネルにおいてタスクディスパッチ禁止フラグを
    2037 enadspの形で保持したのと整合させたためである.
    2038 
    2039 ASPカーネルでは,enadspはdisdspに変更になったことから,enatexもdistexに
    2040 å¤‰æ›´ã—た方が良かったと思われる.
    2041 
    2042 ä»¥ä¸Š
     1340この警告メッセージの原因は,直接的には,&winfo_semを(WINFO_WOBJ *)にキャ
     1341ストしていることであるが,本質的な原因は,このコードがC言語のstrict
     1342aliasing ruleに従わない代入文の原因になる可能性があり,このルールに依存
     1343した最適化が誤った結果を引き起こす可能性があることである.
     1344
     1345C言語のstrict aliasing ruleは,互換性のない異なる型を通して,オーバラッ
     1346プするメモリ領域をアクセスする代入文を使用してはならないというものであ
     1347る(使用した場合の振舞いは未定義になる).このケースでは,(WINFO_SEM
     1348*)型のポインタ経由と(WINFO_WOBJ *)型のポインタ経由で,オーバラップする
     1349メモリ領域をアクセスする代入文を使用してはならないことになる.また,警
     1350告メッセージの原因になってはいないが,(SEMCB *)型のポインタ経由と
     1351(WOBJCB *)型のポインタ経由で,オーバラップするメモリ領域をアクセスする
     1352代入文を使用してはならない.
     1353
     1354ASPカーネルの実装においては,semaphore.c中の関数においては,(SEMCB *)型
     1355および(WINFO_SEM *)型のポインタを使用しており,(WOBJCB *)型および
     1356(WINFO_WOBJ *)型のポインタ経由でメモリ領域をアクセスすることはない.一
     1357方,そこから呼び出されるwait.c中の関数においては,(WOBJCB *)型および
     1358(WINFO_WOBJ *)型のポインタを使用しており,(SEMCB *)型および(WINFO_SEM
     1359*)型のポインタ経由でメモリ領域をアクセスすることはない.
     1360
     1361strict aliasing ruleに従わない代入文の問題点は,このルールに依存した最
     1362適化が誤った結果を引き起こす可能性があることであるが,異なるコンパイル
     1363単位をまたいで最適化が行われることはないため,これにより問題が起こるこ
     1364とはないと言うことができる.
     1365
     1366同じ議論は,他のソースファイル(eventflag.c,dataqueue.c,pridataq.c,
     1367mailbox.c,mempfix.c)中の警告メッセージについても,そのまま当てはまる.
     1368
     1369
     1370○性能評価用システム時刻参照機能
     1371
     1372●必要性と使途
     1373
     1374ASPカーネルには,ASPカーネル上で動作するタスクやASPカーネル自身の性能を
     1375計測するために,システム時刻より精度の高い性能評価用システム時刻を読み
     1376出す機能をサポートする.性能評価用システム時刻は,マイクロ秒単位で表現
     1377されるが,実際の精度はターゲット依存である.
     1378
     1379この機能を用いてあるプログラムの実行時間を計測するには,その実行直前と
     1380実行直後に性能評価用システム時刻を読み出し,その差を求める.そのため,
     1381性能評価用システム時刻は常に相対値を使用し,性能評価用システム時刻の絶
     1382対値を使用することは想定していない.
     1383
     1384●API仕様
     1385
     1386性能評価用システム時刻参照機能では,次のデータ型を用いる.
     1387
     1388        SYSUTM          性能評価用システム時刻(符号無し整数,単位はマイクロ秒,
     1389                                32ビット以上)
     1390
     1391SYSUTM型は,ターゲット非依存部においてulong_t型(すなわち,unsigned
     1392long型)に定義されており,そのサイズは,32ビット以上で,ターゲット定義
     1393である.
     1394
     1395性能評価用システム時刻がSYSUTM型で表現できる範囲を超えた(つまり,オー
     1396バフローした)場合,性能評価用システム時刻は0に戻る.評価対象プログラム
     1397の実行前後の性能評価用システム時刻の差を求める場合には,計測する時間が
     1398SYSUTM型で表現できる範囲である限り,0に戻ることを特別に考慮する必要はな
     1399い.
     1400
     1401SYSUTM型が32ビットの場合,性能評価用システム時刻は約71分でオーバフロー
     1402する.そのため,この機能を71分を越える時間の測定に使った場合の動作は保
     1403証されない.
     1404
     1405性能評価用システム時刻参照機能のためのサービスコールの仕様については,
     1406「TOPPERS新世代カーネル統合仕様書」の「4.6.1 システム時刻管理」の節を参
     1407照すること.
     1408
     1409●実装
     1410
     1411時刻をマイクロ秒単位で取得するために,周期的なタイムティックを供給する
     1412タイマの現在値(タイマはカウントアップするものと仮定する)を読み出し,
     1413それをマイクロ秒単位に換算した値に,現在のシステム時刻(ミリ秒単位で表
     1414現される)を1000倍した値を加えたものを性能評価用システム時刻とする.現
     1415在のシステム時刻を1000倍する際に,オーバフローが発生する可能性があるが,
     1416無視してかまわない.
     1417
     1418ただし,システム時刻の現在値とタイマの現在値を一貫した状態で読み出すの
     1419は容易ではない.両方の値を順に読み出すと,読出しの間にタイマがオーバフ
     1420ローして割込み要求が発生した場合に,片方はオーバフロー前の値,もう片方
     1421はオーバフロー後の値を読んでしまい,誤った性能評価用システム時刻を取得
     1422してしまう.
     1423
     1424この問題を解決する方法はいくつか考えられるが,どの方法を採用するの決定
     1425にあたり,次の要求事項を設定した.
     1426
     1427(1) 多くのターゲットシステムで実現できること.
     1428
     1429(2) サービスコールの実行時間が可能な限り一定となること.言い換えると,
     1430    条件によってサービスコールの実行時間が大きく変動しないこと.
     1431
     1432(3) サービスコール中の可能な限り同じタイミングの時刻を返すこと.言い換
     1433    えると,条件によって時刻を読み取るタイミングが変動しないこと.
     1434
     1435(4) 調整する必要のあるパラメータを最小限とすること.
     1436
     1437これらの要求事項を満たす方法として,次の方法を用いることにした.
     1438
     1439まず,NMIを除くすべての割込みを禁止した状態で,システム時刻の現在値,タ
     1440イマの現在値(1回目),タイマ割込み要求の有無,タイマの現在値(2回目)
     1441を,この順で読み出す.割込みを禁止しているため,この間にシステム時刻の
     1442現在値が変化することはなく,システム時刻の現在値を読み出す順番はどこで
     1443もよい.また,タイマの現在値の2回目の読出しは,タイマ割込み要求があった
     1444場合にのみ必要となるが,(2)の要求から,タイマ割込み要求の有無によらず読
     1445み出すこととする.
     1446
     1447これらの値を読み出した後,割込み禁止を解除し,次の処理を行う.まず,タ
     1448イマ割込み要求がなかった場合には,システム時刻の現在値と,1回目に読んだ
     1449タイマの現在値は一貫した値であることが保証できるため,これらの値から性
     1450能評価用システム時刻の現在値を求める.
     1451
     1452次にタイマ割込み要求があった場合には,1回目に読んだタイマの現在値が,タ
     1453イマ割込み要求発生前の値(オーバフロー前の値)である場合と,発生後の値
     1454(オーバフロー後の値)である場合の両方の可能性が考えられる.このどちら
     1455の場合であったかを,2回目に読んだタイマの現在値を使って,次のように決定
     1456する.2回目の値は,タイマ割込み要求発生後の値(オーバフロー後の値)であ
     1457ることが保証できるため,1回目の値が2回目の値よりも大きい場合には,その
     1458間にオーバフローがあったものと推測できる.つまり,1回目の値はオーバフロー
     1459前の値ということになり,システム時刻の現在値と一貫した値であるとして性
     1460能評価用システム時刻の現在値を求める.逆に,1回目の値が2回目の値と同じ
     1461かそれより小さい場合には,1回目の値はオーバフロー後の値であると推測でき
     1462る.この場合には,次のタイムティックのシステム時刻を求め,その値と1回目
     1463の値が一貫した値であるとして性能評価用システム時刻の現在値を求める.
     1464
     1465ここで,タイマ割込み要求があった場合には,2回目に読んだタイマの現在値を
     1466用いる方法が考えられるが,(3)の要求を満たさなくなるために採用しなかった.
     1467また,JSPカーネルと同様の方法は,(4)の要求を満たさないために採用しなかっ
     1468た.
     1469
     1470上で「推測できる」としたのは,この推測が成り立たなくなるケースがあるた
     1471めである.この推測が成り立たなくなるケースは,次の2つの場合に分けて分析
     1472することができる.
     1473
     1474(a) 1回目の値がオーバフロー後の値であるにもかかわらず,1回目の値が2回目
     1475    の値よりも大きくなる場合
     1476
     1477このようなケースは,タイマ割込みが要求されているにもかかわらずサービス
     1478されない状態が長時間続くか,タイマの現在値を1回目に読んでから2回目に読
     1479むまでの間に長い時間がかかった結果,その間に(再度)オーバフローが発生
     1480した場合に起こる.つまり,タイマ割込みがサービスされない時間が,タイム
     1481ティックの周期よりも長くなった場合である.このような場合には,システム
     1482時刻の更新も正しく行われなくなる.
     1483
     1484(b) 1回目の値がオーバフロー前の値であるにもかかわらず,1回目の値が2回目
     1485    の値と同じかそれよりも小さくなる場合
     1486
     1487このようなケースは,タイマの現在値を1回目に読んでから2回目に読むまでの
     1488間に,タイマがほぼ1周分カウントアップした場合に起こる.この場合も,タイ
     1489マ割込みが禁止されている時間が,タイムティックの周期よりも長かったこと
     1490になり,システム時刻の更新が正しく行えなくなる.
     1491
     1492いずれのケースも,タイマ割込みが長時間禁止されている,タイマ割込みより
     1493も優先度の高い割込み処理が長時間続けて実行された,シミュレーション環境
     1494においてシミュレータのプロセスが長時間スケジュールされなかったなどの理
     1495由で,システム時刻の更新が正しく行えない状況に相当する.そこでこの状況
     1496を,サービスコール使用上の注意事項に盛り込む.
     1497
     1498実際のコードにおいては,システム時刻の現在値は変数に保持されていないた
     1499め(上位桁はcurrent_timeに保持されているが,下位桁を保持する変数がな
     1500い),次のタイムティックのシステム時刻を用いて計算している.そのため,
     1501タイマの現在値がオーバフロー後の値であると判断した場合を除いては,タイ
     1502ムティックの周期時間を,求めた性能評価用システム時刻から減算する.この
     1503処理により,サービスコールの実行時間が変動することになるが,if文の内容
     1504が(コンパイラの最適化を仮定すると)定数値の減算1回なので,変動はわずか
     1505である.
     1506
     1507このサービスコールは,任意の状態から呼び出すことができるため,SILの全割
     1508込みロック機能を用いて,サービスコール内部のクリティカルセクションを実
     1509現する.
     1510
     1511
     1512○タスク例外処理禁止フラグをenatexで実装している理由
     1513
     1514タスク例外処理禁止フラグは,TCB中のenatexフィールド(タスク例外処理許可
     1515状態であることを示す)の形で保持している.このフィールドをdistexとせず
     1516enatexとしたのは,JSPカーネルにおいてタスクディスパッチ禁止フラグを
     1517enadspの形で保持したのと整合させたためである.
     1518
     1519ASPカーネルでは,enadspはdisdspに変更になったことから,enatexもdistexに
     1520変更した方が良かったと思われる.
     1521
     1522以上
Note: See TracChangeset for help on using the changeset viewer.