[openrtm-commit:00686] r2326 - in trunk/OpenRTM-aist/src/ext: . ec ec/rtpreempt
openrtm @ openrtm.org
openrtm @ openrtm.org
2012年 2月 9日 (木) 10:17:19 JST
Author: n-ando
Date: 2012-02-09 10:17:19 +0900 (Thu, 09 Feb 2012)
New Revision: 2326
Modified:
trunk/OpenRTM-aist/src/ext/Makefile.am
trunk/OpenRTM-aist/src/ext/ec/Makefile.am
trunk/OpenRTM-aist/src/ext/ec/rtpreempt/RTPreemptEC.cpp
trunk/OpenRTM-aist/src/ext/ec/rtpreempt/RTPreemptEC.h
Log:
[compat,impl/makefile,bigfix] RTPreemptEC has been updated for new ECBase. refs #2366
Modified: trunk/OpenRTM-aist/src/ext/Makefile.am
===================================================================
--- trunk/OpenRTM-aist/src/ext/Makefile.am 2012-02-09 01:13:25 UTC (rev 2325)
+++ trunk/OpenRTM-aist/src/ext/Makefile.am 2012-02-09 01:17:19 UTC (rev 2326)
@@ -7,6 +7,6 @@
AUTOMAKE_OPTIONS = 1.4
-SUBDIRS = ec sdo
+SUBDIRS = local_service ec sdo
Modified: trunk/OpenRTM-aist/src/ext/ec/Makefile.am
===================================================================
--- trunk/OpenRTM-aist/src/ext/ec/Makefile.am 2012-02-09 01:13:25 UTC (rev 2325)
+++ trunk/OpenRTM-aist/src/ext/ec/Makefile.am 2012-02-09 01:17:19 UTC (rev 2326)
@@ -7,7 +7,7 @@
AUTOMAKE_OPTIONS = 1.4
-#SUBDIRS = @ARTLINUX@ @RTPREEMPTEC@
+SUBDIRS = @ARTLINUX@ @RTPREEMPTEC@
-#DIST_SUBDIRS = artlinux rtpreempt logical_time
-SUBDIRS = logical_time
\ No newline at end of file
+DIST_SUBDIRS = artlinux rtpreempt logical_time
+#SUBDIRS = logical_time
Modified: trunk/OpenRTM-aist/src/ext/ec/rtpreempt/RTPreemptEC.cpp
===================================================================
--- trunk/OpenRTM-aist/src/ext/ec/rtpreempt/RTPreemptEC.cpp 2012-02-09 01:13:25 UTC (rev 2325)
+++ trunk/OpenRTM-aist/src/ext/ec/rtpreempt/RTPreemptEC.cpp 2012-02-09 01:17:19 UTC (rev 2326)
@@ -2,75 +2,65 @@
/*!
* @file RTPreemptEC.cpp
* @brief RTPreemptEC class
- * @date $Date$
+ * @date $Date: 2008-01-14 07:53:01 $
* @author Noriaki Ando <n-ando at aist.go.jp>
*
- * Copyright (C) 2010
+ * Copyright (C) 2006-2008,2012
+ * Noriaki Ando
* Intelligent Systems Research Institute,
* National Institute of
* Advanced Industrial Science and Technology (AIST), Japan
* All rights reserved.
*
- * $Id$
+ * $Id: RTPreemptEC.cpp 2307 2012-02-05 21:29:15Z n-ando $
*
*/
-#include "RTPreemptEC.h"
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <sched.h>
#include <sys/mman.h>
-#include <string.h>
-#include <rtm/ECFactory.h>
-#include <rtm/Manager.h>
-#include <coil/stringutil.h>
+#include <algorithm>
+#include <iostream>
+
+#include <coil/Time.h>
+#include <coil/TimeValue.h>
+
+#include <rtm/RTObjectStateMachine.h>
+#include <RTPreemptEC.h>
+
#define MAX_SAFE_STACK (8*1024)
#define NSEC_PER_SEC 1000000000
+#define DEEFAULT_PERIOD 0.000001
-namespace OpenRTM
+namespace RTC_exp
{
/*!
* @if jp
* @brief デフォルトコンストラクタ
* @else
- * @brief Default Constructor
+ * @brief Default constructor
* @endif
*/
- RTPreemptEC::RTPreemptEC()
- : ::RTC::PeriodicExecutionContext(),
- m_priority(49), m_policy(SCHED_FIFO), m_waitoffset(0)
+ RTPreemptEC::
+ RTPreemptEC()
+ : ExecutionContextBase("periodic_ec"),
+ rtclog("periodic_ec"),
+ m_svc(false), m_nowait(false)
{
- rtclog.setName("RTPreemptEC");
- coil::Properties& prop(::RTC::Manager::instance().getConfig());
+ RTC_TRACE(("RTPreemptEC()"));
- // Priority
- getProperty(prop, "exec_cxt.periodic.priority", m_priority);
- getProperty(prop, "exec_cxt.periodic.rtpreempt.priority", m_priority);
- RTC_DEBUG(("Priority: %d", m_priority));
+ // getting my reference
+ setObjRef(this->_this());
- // Policy
- {
- std::string policy;
- getProperty(prop, "exec_cxt.periodic.rtpreempt.sched_policy", policy);
- if (!policy.empty())
- {
- coil::normalize(policy);
- if (policy == "rr") { m_policy = SCHED_RR; }
- if (policy == "fifo") { m_policy = SCHED_FIFO; }
- RTC_DEBUG(("Scheduling policy: %s", policy.c_str()));
- }
- else
- {
- RTC_DEBUG(("Scheduling policy: fifo"));
- }
- }
+ // profile initialization
+ setKind(RTC::PERIODIC);
+ setRate(1.0 / (double)DEEFAULT_PERIOD);
- // Wait offset
- getProperty(prop, "exec_cxt.periodic.rtpreempt.wait_offset", m_waitoffset);
- RTC_DEBUG(("Wait offset: %d [ns]", m_waitoffset));
-
+ RTC_DEBUG(("Actual period: %d [sec], %d [usec]",
+ m_profile.getPeriod().sec(), m_profile.getPeriod().usec()));
}
/*!
@@ -82,88 +72,586 @@
*/
RTPreemptEC::~RTPreemptEC()
{
+ RTC_TRACE(("~RTPreemptEC()"));
+ {
+ Guard guard(m_svcmutex);
+ m_svc = false;
+ }
+ {
+ Guard guard(m_workerthread.mutex_);
+ m_workerthread.running_ = true;
+ m_workerthread.cond_.signal();
+ }
+ wait();
}
+ void RTPreemptEC::init(coil::Properties& props)
+ {
+ RTC_TRACE(("init()"));
+ ExecutionContextBase::init(props);
+
+ setPriority(props);
+ setPolicy(props);
+ setWaitOffset(props);
+
+ RTC_DEBUG(("init() done"));
+ }
+
+
+ /*------------------------------------------------------------
+ * Start activity
+ * ACE_Task class method over ride.
+ *------------------------------------------------------------*/
/*!
* @if jp
+ * @brief ExecutionContext用アクティビティスレッドを生成する
+ * @else
+ * @brief Generate internal activity thread for ExecutionContext
+ * @endif
+ */
+ int RTPreemptEC::open(void *args)
+ {
+ RTC_TRACE(("open()"));
+ activate();
+ return 0;
+ }
+
+ /*------------------------------------------------------------
+ * Run by a daemon thread to handle deferred processing
+ * ACE_Task class method over ride.
+ *------------------------------------------------------------*/
+ /*!
+ * @if jp
* @brief ExecutionContext 用のスレッド実行関数
* @else
* @brief Thread execution function for ExecutionContext
* @endif
- */
- int RTPreemptEC::svc(void)
+ */
+ bool RTPreemptEC::prepareThread()
{
- // schedulaer setting
struct sched_param param;
param.sched_priority = m_priority;
if(sched_setscheduler(0, m_policy, ¶m) == -1)
{
std::cerr << "sched_setscheduler failed" << std::endl;
- return -1;
+ return false;
}
// memory locking
if(mlockall(MCL_CURRENT | MCL_FUTURE) == -1)
{
std::cerr << "mlockall failed" << std::endl;
- return -1;
+ return false;
}
+ return true;
+ }
+ int RTPreemptEC::svc(void)
+ {
+ RTC_TRACE(("svc()"));
+ if (!prepareThread()) { return -1; }
// stack preallocation
unsigned char dummy[MAX_SAFE_STACK];
memset(&dummy, 0, MAX_SAFE_STACK);
- struct timespec t0, t1, t;
+
+ struct timespec ts0, ts1, ts2, ts3;
+ int count(0);
do
{
- clock_gettime(CLOCK_MONOTONIC ,&t0);
- m_worker.mutex_.lock();
- while (!m_worker.running_)
+ ExecutionContextBase::invokeWorkerPreDo();
+ {
+ Guard guard(m_workerthread.mutex_);
+ while (!m_workerthread.running_)
+ {
+ m_workerthread.cond_.wait();
+ }
+ }
+ clock_gettime(CLOCK_MONOTONIC ,&ts0);
+ coil::TimeValue t0(ts0.tv_sec, ts0.tv_nsec * 1000);
+ ExecutionContextBase::invokeWorkerDo();
+ ExecutionContextBase::invokeWorkerPostDo();
+ clock_gettime(CLOCK_MONOTONIC ,&ts1);
+ coil::TimeValue t1(ts1.tv_sec, ts1.tv_nsec * 1000);
+
+ coil::TimeValue period(getPeriod());
+ if (count > 1000)
{
- m_worker.cond_.wait();
+ RTC_PARANOID(("Period: %f [s]", (double)period));
+ RTC_PARANOID(("Execution: %f [s]", (double)(t1 - t0)));
+ RTC_PARANOID(("Sleep: %f [s]", (double)(period - (t1 - t0))));
}
- if (m_worker.running_)
- {
- std::for_each(m_comps.begin(), m_comps.end(), invoke_worker());
- }
- m_worker.mutex_.unlock();
- clock_gettime(CLOCK_MONOTONIC ,&t1);
+ clock_gettime(CLOCK_MONOTONIC ,&ts2);
+ coil::TimeValue t2(ts2.tv_sec, ts2.tv_nsec * 1000);
+ if (m_nowait) { ++count; continue; }
- if (!m_nowait)
+ struct timespec sleeptime;
+ if (getSleepTime(sleeptime, ts0, ts1) == true)
{
- if (t0.tv_nsec > t1.tv_nsec)
+ clock_nanosleep(CLOCK_MONOTONIC, !TIMER_ABSTIME,
+ &sleeptime, NULL);
+ if (count > 1000)
{
- t.tv_nsec = m_period.usec() * 1000
- - (NSEC_PER_SEC - t0.tv_nsec + t1.tv_nsec) + m_waitoffset;
- t.tv_sec = m_period.sec()
- - (t1.tv_sec - 1 - t0.tv_sec);
+ clock_gettime(CLOCK_MONOTONIC ,&ts3);
+ coil::TimeValue t3(ts3.tv_sec, ts3.tv_nsec * 1000);
+ RTC_PARANOID(("Slept: %f [s]", (double)(t3 - t2)));
+ count = 0;
}
- else
- {
- t.tv_nsec = m_period.usec() * 1000
- - (t1.tv_nsec - t0.tv_nsec) + m_waitoffset;
- t.tv_sec = m_period.sec()
- - (t1.tv_sec - t0.tv_sec);
- }
-
- if (t.tv_nsec < 0 || t.tv_sec < 0)
- {
- std::cerr << "faital error: deadline passed. " << std::endl;
- std::cerr << "Wait time: ";
- std::cerr << t.tv_sec << "[s], ";
- std::cerr << t.tv_nsec << "[ns]" << std::endl;
- std::cerr << "Next wait time force to: 0.0 [s]" << std::endl;
- continue;
- }
- clock_nanosleep(CLOCK_MONOTONIC, !TIMER_ABSTIME, &t, NULL);
}
- } while (m_svc);
-
+ ++count;
+ } while (threadRunning());
+ RTC_DEBUG(("Thread terminated."));
return 0;
}
-};
+ /*!
+ * @if jp
+ * @brief ExecutionContext 用のスレッド実行関数
+ * @else
+ * @brief Thread execution function for ExecutionContext
+ * @endif
+ */
+ int RTPreemptEC::close(unsigned long flags)
+ {
+ RTC_TRACE(("close()"));
+ // At this point, this component have to be finished.
+ // Current state and Next state should be RTC_EXITING.
+ return 0;
+ }
+ //============================================================
+ // ExecutionContext CORBA operations
+ //============================================================
+ /*!
+ * @if jp
+ * @brief ExecutionContext 実行状態確認関数
+ * @else
+ * @brief Check for ExecutionContext running state
+ * @endif
+ */
+ CORBA::Boolean RTPreemptEC::is_running()
+ throw (CORBA::SystemException)
+ {
+ return ExecutionContextBase::isRunning();
+ }
+
+ /*!
+ * @if jp
+ * @brief ExecutionContext の実行を開始
+ * @else
+ * @brief Start the ExecutionContext
+ * @endif
+ */
+ RTC::ReturnCode_t RTPreemptEC::start()
+ throw (CORBA::SystemException)
+ {
+ return ExecutionContextBase::start();
+ }
+
+ /*!
+ * @if jp
+ * @brief ExecutionContext の実行を停止
+ * @else
+ * @brief Stop the ExecutionContext
+ * @endif
+ */
+ RTC::ReturnCode_t RTPreemptEC::stop()
+ throw (CORBA::SystemException)
+ {
+ return ExecutionContextBase::stop();
+ }
+
+
+
+ /*!
+ * @if jp
+ * @brief ExecutionContext の実行周期(Hz)を取得する
+ * @else
+ * @brief Get execution rate(Hz) of ExecutionContext
+ * @endif
+ */
+ CORBA::Double RTPreemptEC::get_rate()
+ throw (CORBA::SystemException)
+ {
+ return ExecutionContextBase::getRate();
+ }
+
+ /*!
+ * @if jp
+ * @brief ExecutionContext の実行周期(Hz)を設定する
+ * @else
+ * @brief Set execution rate(Hz) of ExecutionContext
+ * @endif
+ */
+ RTC::ReturnCode_t RTPreemptEC::set_rate(CORBA::Double rate)
+ throw (CORBA::SystemException)
+ {
+ return ExecutionContextBase::setRate(rate);
+ }
+
+ /*!
+ * @if jp
+ * @brief RTコンポーネントを追加する
+ * @else
+ * @brief Add an RT-Component
+ * @endif
+ */
+ RTC::ReturnCode_t
+ RTPreemptEC::add_component(RTC::LightweightRTObject_ptr comp)
+ throw (CORBA::SystemException)
+ {
+ return ExecutionContextBase::addComponent(comp);
+ }
+
+ /*!
+ * @if jp
+ * @brief コンポーネントをコンポーネントリストから削除する
+ * @else
+ * @brief Remove the RT-Component from participant list
+ * @endif
+ */
+ RTC::ReturnCode_t RTPreemptEC::
+ remove_component(RTC::LightweightRTObject_ptr comp)
+ throw (CORBA::SystemException)
+ {
+ return ExecutionContextBase::removeComponent(comp);
+ }
+
+ /*!
+ * @if jp
+ * @brief RTコンポーネントをアクティブ化する
+ * @else
+ * @brief Activate an RT-Component
+ * @endif
+ */
+ RTC::ReturnCode_t RTPreemptEC::
+ activate_component(RTC::LightweightRTObject_ptr comp)
+ throw (CORBA::SystemException)
+ {
+ return ExecutionContextBase::activateComponent(comp);
+ }
+
+ /*!
+ * @if jp
+ * @brief RTコンポーネントを非アクティブ化する
+ * @else
+ * @brief Deactivate an RT-Component
+ * @endif
+ */
+ RTC::ReturnCode_t RTPreemptEC::
+ deactivate_component(RTC::LightweightRTObject_ptr comp)
+ throw (CORBA::SystemException)
+ {
+ return ExecutionContextBase::deactivateComponent(comp);
+ }
+
+ /*!
+ * @if jp
+ * @brief RTコンポーネントをリセットする
+ * @else
+ * @brief Reset the RT-Component
+ * @endif
+ */
+ RTC::ReturnCode_t RTPreemptEC::
+ reset_component(RTC::LightweightRTObject_ptr comp)
+ throw (CORBA::SystemException)
+ {
+ return ExecutionContextBase::resetComponent(comp);
+ }
+
+ /*!
+ * @if jp
+ * @brief RTコンポーネントの状態を取得する
+ * @else
+ * @brief Get RT-Component's state
+ * @endif
+ */
+ RTC::LifeCycleState RTPreemptEC::
+ get_component_state(RTC::LightweightRTObject_ptr comp)
+ throw (CORBA::SystemException)
+ {
+ RTC::LifeCycleState ret = ExecutionContextBase::getComponentState(comp);
+ return ret;
+ }
+
+ /*!
+ * @if jp
+ * @brief ExecutionKind を取得する
+ * @else
+ * @brief Get the ExecutionKind
+ * @endif
+ */
+ RTC::ExecutionKind RTPreemptEC::get_kind()
+ throw (CORBA::SystemException)
+ {
+ return ExecutionContextBase::getKind();
+ }
+
+ //------------------------------------------------------------
+ // ExecutionContextService interfaces
+ //------------------------------------------------------------
+ /*!
+ * @if jp
+ * @brief ExecutionContextProfile を取得する
+ * @else
+ * @brief Get the ExecutionContextProfile
+ * @endif
+ */
+ RTC::ExecutionContextProfile* RTPreemptEC::get_profile()
+ throw (CORBA::SystemException)
+ {
+ return ExecutionContextBase::getProfile();
+ }
+
+
+ //============================================================
+ // protected functions
+ //============================================================
+ /*!
+ * @brief onStarted() template function
+ */
+ RTC::ReturnCode_t RTPreemptEC::onStarted()
+ {
+ // change EC thread state
+ {
+ Guard guard(m_svcmutex);
+ if (!m_svc)
+ {
+ m_svc = true;
+ this->open(0);
+ }
+ }
+ if (isAllNextState(RTC::INACTIVE_STATE))
+ {
+ Guard guard(m_workerthread.mutex_);
+ m_workerthread.running_ = false;
+ }
+ else
+ {
+ Guard guard(m_workerthread.mutex_);
+ m_workerthread.running_ = true;
+ m_workerthread.cond_.signal();
+ }
+ return RTC::RTC_OK;
+ }
+
+ /*!
+ * @brief onStopping() template function
+ */
+ RTC::ReturnCode_t RTPreemptEC::onStopping()
+ {
+ // stop thread
+ Guard guard(m_workerthread.mutex_);
+ m_workerthread.running_ = false;
+ return RTC::RTC_OK;
+ }
+
+ /*!
+ * @brief onWaitingActivated() template function
+ */
+ RTC::ReturnCode_t RTPreemptEC::
+ onWaitingActivated(RTC_impl::RTObjectStateMachine* comp, long int count)
+ {
+ RTC_TRACE(("onWaitingActivated(count = %d)", count));
+ RTC_PARANOID(("curr: %s, next: %s",
+ getStateString(comp->getStates().curr),
+ getStateString(comp->getStates().next)));
+ // Now comp's next state must be ACTIVE state
+ // If worker thread is stopped, restart worker thread.
+ Guard guard(m_workerthread.mutex_);
+ if (m_workerthread.running_ == false)
+ {
+ m_workerthread.running_ = true;
+ m_workerthread.cond_.signal();
+ }
+ return RTC::RTC_OK;
+ }
+
+ /*!
+ * @brief onActivated() template function
+ */
+ RTC::ReturnCode_t RTPreemptEC::
+ onActivated(RTC_impl::RTObjectStateMachine* comp, long int count)
+ {
+ RTC_TRACE(("onActivated(count = %d)", count));
+ RTC_PARANOID(("curr: %s, next: %s",
+ getStateString(comp->getStates().curr),
+ getStateString(comp->getStates().next)));
+ // count = -1; Asynch mode. Since onWaitingActivated is not
+ // called, onActivated() have to send restart singnal to worker
+ // thread.
+ // count > 0: Synch mode.
+
+ // Now comp's next state must be ACTIVE state
+ // If worker thread is stopped, restart worker thread.
+ Guard guard(m_workerthread.mutex_);
+ if (m_workerthread.running_ == false)
+ {
+ m_workerthread.running_ = true;
+ m_workerthread.cond_.signal();
+ }
+ return RTC::RTC_OK;
+ }
+
+ /*!
+ * @brief onWaitingDeactivated() template function
+ */
+ RTC::ReturnCode_t RTPreemptEC::
+ onWaitingDeactivated(RTC_impl::RTObjectStateMachine* comp, long int count)
+ {
+ RTC_TRACE(("onWaitingDeactivated(count = %d)", count));
+ RTC_PARANOID(("curr: %s, next: %s",
+ getStateString(comp->getStates().curr),
+ getStateString(comp->getStates().next)));
+ if (isAllNextState(RTC::INACTIVE_STATE))
+ {
+ Guard guard(m_workerthread.mutex_);
+ if (m_workerthread.running_ == true)
+ {
+ m_workerthread.running_ = false;
+ RTC_TRACE(("All RTCs are INACTIVE. Stopping worker thread."));
+ }
+ }
+ return RTC::RTC_OK;
+ }
+
+ /*!
+ * @brief onDeactivated() template function
+ */
+ RTC::ReturnCode_t RTPreemptEC::
+ onDeactivated(RTC_impl::RTObjectStateMachine* comp, long int count)
+ {
+ RTC_TRACE(("onDeactivated(count = %d)", count));
+ RTC_PARANOID(("curr: %s, next: %s",
+ getStateString(comp->getStates().curr),
+ getStateString(comp->getStates().next)));
+ if (isAllNextState(RTC::INACTIVE_STATE))
+ {
+ Guard guard(m_workerthread.mutex_);
+ if (m_workerthread.running_ == true)
+ {
+ m_workerthread.running_ = false;
+ RTC_TRACE(("All RTCs are INACTIVE. Stopping worker thread."));
+ }
+ }
+ return RTC::RTC_OK;
+ }
+
+ /*!
+ * @brief onWaitingReset() template function
+ */
+ RTC::ReturnCode_t RTPreemptEC::
+ onWaitingReset(RTC_impl::RTObjectStateMachine* comp, long int count)
+ {
+ RTC_TRACE(("onWaitingReset(count = %d)", count));
+ RTC_PARANOID(("curr: %s, next: %s",
+ getStateString(comp->getStates().curr),
+ getStateString(comp->getStates().next)));
+ if (isAllNextState(RTC::INACTIVE_STATE))
+ {
+ Guard guard(m_workerthread.mutex_);
+ if (m_workerthread.running_ == true)
+ {
+ m_workerthread.running_ = false;
+ RTC_TRACE(("All RTCs are INACTIVE. Stopping worker thread."));
+ }
+ }
+ return RTC::RTC_OK;
+ }
+
+ /*!
+ * @brief onReset() template function
+ */
+ RTC::ReturnCode_t RTPreemptEC::
+ onReset(RTC_impl::RTObjectStateMachine* comp, long int count)
+ {
+ RTC_TRACE(("onReset(count = %d)", count));
+ RTC_PARANOID(("curr: %s, next: %s",
+ getStateString(comp->getStates().curr),
+ getStateString(comp->getStates().next)));
+ if (isAllNextState(RTC::INACTIVE_STATE))
+ {
+ Guard guard(m_workerthread.mutex_);
+ if (m_workerthread.running_ == true)
+ {
+ m_workerthread.running_ = false;
+ RTC_TRACE(("All RTCs are INACTIVE. Stopping worker thread."));
+ }
+ }
+ return RTC::RTC_OK;
+ }
+
+ //============================================================
+ // private functions
+ //============================================================
+ void RTPreemptEC::
+ setPriority(coil::Properties& prop)
+ {
+ RTC_TRACE(("setPriority()"));
+ getProperty(prop, "priority", m_priority);
+
+
+ RTC_DEBUG(("setPriority(): priority: %d", m_priority));
+ }
+ void RTPreemptEC::
+ setPolicy(coil::Properties& prop)
+ {
+ RTC_TRACE(("setPriority()"));
+ std::string policy;
+ getProperty(prop, "priority", policy);
+ if (!policy.empty())
+ {
+ coil::normalize(policy);
+ if (policy == "rr") { m_policy = SCHED_RR; }
+ if (policy == "fifo") { m_policy = SCHED_FIFO; }
+ RTC_DEBUG(("Scheduling policy: %s", policy.c_str()));
+ }
+ else
+ {
+ RTC_DEBUG(("Scheduling policy: fifo"));
+ m_policy = SCHED_FIFO;
+ }
+ RTC_DEBUG(("setPolicy(): policy: %s", policy.c_str()));
+ }
+ void RTPreemptEC::
+ setWaitOffset(coil::Properties& prop)
+ {
+ RTC_TRACE(("setWaitOffset()"));
+ getProperty(prop, "wait_offset", m_waitoffset);
+ RTC_DEBUG(("setWaitOffset(): offset: %d", m_waitoffset));
+ }
+
+ bool RTPreemptEC::getSleepTime(struct timespec& ts,
+ const struct timespec& t0,
+ const struct timespec& t1)
+ {
+ coil::TimeValue period(getPeriod());
+ if (t0.tv_nsec > t1.tv_nsec)
+ {
+ ts.tv_nsec = period.usec() * 1000
+ - (NSEC_PER_SEC - t0.tv_nsec + t1.tv_nsec) + m_waitoffset;
+ ts.tv_sec = period.sec() - (t1.tv_sec - 1 - t0.tv_sec);
+ }
+ else
+ {
+ ts.tv_nsec = period.usec() * 1000
+ - (t1.tv_nsec - t0.tv_nsec) + m_waitoffset;
+ ts.tv_sec = period.sec() - (t1.tv_sec - t0.tv_sec);
+ }
+ if (ts.tv_nsec < 0 || ts.tv_sec < 0)
+ {
+ std::cerr << "faital error: deadline passed. " << std::endl;
+ std::cerr << "Wait time: ";
+ std::cerr << ts.tv_sec << "[s], ";
+ std::cerr << ts.tv_nsec << "[ns]" << std::endl;
+ std::cerr << "Next wait time force to: 0.0 [s]"
+ << std::endl;
+ return false; // sleeptime < 0
+ }
+ return true; // sleeptime >= 0
+ }
+}; // namespace RTC
+
extern "C"
{
/*!
@@ -173,12 +661,18 @@
* @brief Initialization function to register to ECFactory
* @endif
*/
- void RTPreemptECInit(RTC::Manager* manager)
+
+ void RTPreemptECInit(RTC::Manager* manager)
{
- RTC::Manager::instance().
- registerECFactory("RTPreemptEC",
- RTC::ECCreate<OpenRTM::RTPreemptEC>,
- RTC::ECDelete<OpenRTM::RTPreemptEC>);
-
+ RTC::ExecutionContextFactory::
+ instance().addFactory("RTPreemptEC",
+ ::coil::Creator< ::RTC::ExecutionContextBase,
+ ::RTC_exp::RTPreemptEC>,
+ ::coil::Destructor< ::RTC::ExecutionContextBase,
+ ::RTC_exp::RTPreemptEC>);
+
+ coil::vstring ecs;
+ ecs = RTC::ExecutionContextFactory::instance().getIdentifiers();
}
};
+
Modified: trunk/OpenRTM-aist/src/ext/ec/rtpreempt/RTPreemptEC.h
===================================================================
--- trunk/OpenRTM-aist/src/ext/ec/rtpreempt/RTPreemptEC.h 2012-02-09 01:13:25 UTC (rev 2325)
+++ trunk/OpenRTM-aist/src/ext/ec/rtpreempt/RTPreemptEC.h 2012-02-09 01:17:19 UTC (rev 2326)
@@ -2,27 +2,39 @@
/*!
* @file RTPreemptEC.h
* @brief RTPreemptEC class
- * @date $Date$
+ * @date $Date: 2008-01-14 07:53:05 $
* @author Noriaki Ando <n-ando at aist.go.jp>
*
- * Copyright (C) 2010
+ * Copyright (C) 2006-2008,2012
+ * Noriaki Ando
* Intelligent Systems Research Institute,
* National Institute of
* Advanced Industrial Science and Technology (AIST), Japan
* All rights reserved.
*
- * $Id$
+ * $Id: RTPreemptEC.h 2307 2012-02-05 21:29:15Z n-ando $
*
*/
-#ifndef OPENRTM_RTPREEMPTEC_H
-#define OPENRTM_RTPREEMPTEC_H
+#ifndef RTC_RTPREEMPTEC2_H
+#define RTC_RTPREEMPTEC2_H
-#include <rtm/RTC.h>
-#include <rtm/Manager.h>
-#include <rtm/PeriodicExecutionContext.h>
+#include <vector>
+#include <iostream>
-namespace OpenRTM
+#include <coil/Task.h>
+#include <coil/Mutex.h>
+#include <coil/Condition.h>
+
+#include <rtm/ExecutionContextBase.h>
+
+#define NUM_OF_LIFECYCLESTATE 4
+
+#ifdef WIN32
+#pragma warning( disable : 4290 )
+#endif
+
+namespace RTC_exp
{
/*!
* @if jp
@@ -35,11 +47,11 @@
* リング機能を利用した実行コンテキストである。
*
* この実行コンテキストを利用するには、rtc.conf に下記のように記述する。
- *
+ *
* <pre>
- * exec_cxt.periodic.type: RTPreemptEC
- * exec_cxt.periodic.rate: 1000
- * exec_cxt.priority: 50
+ * execution_contexts: rtpreempt_ec
+ * ec.rtpreempt_ec.rate: 1000
+ * ec.rtpreempt_ec.priority: 50
* manager.modules.load_path: <RTPreemptRC.so がある場所へのパス>
* manager.modules.preload: RTPreemptEC.so
* </pre>
@@ -49,17 +61,16 @@
*
* このECに特有なオプションは以下のとおりである。
*
- * - exec_cxt.periodic.priority: (default: 49) <br>
- * - exec_cxt.periodic.rtpreempt.priority: (default: 49)<br>
+ * - ec.rtpreempt_ec.priority: (default: 49) <br>
* スレッドの実行優先度 1 (最低) から 99 (最高)<br>
* Linux sched_setscheduler(2) を参照のこと。<br>
*
- * - exec_cxt.periodic.rtpreempt.sched_policy: (default: fifo)<br>
+ * - ec.rtpreempt_ec.sched_policy: (default: fifo)<br>
* スケジューリングのポリシ。<br>
* rr: ラウンドロビン, fifo: FIFO 型 (default: fifo)<br>
* Linux sched_setscheduler(2) を参照のこと。<br>
*
- * - exec_cxt.periodic.rtpreempt.wait_offset: (default: -10000)<br>
+ * - ec.rtpeempt_ec.wait_offset: (default: -10000)<br>
* ウェイト時間のオフセット。[ns] 単位で指定する。 <br>
* 1周期あたり数十 us 程度の定常的な遅れが発生する場合があるので、
* この値を調整することで、より正確な周期で実行させることができる。
@@ -98,8 +109,8 @@
*
* - exec_cxt.periodic.priority: (default: 49)<br>
* - exec_cxt.periodic.rtpreempt.priority: (default: 49)<br>
- * Execution priority of threads from 1 (lowest) to 99 (highest)<br>
- * See Linux sched_setscheduler(2).
+ * Execution priority of threads from 1 (lowest) to 99 (highest)<br>
+ * See Linux sched_setscheduler(2).
*
* - exec_cxt.periodic.rtpreempt.sched_policy: (default: fifo)<br>
* Scheduling policy.<br>
@@ -124,19 +135,29 @@
* @endif
*/
class RTPreemptEC
- : public virtual ::RTC::PeriodicExecutionContext
+ : public virtual POA_RTC::ExecutionContextService,
+ public virtual PortableServer::RefCountServantBase,
+ public RTC::ExecutionContextBase,
+ public coil::Task
{
+ typedef coil::Guard<coil::Mutex> Guard;
public:
/*!
* @if jp
* @brief デフォルトコンストラクタ
*
* デフォルトコンストラクタ
+ * プロファイルに以下の項目を設定する。
+ * - kind : PERIODIC
+ * - rate : 0.0
*
* @else
* @brief Default Constructor
*
* Default Constructor
+ * Set the following items to profile.
+ * - kind : PERIODIC
+ * - rate : 0.0
*
* @endif
*/
@@ -155,31 +176,542 @@
*
* @endif
*/
- virtual ~RTPreemptEC();
+ virtual ~RTPreemptEC(void);
/*!
* @if jp
+ * @brief ExecutionContextの処理を進める
+ *
+ * ExecutionContextの処理を1周期分進める。
+ *
+ * @else
+ * @brief Proceed with tick of ExecutionContext
+ *
+ * Proceed with tick of ExecutionContext for one period.
+ *
+ * @endif
+ */
+ void init(coil::Properties& props);
+
+ /*!
+ * @if jp
+ * @brief ExecutionContext用アクティビティスレッドを生成する
+ *
+ * Executioncontext 用の内部アクティビティスレッドを生成し起動する。
+ * これは coil::Task サービスクラスメソッドのオーバーライド。
+ *
+ * @param args 通常は0
+ *
+ * @return 生成処理実行結果
+ *
+ * @else
+ *
+ * @brief Generate internal activity thread for ExecutionContext
+ *
+ * Generate internal activity thread and run. This is coil::Task
+ * class method's override.
+ *
+ * @param args Usually give 0
+ *
+ * @return The generation result
+ *
+ * @endif
+ */
+ virtual int open(void *args);
+
+ /*!
+ * @if jp
* @brief ExecutionContext 用のスレッド実行関数
*
- * ExecutionContext 用のスレッド実行関数。
- * 登録されたコンポーネントの処理を呼び出す。
+ * ExecutionContext 用のスレッド実行関数。登録されたコンポーネント
+ * の処理を呼び出す。
*
* @return 実行結果
*
* @else
* @brief Thread execution function for ExecutionContext
*
- * Thread execution function for ExecutionContext.
- * Invoke the registered components operation.
+ * Thread execution function for ExecutionContext. Invoke the
+ * registered components operation.
*
* @return The execution result
*
* @endif
- */
+ */
virtual int svc(void);
/*!
* @if jp
+ * @brief ExecutionContext 用のスレッド実行関数
+ *
+ * ExecutionContext 用のスレッド終了時に呼ばれる。コンポーネントオ
+ * ブジェクトの非アクティブ化、マネージャへの通知を行う。これは
+ * coil::Task サービスクラスメソッドのオーバーライド。
+ *
+ * @param flags 終了処理フラグ
+ *
+ * @return 終了処理結果
+ *
+ * @else
+ *
+ * @brief Thread execution function for ExecutionContext
+ *
+ * This function is invoked when activity thread for
+ * ExecutionContext exits. Deactivate the component object and
+ * notify it to manager. This is coil::Task class method's
+ * override.
+ *
+ * @param flags Flag of the close
+ *
+ * @return The close result
+ *
+ * @endif
+ */
+ virtual int close(unsigned long flags);
+
+ //============================================================
+ // ExecutionContext
+ //============================================================
+ /*!
+ * @if jp
+ * @brief ExecutionContext 実行状態確認関数
+ *
+ * この操作は ExecutionContext が Runnning 状態の場合に true を返す。
+ * Executioncontext が Running の間、当該 Executioncontext に参加し
+ * ている全てのアクティブRTコンポーネントが、ExecutionContext の実
+ * 行種類に応じて実行される。
+ *
+ * @return 状態確認関数(動作中:true、停止中:false)
+ *
+ * @else
+ *
+ * @brief Check for ExecutionContext running state
+ *
+ * This operation shall return true if the context is in the
+ * Running state. While the context is Running, all Active RTCs
+ * participating in the context shall be executed according to the
+ * context’s execution kind.
+ *
+ * @return Check state function (Running:true、Stopping:false)
+ *
+ * @endif
+ */
+ virtual CORBA::Boolean is_running(void)
+ throw (CORBA::SystemException);
+
+ /*!
+ * @if jp
+ * @brief ExecutionContext の実行を開始
+ *
+ * ExecutionContext の実行状態を Runnning とするためのリクエストを
+ * 発行する。ExecutionContext の状態が遷移すると
+ * ComponentAction::on_startup が呼び出される。参加しているRTコンポー
+ * ネントが、初期化されるまで ExecutionContext を開始することはでき
+ * ない。ExecutionContext は複数回開始/停止を繰り返すことができる。
+ *
+ * @return ReturnCode_t 型のリターンコード
+ *
+ * @else
+ *
+ * @brief Start the ExecutionContext
+ *
+ * Request that the context enter the Running state. Once the
+ * state transition occurs, the ComponentAction::on_startup
+ * operation will be invoked. An execution context may not be
+ * started until the RT-Components that participate in it have
+ * been initialized. An execution context may be started and
+ * stopped multiple times.
+ *
+ * @return The return code of ReturnCode_t type
+ *
+ * @endif
+ */
+ virtual RTC::ReturnCode_t start(void)
+ throw (CORBA::SystemException);
+
+ /*!
+ * @if jp
+ * @brief ExecutionContext の実行を停止
+ *
+ * ExecutionContext の状態を Stopped とするためのリクエストを発行す
+ * る。遷移が発生した場合は、ComponentAction::on_shutdown が呼び出
+ * される。参加しているRTコンポーネントが終了する前に
+ * ExecutionContext を停止する必要がある。ExecutionContext は複数回
+ * 開始/停止を繰り返すことができる。
+ *
+ * @return ReturnCode_t 型のリターンコード
+ *
+ * @else
+ *
+ * @brief Stop the ExecutionContext
+ *
+ * Request that the context enter the Stopped state. Once the
+ * transition occurs, the ComponentAction::on_shutdown operation
+ * will be invoked. An execution context must be stopped before
+ * the RT components that participate in it are finalized. An
+ * execution context may be started and stopped multiple times.
+ *
+ * @return The return code of ReturnCode_t type
+ *
+ * @endif
+ */
+ virtual RTC::ReturnCode_t stop(void)
+ throw (CORBA::SystemException);
+
+ /*!
+ * @if jp
+ * @brief ExecutionContext の実行周期(Hz)を取得する
+ *
+ * Active 状態にてRTコンポーネントが実行される周期(単位:Hz)を取得す
+ * る。
+ *
+ * @return 処理周期(単位:Hz)
+ *
+ * @else
+ *
+ * @brief Get execution rate(Hz) of ExecutionContext
+ *
+ * This operation shall return the rate (in hertz) at which its
+ * Active participating RTCs are being invoked.
+ *
+ * @return Execution cycle(Unit:Hz)
+ *
+ * @endif
+ */
+ virtual CORBA::Double get_rate(void)
+ throw (CORBA::SystemException);
+
+ /*!
+ * @if jp
+ * @brief ExecutionContext の実行周期(Hz)を設定する
+ *
+ * Active 状態にてRTコンポーネントが実行される周期(単位:Hz)を設定す
+ * る。実行周期の変更は、DataFlowComponentAction の
+ * on_rate_changed によって各RTコンポーネントに伝達される。
+ *
+ * @param rate 処理周期(単位:Hz)
+ *
+ * @return ReturnCode_t 型のリターンコード
+ *
+ * @else
+ *
+ * @brief Set execution rate(Hz) of ExecutionContext
+ *
+ * This operation shall set the rate (in hertz) at which this
+ * context’s Active participating RTCs are being called. If the
+ * execution kind of the context is PERIODIC, a rate change shall
+ * result in the invocation of on_rate_changed on any RTCs
+ * realizing DataFlowComponentAction that are registered with any
+ * RTCs participating in the context.
+ *
+ * @param rate Execution cycle(Unit:Hz)
+ *
+ * @return The return code of ReturnCode_t type
+ *
+ * @endif
+ */
+ virtual RTC::ReturnCode_t set_rate(CORBA::Double rate)
+ throw (CORBA::SystemException);
+
+ /*!
+ * @if jp
+ * @brief RTコンポーネントをアクティブ化する
+ *
+ * Inactive 状態にあるRTコンポーネントをActive に遷移させ、アクティ
+ * ブ化する。この操作が呼ばれた結果、on_activate が呼び出される。指
+ * 定したRTコンポーネントが参加者リストに含まれない場合は、
+ * BAD_PARAMETER が返される。指定したRTコンポーネントの状態が
+ * Inactive 以外の場合は、PRECONDITION_NOT_MET が返される。
+ *
+ * @param comp アクティブ化対象RTコンポーネント
+ *
+ * @return ReturnCode_t 型のリターンコード
+ *
+ * @else
+ *
+ * @brief Activate an RT-component
+ *
+ * The given participant RTC is Inactive and is therefore not
+ * being invoked according to the execution context’s execution
+ * kind. This operation shall cause the RTC to transition to the
+ * Active state such that it may subsequently be invoked in this
+ * execution context. The callback on_activate shall be called as
+ * a result of calling this operation. This operation shall not
+ * return until the callback has returned, and shall result in an
+ * error if the callback does.
+ *
+ * @param comp The target RT-Component for activation
+ *
+ * @return The return code of ReturnCode_t type
+ *
+ * @endif
+ */
+ virtual RTC::ReturnCode_t
+ activate_component(RTC::LightweightRTObject_ptr comp)
+ throw (CORBA::SystemException);
+
+ /*!
+ * @if jp
+ * @brief RTコンポーネントを非アクティブ化する
+ *
+ * Inactive 状態にあるRTコンポーネントを非アクティブ化し、Inactive
+ * に遷移させる。この操作が呼ばれた結果、on_deactivate が呼び出され
+ * る。指定したRTコンポーネントが参加者リストに含まれない場合は、
+ * BAD_PARAMETER が返される。指定したRTコンポーネントの状態が
+ * Active 以外の場合は、PRECONDITION_NOT_MET が返される。
+ *
+ * @param comp 非アクティブ化対象RTコンポーネント
+ *
+ * @return ReturnCode_t 型のリターンコード
+ *
+ * @else
+ *
+ * @brief Deactivate an RT-component
+ *
+ * The given RTC is Active in the execution context. Cause it to
+ * transition to the Inactive state such that it will not be
+ * subsequently invoked from the context unless and until it is
+ * activated again. The callback on_deactivate shall be called as
+ * a result of calling this operation. This operation shall not
+ * return until the callback has returned, and shall result in an
+ * error if the callback does.
+ *
+ * @param comp The target RT-Component for deactivate
+ *
+ * @return The return code of ReturnCode_t type
+ *
+ * @endif
+ */
+ virtual RTC::ReturnCode_t
+ deactivate_component(RTC::LightweightRTObject_ptr comp)
+ throw (CORBA::SystemException);
+
+ /*!
+ * @if jp
+ * @brief RTコンポーネントをリセットする
+ *
+ * Error 状態のRTコンポーネントの復帰を試みる。この操作が呼ばれた結
+ * 果、on_reset が呼び出される。指定したRTコンポーネントが参加者リ
+ * ストに含まれない場合は、BAD_PARAMETER が返される。指定したRTコン
+ * ポーネントの状態が Error 以外の場合は、PRECONDITION_NOT_MET が返
+ * される。
+ *
+ * @param comp リセット対象RTコンポーネント
+ *
+ * @return ReturnCode_t 型のリターンコード
+ *
+ * @else
+ *
+ * @brief Reset the RT-component
+ *
+ * Attempt to recover the RTC when it is in Error. The
+ * ComponentAction::on_reset callback shall be invoked. This
+ * operation shall not return until the callback has returned, and
+ * shall result in an error if the callback does. If possible, the
+ * RTC developer should implement that callback such that the RTC
+ * may be returned to a valid state.
+ *
+ * @param comp The target RT-Component for reset
+ *
+ * @return The return code of ReturnCode_t type
+ *
+ * @endif
+ */
+ virtual RTC::ReturnCode_t
+ reset_component(RTC::LightweightRTObject_ptr comp)
+ throw (CORBA::SystemException);
+
+ /*!
+ * @if jp
+ * @brief RTコンポーネントの状態を取得する
+ *
+ * 指定したRTコンポーネントの状態(LifeCycleState)を取得する。指定し
+ * たRTコンポーネントが参加者リストに含まれない場合は、
+ * UNKNOWN_STATE が返される。
+ *
+ * @param comp 状態取得対象RTコンポーネント
+ *
+ * @return 現在の状態(LifeCycleState)
+ *
+ * @else
+ *
+ * @brief Get RT-component's state
+ *
+ * This operation shall report the LifeCycleState of the given
+ * participant RTC. UNKNOWN_STATE will be returned, if the given
+ * RT-Component is not inclued in the participant list.
+ *
+ * @param comp The target RT-Component to get the state
+ *
+ * @return The current state of the target RT-Component(LifeCycleState)
+ *
+ * @endif
+ */
+ virtual RTC::LifeCycleState
+ get_component_state(RTC::LightweightRTObject_ptr comp)
+ throw (CORBA::SystemException);
+
+ /*!
+ * @if jp
+ * @brief ExecutionKind を取得する
+ *
+ * 本 ExecutionContext の ExecutionKind を取得する
+ *
+ * @return ExecutionKind
+ *
+ * @else
+ *
+ * @brief Get the ExecutionKind
+ *
+ * This operation shall report the execution kind of the execution
+ * context.
+ *
+ * @return ExecutionKind
+ *
+ * @endif
+ */
+ virtual RTC::ExecutionKind get_kind(void)
+ throw (CORBA::SystemException);
+
+ /*!
+ * @if jp
+ * @brief RTコンポーネントを追加する
+ *
+ * 指定したRTコンポーネントを参加者リストに追加する。追加されたRTコ
+ * ンポーネントは attach_context が呼ばれ、Inactive 状態に遷移する。
+ * 指定されたRTコンポーネントがnullの場合は、BAD_PARAMETER が返され
+ * る。指定されたRTコンポーネントが DataFlowComponent 以外の場合は、
+ * BAD_PARAMETER が返される。
+ *
+ * @param comp 追加対象RTコンポーネント
+ *
+ * @return ReturnCode_t 型のリターンコード
+ *
+ * @else
+ *
+ * @brief Add an RT-component
+ *
+ * The operation causes the given RTC to begin participating in
+ * the execution context. The newly added RTC will receive a call
+ * to LightweightRTComponent::attach_context and then enter the
+ * Inactive state. BAD_PARAMETER will be invoked, if the given
+ * RT-Component is null or if the given RT-Component is other than
+ * DataFlowComponent.
+ *
+ * @param comp The target RT-Component for add
+ *
+ * @return The return code of ReturnCode_t type
+ *
+ * @endif
+ */
+ virtual RTC::ReturnCode_t
+ add_component(RTC::LightweightRTObject_ptr comp)
+ throw (CORBA::SystemException);
+
+ /*!
+ * @if jp
+ * @brief RTコンポーネントを参加者リストから削除する
+ *
+ * 指定したRTコンポーネントを参加者リストから削除する。削除された
+ * RTコンポーネントは detach_context が呼ばれる。指定されたRTコンポー
+ * ネントが参加者リストに登録されていない場合は、BAD_PARAMETER が返
+ * される。
+ *
+ * @param comp 削除対象RTコンポーネント
+ *
+ * @return ReturnCode_t 型のリターンコード
+ *
+ * @else
+ *
+ * @brief Remove the RT-Component from participant list
+ *
+ * This operation causes a participant RTC to stop participating
+ * in the execution context. The removed RTC will receive a call
+ * to LightweightRTComponent::detach_context. BAD_PARAMETER will
+ * be returned, if the given RT-Component is not participating in
+ * the participant list.
+ *
+ * @param comp The target RT-Component for delete
+ *
+ * @return The return code of ReturnCode_t type
+ *
+ * @endif
+ */
+ virtual RTC::ReturnCode_t
+ remove_component(RTC::LightweightRTObject_ptr comp)
+ throw (CORBA::SystemException);
+
+ /*!
+ * @if jp
+ * @brief ExecutionContextProfile を取得する
+ *
+ * 本 ExecutionContext のプロファイルを取得する。
+ *
+ * @return ExecutionContextProfile
+ *
+ * @else
+ *
+ * @brief Get the ExecutionContextProfile
+ *
+ * This operation provides a profile “descriptor” for the execution
+ * context.
+ *
+ * @return ExecutionContextProfile
+ *
+ * @endif
+ */
+ virtual RTC::ExecutionContextProfile* get_profile(void)
+ throw (CORBA::SystemException);
+
+ protected:
+ /*!
+ * @brief onStarted() template function
+ */
+ virtual RTC::ReturnCode_t onStarted();
+ /*!
+ * @brief onStopping() template function
+ */
+ virtual RTC::ReturnCode_t onStopping();
+ /*!
+ * @brief onWaitingActivated() template function
+ */
+ virtual RTC::ReturnCode_t
+ onWaitingActivated(RTC_impl::RTObjectStateMachine* comp, long int count);
+ /*!
+ * @brief onActivated() template function
+ */
+ virtual RTC::ReturnCode_t
+ onActivated(RTC_impl::RTObjectStateMachine* comp, long int count);
+ /*!
+ * @brief onWaitingDeactivated() template function
+ */
+ virtual RTC::ReturnCode_t
+ onWaitingDeactivated(RTC_impl::RTObjectStateMachine* comp,
+ long int count);
+ /*!
+ * @brief onDeactivated() template function
+ */
+ virtual RTC::ReturnCode_t
+ onDeactivated(RTC_impl::RTObjectStateMachine* comp, long int count);
+ /*!
+ * @brief onWaitingReset() template function
+ */
+ virtual RTC::ReturnCode_t
+ onWaitingReset(RTC_impl::RTObjectStateMachine* comp, long int count);
+ /*!
+ * @brief onReset() template function
+ */
+ virtual RTC::ReturnCode_t
+ onReset(RTC_impl::RTObjectStateMachine* comp, long int count);
+
+ bool threadRunning()
+ {
+ Guard guard(m_svcmutex);
+ return m_svc;
+ }
+
+ /*!
+ * @if jp
* @brief あるキーを持つプロパティを取得する
*
* @param ExecutionContext 用のスレッド実行関数。
@@ -196,7 +728,7 @@
* @return The execution result
*
* @endif
- */
+ */
template <class T>
void getProperty(coil::Properties& prop, const char* key, T& value)
{
@@ -211,12 +743,80 @@
}
private:
+ bool prepareThread();
+ void setPriority(coil::Properties& prop);
+ void setPolicy(coil::Properties& prop);
+ void setWaitOffset(coil::Properties& prop);
+ bool getSleepTime(struct timespec& ts,
+ const struct timespec& t0,
+ const struct timespec& t1);
+
+ protected:
+ /*!
+ * @if jp
+ * @brief ロガーストリーム
+ * @else
+ * @brief Logger stream
+ * @endif
+ */
+ RTC::Logger rtclog;
+
+ /*!
+ * @if jp
+ * @brief ExecutionContext のスレッド実行フラグ
+ * @else
+ * @brief The thread running flag of ExecutionContext
+ * @endif
+ */
+ bool m_svc;
+ coil::Mutex m_svcmutex;
+
+ /*!
+ * @if jp
+ * @brief worker 用状態変数クラス
+ * @else
+ * @brief Condition variable class for worker
+ * @endif
+ */
+ struct WorkerThreadCtrl
+ {
+ WorkerThreadCtrl() : cond_(mutex_), running_(false) {};
+ coil::Mutex mutex_;
+ coil::Condition<coil::Mutex> cond_;
+ bool running_;
+ };
+
+ /*!
+ * @if jp
+ * @brief svn用の状態変数
+ * @else
+ * @brief A condition variable for external triggered worker
+ * @endif
+ */
+ WorkerThreadCtrl m_workerthread;
+
+ /*!
+ * @if jp
+ * @brief ExecutionContext 即時実行(wait無し実行)フラグ
+ * @else
+ * @brief Flag of ExecutionContext to run immediately
+ * (to run without waiting)
+ * @endif
+ */
+ bool m_nowait;
+
+ private:
int m_priority;
int m_policy;
int m_waitoffset;
- };
-};
+ }; // class RTPreemptEC
+}; // namespace RTC
+#ifdef WIN32
+#pragma warning( default : 4290 )
+#endif
+
+
extern "C"
{
/*!
@@ -226,8 +826,7 @@
* @brief Initialization function to register to ECFactory
* @endif
*/
- void DLL_EXPORT RTPreemptECInit(RTC::Manager* manager);
+ void RTPreemptECInit(RTC::Manager* manager);
};
-#endif // OPENRTM_RTPREEMPTEC_H
-
+#endif // RTC_RTPREEMPTEC_H
openrtm-commit メーリングリストの案内