00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "config.h"
00019
00020 #include <math.h>
00021
00022 #include <assert_pp.h>
00023
00024 #include <rk_stub.h>
00025
00026 #include "BasicDelegate.hh"
00027
00028 BasicDelegate::BasicDelegate(const char *name,
00029 unsigned long period,
00030 unsigned long deadline) :
00031 bd_Period(period), bd_Deadline(deadline)
00032 {
00033 require(name != NULL);
00034 require(deadline <= period);
00035
00036 this->bd_AdviseDrop = 0;
00037
00038 this->bd_PID = rk_stub_mk_pid(name,
00039 this,
00040 cxx_delegate_precall,
00041 cxx_delegate_postcall);
00042
00043
00044 this->bd_CPUSchedule.length(3);
00045 this->bd_CPUSchedule[0].name = "period";
00046 this->bd_CPUSchedule[0].value <<= (CORBA::ULong)period;
00047 this->bd_CPUSchedule[1].name = "deadline";
00048 this->bd_CPUSchedule[1].value <<= (CORBA::ULong)deadline;
00049 this->bd_CPUSchedule[2].name = "pid";
00050 this->bd_CPUSchedule[2].value <<= this->bd_PID;
00051 this->bd_TaskDescription.length(1);
00052 this->bd_TaskDescription[0].name = "name";
00053 this->bd_TaskDescription[0].value <<= name;
00054 }
00055
00056 BasicDelegate::~BasicDelegate()
00057 {
00058 }
00059
00060 rk_stub_precall_retval_t BasicDelegate::precall(void)
00061 {
00062 rk_stub_precall_retval_t retval;
00063
00064 require(this->bd_AdviseDrop >= 0);
00065
00066
00067 if( this->bd_AdviseDrop > 0 )
00068 {
00069 this->bd_AdviseDrop -= 1;
00070 retval = RKSP_DROP;
00071 }
00072 else
00073 {
00074 rk_stub_getrusage(this->bd_PID, &this->bd_RUStart);
00075 rk_clock_gettime(CLOCK_REALTIME, &this->bd_Start);
00076 retval = RKSP_OK;
00077 }
00078
00079 return( retval );
00080 }
00081
00082 void BasicDelegate::postcall(void)
00083 {
00084 long long start_us, end_us, diff_us;
00085 struct rusage ru_end;
00086 struct timespec end;
00087 float periods;
00088
00089 require(!CORBA::is_nil(this->bd_Advocate.in()));
00090
00091 rk_stub_getrusage(this->bd_PID, &ru_end);
00092 rk_clock_gettime(CLOCK_REALTIME, &end);
00093
00094
00095 start_us = timespec_to_microsec(&this->bd_Start);
00096 end_us = timespec_to_microsec(&end);
00097 diff_us = end_us - start_us;
00098
00099 cout << "start: " << start_us
00100 << "; end: " << end_us
00101 << "; diff: " << diff_us
00102 << endl;
00103
00104
00105
00106
00107
00108
00109
00110
00111 periods = (float)(diff_us % this->bd_Deadline) / (float)this->bd_Deadline;
00112 cout << "periods: " << periods << endl;
00113 if( periods == 0.0 )
00114 {
00115
00116
00117
00118
00119 periods += 1.0;
00120 }
00121
00122 periods +=
00123 (float)(diff_us - (periods * this->bd_Deadline)) /
00124 (float)this->bd_Period;
00125 cout << "nperiods: " << periods << endl;
00126 if( periods > 1.0 )
00127 {
00128
00129 this->bd_AdviseDrop = ((int)floorf(periods + 0.99)) - 1;
00130 }
00131
00132 start_us = this->bd_RUStart.ru_utime.tv_usec;
00133 start_us += this->bd_RUStart.ru_utime.tv_sec * 1000000;
00134 end_us = ru_end.ru_utime.tv_usec;
00135 end_us += ru_end.ru_utime.tv_sec * 1000000;
00136 diff_us = end_us - start_us;
00137 try
00138 {
00139
00140 this->bd_Advocate->ReportCPU(this->bd_Advocate.in(), diff_us, diff_us);
00141 }
00142 catch(Broker::InvalidStatus &is)
00143 {
00144 cout << "Exception: " << is << endl;
00145 exit(1);
00146 }
00147 catch(CORBA::SystemException &se)
00148 {
00149 cout << "CORBA Exception: " << se << endl;
00150 exit(1);
00151 }
00152 catch(...)
00153 {
00154 cout << "Unhandled exception" << endl;
00155 }
00156 }