(toppers-users 3811) Re: SSPの DEF_EPRI とは何でしょうか。

koizumi yoshiyuki koizumiyoshiyuki @ gmail.com
2012年 1月 22日 (日) 00:59:51 JST


  斉藤さん

こいさんです。

全部理解できたわけでは有りませんが、動作可能タスク数を記憶する必要がありそうです。

もし、起動タスクのキューを新たに作るなら、動作可能タスクのカウンタを作れば、primapがキューとして使えそうだといったレベルでこの話は終わりにしましょうか。


追伸
 2つの優先度の話が色々議論されていますが、参加できずにいます。優先度とディスパッチの現状の仕様を共通に認識できるようにして欲しいと思います。
私がソースを読んで認識していることをメモにしました。起動キューのように漏れがあるかも知れませんが、たたき台になれば幸いです。

SSPの優先度

・ SSPのタスクは優先度を2つ持っています。起動優先度(_PRIORITY)と実行優先度(_EXEPRIORITY)が有ります。
・ 起動優先度は全てのタスクで異なりますが、タスクは同じ実行優先度を持つことが可能です。
・ 実行優先度の指定を省略すると起動優先度と同じ値が割り当てられます。
・ 実行優先度を指定する場合は、起動優先度より高い優先度を指定する必要があります。
・
タスク起動要求が発生するとディパッチャが呼び出され、ディパッチャは動作中のタスクの実行優先度と、実行待ちタスクの最も高い起動優先度を持つタスクの実行優先度を比較し、実行待ちタスクの実行優先度が高い場合はタスク切り替えが発生します。

ディパッチアルゴリズム
・ 複数の同一実行優先度のタスクが起動された状態では、実行中のタスクが優先権を持ちます。
・ 実行中のタスクがなかった場合は、起動優先度が高いものが優先権を持ちます。
・ 実行中のタスクが終了したとき、次に動作するタスクは起動優先度の高いものが優先権を持ちます。
・ 実行優先が実行中の実行優先度より高い場合でも、起動優先度が低い場合は起動されない。

  動作の違い

1 同一実行優先度を持つタスクが複数起動された場合、
ASPやJSPでは同一優先度のタスクは起動順に優先度が割り当てられている。(FIFO方式)
  SSPでは起動優先度定まる。SSPでは高い起動優先度持つタスクが優先される。(待ちタスクは起動優先度による最優先方式)

よって、3つ以上の同一優先度のタスクが起動された場合、起動優先度の高い2つのタスク以外は起動されない場合(長い時間待たされる)が発生する。

2 実行優先度が高くても、起動優先度が高いタスクが優先される。
違いに含めてよいか解りませんが、注として上げました。

以上


2012年1月21日23:46 Naoki Saito <nsaito.nmiri @ gmail.com>:

