Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

BasicDelegate.cc

Go to the documentation of this file.
00001 /*
00002  * BasicDelegate.cc
00003  *
00004  * Copyright (c) 2003 The University of Utah and the Flux Group.
00005  * All rights reserved.
00006  *
00007  * This file is licensed under the terms of the GNU Public License.  
00008  * See the file "license.terms" for restrictions on redistribution 
00009  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
00010  */
00011 
00012 /**
00013  * @file BasicDelegate.cc
00014  *
00015  * Implementation of the BasicDelegate class.
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     /* Create the fake process. */
00038     this->bd_PID = rk_stub_mk_pid(name,
00039                                   this,
00040                                   cxx_delegate_precall,
00041                                   cxx_delegate_postcall);
00042     
00043     /* Build up the parameter lists. */
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     /* Check if we need to do a drop. */
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     /* Figure out how long it took, in microseconds, to process the data. */
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      * Now convert the microseconds value to a float value that
00106      * Broker::RealTimeAdvocate::ReportCPU will understand.
00107      *
00108      * First, compute how much time it took between the start of the period
00109      * and the deadline.
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          * Add one if the method finished exactly on time.  (Probably only
00117          * happens in the simulator...)
00118          */
00119         periods += 1.0;
00120     }
00121     /* ... and then add in any full periods that were used. */
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         /* We overran the deadline, drop the data periods that were overrun. */
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         /* Send our report to the advocate. */
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 }

Generated on Mon Dec 1 16:29:05 2003 for CPU Broker by doxygen 1.3.4