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