[openrtm-users 03222] ECの実装についての提案

1 つの投稿 / 0 new
tmsimiz
オフライン
Last seen: 8年 4ヶ月 前
登録日: 2011-05-23 10:15
[openrtm-users 03222] ECの実装についての提案

OpenRTM-aist開発者各位

静岡大の清水です。

コンポーネントのonExecute()から自身をdeactivateした場合、
現行のECの実装では、deactivate_component()がタイムアウト付きの
同期呼び出しになっているため、必ずタイムアウト時間(10秒)
待たせられます。

さらに、deactivate_component()の戻り値がERRORとなります。

基本的には、deactivate_component()は同期呼び出しの方が
よいと思いますが、上記のように、コンポーネント内部から
自分をdeactivateしたい場合はデッドロックの問題が発生します。

そこで、対処策を考えてみました。
デッドロックが起きるケースは、
あるECが駆動しているRTCの内部から、
そのECが駆動しているRTCのdeactivateを行った場合のみです。
すなわち、deactivate_component()の呼び出し元のスレッドと、
ECのスレッドが同一である場合のみデッドロックが起きます。

よって、deactivate_component()の呼び出し元のスレッドIDと
ECのスレッドIDが一致するかを確認して、
一致する場合は非同期呼び出し、
一致しない場合は同期呼び出しとなるように実装すれば
問題を回避できるはずです。

試しに、Linux(POSIX)環境で上記の実装を行ってみました。
OpenRTM1.1.1のC++ソースとの差分を添付します。
見てもらえればわかりますが、実装は簡単です。

とりあえず、POSIX用しか実装していませんが、
Windowsでも同様の実装ができるはずです。
また、OSによる実装の違いはcoilで吸収できるので、
RTMコアの汎用性やportabilityは保証されます。

上記の実装が上手く機能するか、
以下のようなRTCでテストしてみました。
onExecute()が10000回呼ばれたら自動でdeactivateするという実装です。

onExecute(UniqueId ec_id)
{
   ReturnCode_t ret(RTC_OK);
  

   m_tick++;

   if (m_tick > 10000) {
       ExecutionContext_var ec;
       ec = this->get_context(ec_id);
       ret = ec->deactivate_component(this->getObjRef());

   }

   return ret;

}

テストした結果、上記のパッチを当てたRTMでは、
タイムアウト待ちなしでdeactivateに成功しました。

また、RTSEからdeactivateした場合(別プロセスからdeactivateした場合)は
deactivate_component()は同期呼び出しとなり、
この場合も問題なくdeactivateできました。

以上、deactivate_component()の実装を検討してもらえると幸いです。

清水

未定義

ダウンロード

最新バージョン : 2.0.1-RELESE

統計

Webサイト統計
ユーザ数:2195
プロジェクト統計
RTコンポーネント307
RTミドルウエア35
ツール22
文書・仕様書2

Choreonoid

モーションエディタ/シミュレータ

OpenHRP3

動力学シミュレータ

OpenRTP

統合開発プラットフォーム

産総研RTC集

産総研が提供するRTC集

TORK

東京オープンソースロボティクス協会

DAQ-Middleware

ネットワーク分散環境でデータ収集用ソフトウェアを容易に構築するためのソフトウェア・フレームワーク