00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "config.h"
00019
00020 #include <assert_pp.h>
00021
00022 #include <iostream>
00023
00024 #include <time_util.h>
00025
00026 #include "RealTimeSchedule.hh"
00027
00028 #if !defined(min)
00029
00030
00031
00032
00033
00034 #define min(x, y) ((x) < (y) ? (x) : (y))
00035
00036
00037
00038
00039
00040
00041 #define max(x, y) ((x) > (y) ? (x) : (y))
00042 #endif
00043
00044 RealTimeSchedule::RealTimeSchedule(CORBA::ULong start,
00045 CORBA::ULong period,
00046 CORBA::ULong deadline,
00047 rts_reserve_mode_t reserve_mode,
00048 pid_t pid) :
00049 rts_Start(start),
00050 rts_Period(period),
00051 rts_Deadline(deadline),
00052 rts_ReserveMode(reserve_mode),
00053 rts_PID(pid)
00054 {
00055 require(deadline <= period);
00056 }
00057
00058 void RealTimeSchedule::setParameters(const Broker::ScheduleParameters &sp)
00059 throw (Broker::DuplicateScheduleParameter,
00060 Broker::InvalidScheduleParameter,
00061 Broker::MissingScheduleParameter)
00062 {
00063 unsigned long long start = 0, period = ~0, deadline = ~0;
00064 unsigned int lpc;
00065 const char *str;
00066 pid_t pid = -1;
00067
00068 for( lpc = 0; lpc < sp.length(); lpc++ )
00069 {
00070 if( strcasecmp(sp[lpc].name.in(), "reserve-mode") == 0 )
00071 {
00072 const char *str;
00073
00074 if( sp[lpc].value >>= str )
00075 {
00076 if( strcasecmp(str, "soft") == 0 )
00077 {
00078 this->rts_ReserveMode = RTS_RSV_SOFT;
00079 }
00080 else if( strcasecmp(str, "hard") == 0 )
00081 {
00082 this->rts_ReserveMode = RTS_RSV_HARD;
00083 }
00084 else
00085 {
00086 throw Broker::InvalidScheduleParameter(
00087 "'reserve-mode' not 'hard' or 'soft'", sp[lpc]);
00088 }
00089 }
00090 else
00091 {
00092 throw Broker::InvalidScheduleParameter(
00093 "'reserve-mode' not a string", sp[lpc]);
00094 }
00095 }
00096 else if( strcasecmp(sp[lpc].name.in(), "start") == 0 )
00097 {
00098 if( ((sp[lpc].value >>= str) && string_to_microsec(&start, str)) )
00099 {
00100 }
00101 else
00102 {
00103 throw Broker::InvalidScheduleParameter("'start' is not a time",
00104 sp[lpc]);
00105 }
00106 }
00107 else if( strcasecmp(sp[lpc].name.in(), "pid") == 0 )
00108 {
00109 CORBA::Long c_pid;
00110 const char *str;
00111
00112 if( pid != -1 )
00113 {
00114 throw Broker::DuplicateScheduleParameter("pid");
00115 }
00116 else if( sp[lpc].value >>= c_pid )
00117 {
00118 pid = c_pid;
00119 }
00120 else if( (sp[lpc].value >>= str) &&
00121 (sscanf(str, "%d", &pid) == 1) )
00122 {
00123 }
00124 else
00125 {
00126 throw Broker::InvalidScheduleParameter("'pid' not a long",
00127 sp[lpc]);
00128 }
00129 if( pid < 0 )
00130 {
00131 pid = -1;
00132 throw Broker::InvalidScheduleParameter("'pid' not a long",
00133 sp[lpc]);
00134 }
00135 }
00136 else if( strcasecmp(sp[lpc].name.in(), "period") == 0 )
00137 {
00138 CORBA::ULong period_ul;
00139
00140 if( period != ~0ULL )
00141 {
00142 throw Broker::DuplicateScheduleParameter("period");
00143 }
00144 else if( sp[lpc].value >>= period_ul )
00145 {
00146 period = period_ul;
00147 }
00148 else if( (sp[lpc].value >>= str) &&
00149 string_to_microsec(&period, str) )
00150 {
00151 }
00152 else
00153 {
00154 throw Broker::InvalidScheduleParameter(
00155 "'period' is not a time",
00156 sp[lpc]);
00157 }
00158 }
00159 else if( strcasecmp(sp[lpc].name.in(), "deadline") == 0 )
00160 {
00161 CORBA::ULong deadline_ul;
00162
00163 if( deadline != ~0ULL )
00164 {
00165 throw Broker::DuplicateScheduleParameter("deadline");
00166 }
00167 else if( sp[lpc].value >>= deadline_ul )
00168 {
00169 deadline = deadline_ul;
00170 }
00171 else if( (sp[lpc].value >>= str) &&
00172 string_to_microsec(&deadline, str) )
00173 {
00174 }
00175 else
00176 {
00177 throw Broker::InvalidScheduleParameter(
00178 "'deadline' is not a time",
00179 sp[lpc]);
00180 }
00181 }
00182 }
00183
00184
00185 if( period == ~0ULL )
00186 {
00187 throw Broker::MissingScheduleParameter("period");
00188 }
00189 if( pid == -1 )
00190 {
00191 throw Broker::MissingScheduleParameter("pid");
00192 }
00193
00194
00195 if( deadline == ~0ULL )
00196 {
00197 deadline = period;
00198 }
00199
00200 this->rts_Start = start;
00201 this->rts_Deadline = deadline;
00202 this->rts_Period = period;
00203 this->rts_PID = pid;
00204 }
00205
00206 RealTimeSchedule::~RealTimeSchedule()
00207 {
00208 }
00209
00210 CORBA::ULong RealTimeSchedule::intersect(CORBA::ULong start, CORBA::ULong stop)
00211 {
00212 int starting_period_index, ending_period_index;
00213 CORBA::ULong retval = 0;
00214
00215 require(start <= stop);
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 starting_period_index = ((int)start - (int)this->rts_Start) /
00226 (int)this->rts_Period;
00227
00228 if( stop < this->rts_Start )
00229 {
00230
00231 ending_period_index = -1;
00232 }
00233 else
00234 {
00235
00236
00237
00238
00239 ending_period_index = (stop - this->rts_Start - 1) / this->rts_Period;
00240 }
00241
00242 if( starting_period_index < 0 )
00243 {
00244
00245
00246
00247
00248
00249 starting_period_index = -1;
00250 }
00251 else
00252 {
00253 unsigned long long start_us, end_us;
00254
00255
00256
00257
00258
00259 start_us = this->rts_Start +
00260 (this->rts_Period * starting_period_index);
00261
00262 end_us = this->rts_Start +
00263 (this->rts_Period * starting_period_index) +
00264 this->rts_Deadline;
00265
00266 retval += (CORBA::ULong)(min(stop, end_us) - max(start, start_us));
00267 }
00268
00269 if( (starting_period_index + 1) <= (ending_period_index - 1) )
00270 {
00271
00272 retval += (ending_period_index - starting_period_index - 1) *
00273 this->rts_Deadline;
00274 }
00275
00276 if( ending_period_index < 0 )
00277 {
00278
00279 }
00280 else if( starting_period_index != ending_period_index )
00281 {
00282 unsigned long long start_us;
00283
00284
00285 start_us = this->rts_Start + (this->rts_Period * ending_period_index);
00286 retval += (CORBA::ULong)(min(stop, start_us + this->rts_Deadline) -
00287 start_us);
00288 }
00289 return( retval );
00290 }