> こいさんさん
>
> 斉藤です.
>
> キューイングの件,ご提案ありがとうございます.
>
> >  タスクの軌道前にprimap_clearをすると、sanple1ではASPと同様にキューイングが実現できているように動作します。
>
> 一見すると良いアイディアのように思えるのですが,
> 例えば 2つのタスクTASK1(ID=1), TASK2(ID=2)があり,
> TASK1 の方が高優先度とします.
> そしてシステム起動時には TASK1 が休止状態,
> TASK2が実行可能状態とします.
>
> (0) カーネルスタート(primap = 1)
> (1) TASK1 実行開始 (run_task でクリアされて primap = 0)
> (2) TASK1 の中から TASK2 起動 (primap = 2)
> (3) TASK2 実行開始 (primap = 0)
> (4) TASK2 終了
>
> ここまでは良いのですが,run_task の while 判定
>  /* 戻り先タスクの実行時優先度より高い起動時優先度をもつタスクが起動されたか */
> } while((!primap_empty()) && (saved_pri > (next_pri = search_schedtsk())));
>
> の primap_empty() が true となり,終了しませんか?
>
> 以上,よろしくお願い致します.
>
> 2012年1月20日9:38 koizumi yoshiyuki <koizumiyoshiyuki @ gmail.com>:
> >  こいさんです。
> >
> >  言葉が足りずにすみません。申し訳なく思っています。
> >
> >  優先度の指定時に、_EXEPRIORITY設定によっては
> > TASK3が動作しているとにTASK4が動作せず、
> > TASK4が動作中にTASK3が動作しない
> >  ケースはユーザがそのような優先度指定を要求しているのだと、SSPでは考えてる、と理解しました。
> >  仕様なら了解です。
> >
> >
> >  起動キューイングの話ですが、折角なのでもう少し考えて見ました。
> >
> >  起動してしまったタスクのready_primapフラグを使うケースは無いような気がしています。
> >  タスクの軌道前にprimap_clearをすると、sanple1ではASPと同様にキューイングが実現できているように動作します。
> >  ただし、sample1以外のケースのことまでは考えていません。
> >
> >  sample1でキーから 2,a,1,a,a,e,e,2,e と操作すると以下のように動作します。
> >
> > void run_task(uint_t ipri)の修正
> >  do {
> >   runtsk_ipri = tinib_epriority[next_pri];
> >
> >   /* ビットマップクリア. */
> >   primap_clear(next_pri); // タスク起動前に移動
> >
> >   /* CPUロック解除 */
> >   t_unlock_cpu();
> >
> >   /* タスク実行開始 */
> >   (*((TASK)(tinib_task[next_pri])))(tinib_exinf[next_pri]);
> >
> >   if (t_sense_lock()) {
> > 実行結果
> > Sample program starts.
> >  Task  2 activate. 2,eでTASK2が起動
> >  Task  2 running.
> >  Task  2 running.
> >  Task  2 running.
> >  Task  1 activate.
> 1,aでTASK1が起動、TASK2より優先度が高いのでTASK2は動作としては待たされている(又、叱られそう)
> >  Task  1 running.
> >  Task  1 running. aでTASK1の起動キューイング
> >  Task  1 running.
> >  Task  1 running.
> >  Task  1 running.
> >  Task  1 exit. eでTASK1終了したが
> >  Task  1 activate. TASK1のキューイングでTASK1起動
> >  Task  1 running.
> >  Task  1 running.
> >  Task  1 exit. e、でタスク終了
> >  Task  2 running. 中断中のTASK2が動作を継続
> >  Task  2 running.
> >  Task  2 running.
> >  Task  2 running.
> >  Task  2 running.
> >  Task  2 exit. 2、eでタスク終了
> >  なんとなく出来そうですね。
> >
> >  以上
> > 2012年1月19日23:09 Naoki Saito <nsaito.nmiri @ gmail.com>:
> >>
> >> 斉藤です.
> >>
> >>
> >> > >
>  優先度の問題は設計方針の話だと思っています。現行、_EXEPRIORITYが一つのとき矛盾した値を設定すとCFGがエラーを通知してくれています。(私はCFGのプログラムを読みきれません。私がテストしたケースはエラーになった。テストした値は忘れました)
> _EXEPRIORITYを2つ設けて前に書いたような設定をしたとき、(私的には)矛盾が起きます。これが仕様で、使い方の誤りというなら了解です。
> >>
> >> 仕様上は間違いではありません.
> >> その上で,間違った使い方(パラメータの設定の仕方がおかしいとか)であるか
> >> どうかについては,何をしたいプログラムかによりますので,分かりません.
> >>
> >> >
> >> > ・
> 例で上げたケースをCFGでエラーにすることは出来とおもいます。_kernel_tinib_epriorityが昇順(同じ値は正しい)でなければエラーでよいと思います。
> >>
> >> 仕様上は誤りではありませんので,エラーには出来ません.
> >> _kernel_tinib_epriority が昇順であるべきという意見はまだ良く理解出来ていません.
> >> その必要は無いと考えています.
> >>
> >> それから,(toppers-users 3790) にて,
> >> >>> 2番目の文に対しては,当然でたらめになり得ます.
> >> と書きましたが,「でたらめ(出鱈目)」という言葉は辞書で
> >> 「根拠が無い」とか「首尾一貫しない」というような意味だそうです.
> >>
> >> 一応は,仕様で定められた振る舞いを行うように作っていまして
> >> 仕様上説明の出来ない結果を出さないようにしているつもりです.
> >> (もちろんテストしてますがバグが無いことを完全に示せている訳では
> >> ありませんし,開発環境の要因により説明出来ない結果になる可能性は
> >> 否定出来ませんが)
> >>
> >> 従いまして,でたらめというのが,仕様上説明出来ないような結果となることを
> >> 意味するのだとしたら,優先度がでたらめになることは基本的にないと
> >> 考えております.
> >> ただし,使い方によっては目的に沿わない結果となる可能性はあり得ます.
> >> という具合に訂正したいと思います.
> >>
> >> 以上です.
> >>
> >> 2012年1月19日21:12 koizumi yoshiyuki <koizumiyoshiyuki @ gmail.com>:
> >> > こいさんです
> >> >
> >> >  キューイングの話は、ロックして終了すればよいですね。
> >> >
> >> >
> (私の勘違いがありました。タスク終了時の、禁止解除を逆に解釈。フラグのセット、クリア時だけの短い時間のロックを小まめに実施と勝手に理解。長いロックは嬉しくないですからね。ここでは私の想像より長いロックでした。お騒がせしてすみません)
> >> >
> >>
> >> > >
>  優先度の問題は設計方針の話だと思っています。現行、_EXEPRIORITYが一つのとき矛盾した値を設定すとCFGがエラーを通知してくれています。(私はCFGのプログラムを読みきれません。私がテストしたケースはエラーになった。テストした値は忘れました)
> _EXEPRIORITYを2つ設けて前に書いたような設定をしたとき、(私的には)矛盾が起きます。これが仕様で、使い方の誤りというなら了解です。
> >> >
> >> >  ただし、回避策としては
> >> >
> >> > ・
> 例で上げたケースをCFGでエラーにすることは出来とおもいます。_kernel_tinib_epriorityが昇順(同じ値は正しい)でなければエラーでよいと思います。
> >> >
> >> > ・
> 又、Cortex-M3の割り込み優先度のように優先度を16*2にしてprimap_searchの優先度は前半の16bitを使う手法もあるとは思います。こちらは意図が変わるので採用はどうかと思う。
> >> >
> >> > どちらも本当に出来かまで考えたわけでは有りません。
> >> >  SSPはダイナミックに優先度が変更できるシステムではないので回避策はあると思っています。
> >> >
> >> >  似たような意味のパラメータを2箇所で指定すると指定誤りは犯しやすいものです(特に私は)。
> >> >  それが仕様なら、注意書きくらい欲しいですね。
> >> >
> >> >  又、余分な話
> >> >
>  勝手ながら、_PRIORITYはdefineではなく、enumにした方がスマートな気もします。(歴史的な経緯も有るでしょう、余分な話ですね)
> >> >  _EXEPRIORITYは即値ではなく、xx_PRIORITYが良いかな。 と独り言。
> >> >
> >> >  そうだ、こんな書き方もありますかね。
> >> > #if 0
> >> > #define INIT_PRIORITY   (1)
> >> > #define MAIN_PRIORITY   (2)
> >> > #define TASK1_PRIORITY   (3)
> >> > #define TASK2_PRIORITY   (4)
> >> > #define TASK3_PRIORITY   (5)
> >> > #define TASK4_PRIORITY   (6)
> >> > #define TASK3_EXEPRIORITY  (4)
> >> > #define TASK4_EXEPRIORITY  (3)
> >> > #else
> >> > enum {
> >> >  INIT_PRIORITY = 1,
> >> >  MAIN_PRIORITY,
> >> >  TASK1_PRIORITY,
> >> >  TASK2_PRIORITY,
> >> >  TASK3_EXEPRIORITY = TASK2_PRIORITY,
> >> >  TASK4_EXEPRIORITY = TASK2_PRIORITY, //if0の矛盾とは違っています
> >> >  TASK3_PRIORITY,
> >> >  TASK4_PRIORITY,
> >> > };
> >> > #endif
> >> >  _EXEPRIORITYは前に書くので美しくないかね。
> >> >
> >> >  以上
> >> >
> >> > 2012年1月19日19:39 Naoki Saito <nsaito.nmiri @ gmail.com>:
> >> >>
> >> >> 斉藤です。
> >> >>
> >> >> >  2番目の文に対しては,当然でたらめになり得ます.
> >> >> > しかしそれは使い方次第です.どんなむちゃくちゃなプロ グラムを書いても
> >> >> > ちゃんと動けというのはそりゃムリです.
> >> >>
> >> >> とはいいましても
> >> >> できるだけ問題を検知出来るような、
> >> >> OSやツールの機能が提供できれば
> >> >> とも考えておりますので、
> >> >> どのような心配事が有り得るか
> >> >> 御教示いただければとも思います。
> >> >>
> >> >> 以上、よろしくお願いします。
> >> >>
> >> >> 2012/01/19 18:58 "Naoki Saito" <nsaito.nmiri @ gmail.com>:
> >> >>>
> >> >>> 斉藤です.
> >> >>> (toppers-users 3788) を確認したという前提の元で,お返事します.
> >> >>>
> >> >>> > TASK3が動作しているときはTASK4が動かず、
> >> >>> (略)
> >> >>> >  これが意図とでは優先度とは何よと思いたくなるのは、私だけでしょうかね。
> >> >>>
> >> >>> 逆に.優先度とはどのようなものと思われたのか,興味を持ちました.
> >> >>>
> >> >>> 例として仰られたようなケースは一つの使い方でして,
> >> >>> そのような挙動をさせたいというケースもないとはいえないです.
> >> >>> 例えば (toppers-users 3781) で高田先生が仰られた様な
> >> >>> スタック領域が少なくて済むようにしたいというのもその一つかと思います.
> >> >>> 排他制御のためにそうしたいという理由もあると思います.
> >> >>>
> >> >>>
> >> >>> >
> >> >>> > > >
>  どちらのタスクが優先度が高いのかと一言で表現できないのは、美しくないと思います。やる人はいないと思うが、もっと複雑な(誤った?)設定をした場合、優先度がでたらめになりませんか。
> >> >>>
> >> >>> 最初の文に対して,
> >> >>> 美しいかどうかは主観的な評価なのでなんとも申し上げることは出来ませんが
> >> >>> 仰るような考え方によりますと,動的に優先度が変更し得るOSは皆美しくない
> >> >>> ことになりますね.そういう理解で合ってますでしょうか?
> >> >>> 現存するOSはそういうものも割と多いと思いますが,どう思われます?
> >> >>>
> >> >>> 2番目の文に対しては,当然でたらめになり得ます.
> >> >>> しかしそれは使い方次第です.どんなむちゃくちゃなプログラムを書いても
> >> >>> ちゃんと動けというのはそりゃムリです.
> >> >>>
> >> >>> 以上,適切なお答えになっているか心配ですが,よろしくお願いします.
> >> >>>
> >> >>> 2012年1月19日16:15 koizumi yoshiyuki <koizumiyoshiyuki @ gmail.com>:
> >> >>> >  こいさんです
> >> >>> >
> >> >>> >  理屈としては解るのですが、この場合
> >> >>> > TASK3が動作しているときはTASK4が動かず、
> >> >>> > TASK3が動作しているときはTASK4が動きません。
> >> >>> >  これが意図とでは優先度とは何よと思いたくなるのは、私だけでしょうかね。
> >> >>> >
> >> >>>
> >> >>> >
> >> >>> > > >
>  どちらのタスクが優先度が高いのかと一言で表現できないのは、美しくないと思います。やる人はいないと思うが、もっと複雑な(誤った?)設定をした場合、優先度がでたらめになりませんか。
> >> >>> >
> >> >>> >  まあ、意図なら納得するしかありません。
> >> >>> >
> >> >>> >  以上
> >> >>> >
> >> >>> > 2012年1月19日15:39 Naoki Saito <nsaito.nmiri @ gmail.com>:
> >> >>> >>
> >> >>> >> こいさんさん
> >> >>> >>
> >> >>> >> 斉藤です.
> >> >>> >>
> >> >>> >> >  現行のSSPのCFGで以下の設定をすると、優先度反転が発生します。これは良いのでしょうか。
> >> >>> >> >  TASK3が動作中にTASK4はTASK3より優先度が高いのに起動できません。
> >> >>> >>
> >> >>> >> TASK3 の実行時優先度は4で,TASK4の起動時優先度は6ですので
> >> >>> >> TASK4 は TASK3 より優先度が低い(数値としては大きい)です.
> >> >>> >> したがってTASK4 が起動出来ないのは仕様に沿っているように思います.
> >> >>> >>
> >> >>> >> >  CFGで生成されたkernel_cfg.cは以下のようになり、TASK3とTASK4の優先度の反転が発生しています。
> >> >>> >> >
> >> >>> >> > const uint_t   _kernel_tinib_epriority[TNUM_TSKID] =
> >> >>> >> >
> >> >>> >> >
> >> >>> >> >
> >> >>> >> >
> {INT_PRIORITY(1),INT_PRIORITY(2),INT_PRIORITY(3),INT_PRIORITY(4),INT_PRIORITY(4),INT_PRIORITY(3)};
> >> >>> >>
> >> >>> >> これは実行時優先度を格納する配列です.
> >> >>> >> プリエンプトが発生するかどうかは
> >> >>> >> 実行中タスクの実行時優先度と起動要求タスクの起動時優先度とを
> >> >>> >> 比較します.従いまして,TASK4 の実行時優先度はこの場合参照されません.
> >> >>> >>
> >> >>> >> 以上,よろしくお願いします.
> >> >>> >>
> >> >>> >> 2012年1月19日10:59 koizumi yoshiyuki <koizumiyoshiyuki @ gmail.com>:
> >> >>> >> >    高田先生
> >> >>> >> >
> >> >>> >> >  こいさんです。表現は色々有ると思いますが、私にはSSPは優先度を2つ持っているように見えています。
> >> >>> >>
> >> >>> >> >
> >> >>> >> > > >  2つの優先度は _PRIORITY >_EXEPRIORITY
> 設定されてる必要が有るでしょう。これは解りにくいケースもあると思います。
> >> >>> >> >
> >> >>> >>
> >> >>> >> >
> >> >>> >> > >
> >> >>> >> > > > >
>  同じようなケースが(私にはある意味、同じように見えています)Cortex-M3の割り込み優先度に見られます。ここでは優先度を上位/下位の2つに分け、上位側で横取り割り込み優先度とし、下位側は等優先度内(制約タスク相当)の優先度としています。外からは優先度は一つしかないので優先度設定の混乱を避けることができていると思います。
> >> >>> >> >
> >> >>> >> >  尚、
> >> >>> >> >  現行のSSPのCFGで以下の設定をすると、優先度反転が発生します。これは良いのでしょうか。
> >> >>> >> >  TASK3が動作中にTASK4はTASK3より優先度が高いのに起動できません。
> >> >>> >> >
> >> >>> >> >  テストタスクを3つから4つに増やし優先度を以下のように設定する
> >> >>> >> >
> >> >>> >> >  sample1.h
> >> >>> >> > #define INIT_PRIORITY   (1)
> >> >>> >> > #define MAIN_PRIORITY   (2)
> >> >>> >> > #define TASK1_PRIORITY   (3)
> >> >>> >> > #define TASK2_PRIORITY   (4)
> >> >>> >> > #define TASK3_PRIORITY   (5)
> >> >>> >> > #define TASK4_PRIORITY   (6)
> >> >>> >> > #define TASK3_EXEPRIORITY  (4)
> >> >>> >> > #define TASK4_EXEPRIORITY  (3)
> >> >>> >> >
> >> >>> >> >  sample1.cfgを以下のように記述
> >> >>> >> > CRE_TSK(INIT_TASK , { TA_ACT , 0 , init_task , INIT_PRIORITY ,
> >> >>> >> > STACK_SIZE ,
> >> >>> >> > NULL });
> >> >>> >> > CRE_TSK(MAIN_TASK , { TA_NULL , 0 , main_task , MAIN_PRIORITY ,
> >> >>> >> > STACK_SIZE ,
> >> >>> >> > NULL });
> >> >>> >> > CRE_TSK(TASK1 , { TA_NULL , 1 , task , TASK1_PRIORITY ,
> >> >>> >> > STACK_SIZE ,
> >> >>> >> > NULL
> >> >>> >> > });
> >> >>> >> > CRE_TSK(TASK2 , { TA_NULL , 2 , task , TASK2_PRIORITY ,
> >> >>> >> > STACK_SIZE ,
> >> >>> >> > NULL
> >> >>> >> > });
> >> >>> >> > CRE_TSK(TASK3 , { TA_NULL , 3 , task , TASK3_PRIORITY ,
> >> >>> >> > STACK_SIZE ,
> >> >>> >> > NULL
> >> >>> >> > });
> >> >>> >> > CRE_TSK(TASK4 , { TA_NULL , 4 , task , TASK4_PRIORITY ,
> >> >>> >> > STACK_SIZE ,
> >> >>> >> > NULL
> >> >>> >> > });
> >> >>> >> > DEF_EPRI(TASK3 , { TASK3_EXEPRIORITY });
> >> >>> >> > DEF_EPRI(TASK4 , { TASK4_EXEPRIORITY });
> >> >>> >> >  CFGで生成されたkernel_cfg.cは以下のようになり、TASK3とTASK4の優先度の反転が発生しています。
> >> >>> >> >
> >> >>> >> > const uint_t   _kernel_tinib_epriority[TNUM_TSKID] =
> >> >>> >> >
> >> >>> >> >
> >> >>> >> >
> >> >>> >> >
> {INT_PRIORITY(1),INT_PRIORITY(2),INT_PRIORITY(3),INT_PRIORITY(4),INT_PRIORITY(4),INT_PRIORITY(3)};
> >> >>> >> >  以上
> >> >>> >
> >> >>> >
> >> >
> >> >
> >
> >
>
-------------- next part --------------
HTMLの添付ファイルを保管しました...
URL: <http://www.toppers.jp/pipermail/users/attachments/20120122/3ffd0c9a/attachment.html>