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 }