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

RealTimeSchedule.cc

Go to the documentation of this file.
00001 /*
00002  * RealTimeSchedule.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 RealTimeSchedule.cc
00014  *
00015  * Implementation of the RealTimeSchedule class.
00016  */
00017 
00018 #include "config.h"
00019 
00020 #include <assert_pp.h>
00021 
00022 #include <iostream>
00023 
00024 #include "RealTimeSchedule.hh"
00025 
00026 #if !defined(min)
00027 #define min(x, y) ((x) < (y) ? (x) : (y))
00028 #define max(x, y) ((x) > (y) ? (x) : (y))
00029 #endif
00030 
00031 RealTimeSchedule::RealTimeSchedule(CORBA::ULong start,
00032                                    CORBA::ULong period,
00033                                    CORBA::ULong deadline) :
00034     rts_Start(start), rts_Period(period), rts_Deadline(deadline)
00035 {
00036     require(deadline <= period);
00037 }
00038 
00039 RealTimeSchedule::~RealTimeSchedule()
00040 {
00041 }
00042 
00043 CORBA::ULong RealTimeSchedule::intersect(CORBA::ULong start, CORBA::ULong stop)
00044 {
00045     int starting_period_index, ending_period_index;
00046     CORBA::ULong retval = 0;
00047 
00048     require(start <= stop);
00049 
00050     /*
00051      * The strategy here is to compute the set of periods in this schedule that
00052      * overlap with the given time frame.  Then we simply add the all the ones
00053      * in the middle and the starting and ending periods which may be partially
00054      * covered by the time frame.
00055      */
00056 
00057     /* Compute the index of the first period. */
00058     starting_period_index = ((int)start - (int)this->rts_Start) /
00059         (int)this->rts_Period;
00060     /* The last intersected period is */
00061     if( stop < this->rts_Start )
00062     {
00063         /* ... before this schedule starts, do nothing. */
00064         ending_period_index = -1;
00065     }
00066     else
00067     {
00068         /*
00069          * in the middle.  (Since there is no stop time in the schedule, there
00070          * is always a middle)
00071          */
00072         ending_period_index = (stop - this->rts_Start - 1) / this->rts_Period;
00073     }
00074     /* The start of the intersection is */
00075     if( starting_period_index < 0 )
00076     {
00077         /*
00078          * ... before this schedules start time.  Therefore, the starting
00079          * period is completely covered.  We set the value to -1 here so that
00080          * the computation of periods in the middle will work properly.
00081          */
00082         starting_period_index = -1;
00083     }
00084     else
00085     {
00086         unsigned long long start_us, end_us;
00087 
00088         /*
00089          * ... possibly in the middle of a period.  Therefore, we need to
00090          * compute the absolute start of the intersecting period and
00091          */
00092         start_us = this->rts_Start +
00093             (this->rts_Period * starting_period_index);
00094         /* ... the absolute end of the intersecting period. */
00095         end_us = this->rts_Start +
00096             (this->rts_Period * starting_period_index) +
00097             this->rts_Deadline;
00098         /* Then add the part of the period that actually intersects. */
00099         retval += (CORBA::ULong)(min(stop, end_us) - max(start, start_us));
00100     }
00101     /* If the intersection covers several periods then */
00102     if( (starting_period_index + 1) <= (ending_period_index - 1) )
00103     {
00104         /* ... add those to the return value. */
00105         retval += (ending_period_index - starting_period_index - 1) *
00106             this->rts_Deadline;
00107     }
00108     /* Add to the return value if the intersection ends */
00109     if( ending_period_index < 0 )
00110     {
00111         /* ... before this schedule starts. */
00112     }
00113     else if( starting_period_index != ending_period_index )
00114     {
00115         unsigned long long start_us;
00116 
00117         /* ... at a period not covered by the previous cases (start/middle). */
00118         start_us = this->rts_Start + (this->rts_Period * ending_period_index);
00119         retval += (CORBA::ULong)(min(stop, start_us + this->rts_Deadline) -
00120                                  start_us);
00121     }
00122     return( retval );
00123 }

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