Go to the documentation of this file.00001
00002
00003 #include "hrpEC.h"
00004 #include <rtm/ECFactory.h>
00005 #include "hrpsys/io/iob.h"
00006
00007 #include <iostream>
00008
00009 #include <stdio.h>
00010 #include <errno.h>
00011 #include <sched.h>
00012 #include <signal.h>
00013 #include <sys/time.h>
00014 #include <sys/mman.h>
00015 #include <unistd.h>
00016
00017 #define MAX_SAFE_STACK (8*1024)
00018
00019
00020 void stack_prefault(void) {
00021
00022 unsigned char dummy[MAX_SAFE_STACK];
00023
00024 memset(&dummy, 0, MAX_SAFE_STACK);
00025 return;
00026 }
00027
00028 namespace RTC
00029 {
00030 hrpExecutionContext::hrpExecutionContext()
00031 #ifndef OPENRTM_VERSION_TRUNK
00032 : PeriodicExecutionContext(),
00033 #else
00034 : RTC_exp::PeriodicExecutionContext(),
00035 #endif
00036 m_priority(49),
00037 m_cpu(-1),
00038 m_thread_pending (false)
00039 {
00040 resetProfile();
00041 rtclog.setName("hrpEC");
00042 coil::Properties& prop(Manager::instance().getConfig());
00043
00044
00045 getProperty(prop, "exec_cxt.periodic.priority", m_priority);
00046 getProperty(prop, "exec_cxt.periodic.rtpreempt.priority", m_priority);
00047 getProperty(prop, "exec_cxt.periodic.cpu_affinity", m_cpu);
00048 RTC_DEBUG(("Priority: %d", m_priority));
00049 }
00050
00051 bool hrpExecutionContext::waitForNextPeriod()
00052 {
00053 int nsubstep = number_of_substeps();
00054 while(1){
00055 if (wait_for_iob_signal()){
00056 perror("wait_for_iob_signal()");
00057 return false;
00058 }
00059 if (read_iob_frame() % nsubstep == 0) break;
00060 }
00061 return true;
00062 }
00063
00064 bool hrpExecutionContext::enterRT()
00065 {
00066 struct sched_param param;
00067 param.sched_priority = m_priority;
00068
00069 #ifndef __APPLE__
00070 if (sched_setscheduler(0, SCHED_FIFO, ¶m) == -1) {
00071 perror("sched_setscheduler");
00072 std::cerr << "If you are running this program on normal linux kernel for debug purpose, you can ignore the error message displayed above. If not, this program must have superuser privilege." << std::endl;
00073
00074 }else{
00075
00076 if(mlockall(MCL_CURRENT|MCL_FUTURE) == -1) {
00077 perror("mlockall failed");
00078 }
00079 }
00080
00081 if (m_cpu>=0){
00082 cpu_set_t cpu_set;
00083 CPU_ZERO(&cpu_set);
00084 CPU_SET(m_cpu, &cpu_set);
00085 int result = sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set);
00086 if (result != 0) {
00087 perror("sched_setaffinity():");
00088 }
00089 }
00090 #endif
00091
00092 stack_prefault();
00093
00094 return true;
00095 }
00096 bool hrpExecutionContext::exitRT()
00097 {
00098 return true;
00099 }
00100 };
00101
00102
00103 extern "C"
00104 {
00105 void hrpECInit(RTC::Manager* manager)
00106 {
00107 #ifndef OPENRTM_VERSION_TRUNK
00108 manager->registerECFactory("hrpExecutionContext",
00109 RTC::ECCreate<RTC::hrpExecutionContext>,
00110 RTC::ECDelete<RTC::hrpExecutionContext>);
00111 #else
00112 RTC::ExecutionContextFactory::
00113 instance().addFactory("hrpExecutionContext",
00114 ::coil::Creator< ::RTC::ExecutionContextBase,
00115 RTC::hrpExecutionContext>,
00116 ::coil::Destructor< ::RTC::ExecutionContextBase,
00117 RTC::hrpExecutionContext>);
00118 #endif
00119 std::cerr << "hrpExecutionContext is registered" << std::endl;
00120 }
00121 };
00122