トップ «前の日記(2017-12-08) 最新 次の日記(2017-12-10)» 編集

Orz日記 by Akio Morita

ToDo:

  • 15 SAD Fit[]回りの障害事例の解析
  • 10 smart pointer版PEGクラスの再実装(Left Recursionまわり)
2006|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|06|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|07|08|09|10|11|12|
2013|01|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|06|07|08|10|12|
2016|01|02|03|05|06|08|10|11|
2017|01|02|03|04|05|06|07|09|10|11|12|
2018|01|02|03|04|06|07|08|09|10|11|12|
2019|01|03|04|05|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|06|07|08|09|

2017-12-08 [長年日記]

_ [SAD][EPICS]ca_create_channelとca_getに対するca_pend_ioに付いて

マニュアルを読んだ範囲では、handler無しのca_create_channelとca_getのrequestの完了を待つ際の ca_pend_ioの戻り値に付いてまとめると

ECA_NORMAL

ca_pend_ioに先行するhandler無しの ca_create_channelとca_get要求全ての処理が完了している

ECA_TIMEOUT

ca_pend_ioに先行するhandler無しの ca_create_channelとca_get要求のなかに、未完了のものが含まれる。

=未完了の要求のうち、ca_get要求は再実行されるがca_create_channel要求は再実行されない=(2017/12/11訂正)

ca_pend_io以前に投入されたhandler無しのca_create_channel/ca_get要求は、終了・キャンセルされている。 ただし、CA APIレベルで状態を持たないca_get要求の成否は不明となる (2017/12/11追記)

ca_create_channelに関しては、ca_pend_ioからECA_TIMEOUTで戻った時点で接続状態が確定し、ca_stateが cs_never_connもしくはca_prev_conn状態となっており、ca_clear_channelするまで変わらない。 また、ca_create_channelで生成したchidオブジェクトをca_stateで調べれば、接続確立に失敗しているchannelを特定できる(未接続で確定しているので、以降のca_get/ca_putがECA_DISCONNで失敗するので、ca_clear_channelで捨てる以外することが無いはず)

=一方、ca_get要求は再投入されるとのことなので、ca_getへ渡したbuffer pointerは、CA client library内で生存しており、ca_pend_ioがECA_NORMALを返すまで開放することが出来ない=(ca_pend_ioから戻った時点で、参照が開放される 2017/12/11訂正)

また、どのca_get要求が未完了なのかを調べるAPIが存在しないので、 以前に未完了で放置したca_get要求が有った場合、直前のca_getが成功したか否かを判定するには、DBR_TIME型などの付加情報の付いた要求を行いbufferが上書きされてるかを判定することになる。

=TCP/IPの接続タイムアウトで接続が遮断すれば、channel状態がDISCONNへ移行し、当該channelへのca_get要求が廃棄されるはずであるが、それまでの間、ca_getへ渡したbufferを安全に回収出来ない=(2017/12/11削除)

=従って、外部ネットワークに悪意があると考えた場合、ca_getはcallback経由の実装を行うべきと思われる=(2017/12/11削除)

ca_get with callbackのアイデア(リソースリーク対策には不要2017/12/11)

callbackへ任意の参照を渡せ、通信が途中で切断された場合はcallbackはbad statusを伴って呼び出されるとの記載があるので、 callbackへ以下の情報を記録したヒープ上のオブジェクトを渡す。

  • main programとの同期変数
  • 読み出しデータの書き込み先の情報

同期変数の状態は以下の4種

  1. main programは、受け取り待ち中(書き込み先情報が有効)
  2. main programは、受け取りを放棄(キャンセル)
  3. main programへ、受け渡し済み(get成功)
  4. main programへ、受け渡し済み(get失敗)

callbackは、同期変数が状態(1)であることを確認し後、データを書き込み、同期変数を状態(3)もしくは(4)へ遷移させる

callbackが、同期変数が状態(2)であることを確認した場合は、ヒープ上のオブジェクトを開放する

main programは、ca_get_callback後に同期変数が状態(3)もしくは(4)へ変わるのをca_pend_ioを行いながら待ち、受け取りに成功した場合は、ヒープ上のオブジェクトを開放する

main programがtimeoutした場合は、同期変数を状態(2)へ遷移させ、受け取り先の割り当てを解除する

callback動作が、プリエンプトな場合は同期変数の操作はアトミックである必要があり、main programとcallbackが併走する場合は、callback側が動作中であることを示す遷移状態かロックを追加する必要がある

ISO C11で同期変数を実装するならatomic_intとか?

2017/12/11追記

ca_get_callbackによる要求に対して、ca_pend_ioはブロッキング動作しないとの事なので、同期待ちがspin waitもしくはsignalベースとなりあまりうれしくないことが判明

ca_sg_create/ca_sg_array_put/ca_sg_blockを使うべきか?

ca_cg_resetで、同期グループ内でissueされている要求をキャンセルできるようなので、安全にリソースを回収できる

ただし、同期グループに複数のI/Oが含まれる場合、どのI/Oが未完で終わったかを識別するAPIが存在しない

  • 生データ以外の例外値が存在する追加データが存在するタイプを要求し、メモリの上書き状態を確かめる
  • 複数の同期グループを構成し、ca_sg_testで個別に調べる
    • 特定の同期グループに対して、ca_sg_blockした際に他の同期グループのタスクが進行するか否かが自明ではない
    • 複数の同期グループを同時に待つAPIが存在しない
      • ca_sg_testと経過時間測定を組み合わせて自前で作成するか、ca_pend_ioとca_sg_testの組み合わせか?
  • 少なくともca_pend_ioでは、同期グループのタスクは進行しない(3.16.1での実験結果)
  • ca_sg_blockがTIMEOUTした時点で、ca_sg_array_get要求がキャンセルされる(3.16.1での実験結果)
  • 特定の同期グループに対するca_sg_blockで他の同期グループのタスクが処理されない場合、効率的に実装する手段が存在しない

従って、ca_get要求が処理されたかを個別に確認するには、以下の2種に絞られる

  • 付加データを含めて要求し、付加データの領域に予め有り得ない値を書き込み、書き換えを検出する
    • dbr_time型であれば、stamp.nsecが使いやすい(有効値 [0, 999999999])
  • callbackベースで実装する。ただし、timeout待ちのblocking waitが面倒

カテゴリー: Admin | Emacs | EPICS | Fortran | FreeBSD | GCC | hgsubversion | IPv6 | KEKB | LHC | Lisp | LLVM | MADX | Ryzen | SAD | samba | tDiary | unix | WWW | YaSAI | お仕事 | イベント | 出張 | 宴会 | 数学 | 艦これ | 買いもの | 追記 | 雑記