00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation; either version 2 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * This program is distributed in the hope that it will be useful, 00008 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00009 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00010 * GNU General Public License for more details. 00011 * 00012 * You should have received a copy of the GNU General Public License 00013 * along with this program; if not, write to the Free Software 00014 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00015 * 00016 * (c)Copyright 2006 Hewlett-Packard Development Company, LP. 00017 * 00018 */ 00019 00020 #include "C_TrafficModel.hpp" 00021 #include "GeneratorTrace.hpp" 00022 #include "Utils.hpp" 00023 00024 #include <cmath> 00025 00026 //#include <math.h> // for floor 00027 00028 00029 #define GET_TIME(clock) \ 00030 {\ 00031 struct timezone tzp;\ 00032 gettimeofday (clock, &tzp);\ 00033 } 00034 00035 00054 void C_TrafficModel::update () 00055 { 00056 GET_TIME(&m_currentTimeval); 00057 // Period duration : ti - tp in mili-seconds 00058 m_sem_created_call->P(); 00059 m_currentPeriodDuration = (m_currentTimeval.tv_sec - 00060 m_startPeriodDate.tv_sec)*1000 + 00061 (m_currentTimeval.tv_usec - 00062 m_startPeriodDate.tv_usec)/1000; 00063 00064 00065 //std::cerr << "update m_currentPeriodDuration " << m_currentPeriodDuration << std::endl; 00066 00067 // Traffic duration : ti - T0 in mili-seconds 00068 m_currentTrafficDuration = (m_currentTimeval.tv_sec - 00069 m_startTrafficDate.tv_sec ) * 1000 + 00070 (m_currentTimeval.tv_usec - 00071 m_startTrafficDate.tv_usec ) / 1000; 00072 00073 m_sem_created_call->V(); 00074 00075 } /* end of update */ 00076 00077 00078 00079 void C_TrafficModel::reset () 00080 { 00081 00082 m_sem_created_call->P(); 00083 if (m_currentPeriodDuration > m_periodDuration) { 00084 m_startPeriodDate.tv_sec = m_currentTimeval.tv_sec; 00085 m_startPeriodDate.tv_usec = m_currentTimeval.tv_usec; 00086 00087 m_nbCallCreatedInPeriod = 0; 00088 m_currentPeriodDuration = 0; 00089 } 00090 m_sem_created_call->V(); 00091 00092 00093 } /* end of reset */ 00094 00095 00096 00097 int C_TrafficModel::init (long P_averageRate, 00098 long P_maxCreationPerPeriod, 00099 long P_setupTime, 00100 long P_rateScale) 00101 { 00102 m_desiredAverageRate = P_averageRate; 00103 m_maxNbCreationPerPeriod = P_maxCreationPerPeriod; 00104 m_periodDuration = 1000; 00105 m_nbCallCreatedInPeriod = 0; 00106 m_currentTrafficDuration = 0; 00107 m_createdCallNb = 0; 00108 m_currentPeriodDuration = 0; 00109 ms_setup_time = P_setupTime * 1000; 00110 m_rateScale = P_rateScale ; 00111 00112 return (0); 00113 } 00114 00115 00116 void C_TrafficModel::start () 00117 { 00118 GET_TIME (&m_startTrafficDate); 00119 GET_TIME (&m_startPeriodDate); 00120 GET_TIME (&m_currentTimeval); 00121 } 00122 00123 00124 void C_TrafficModel::call_created () 00125 { 00126 m_sem_created_call->P(); 00127 m_createdCallNb++; 00128 m_sem_created_call->V(); 00129 m_sem_created_call_period->P(); 00130 m_nbCallCreatedInPeriod++; 00131 m_sem_created_call_period->V(); 00132 } 00133 00134 00147 // int C_TrafficModel::authorize_new_call () 00148 // { 00149 // int L_callLimit; 00150 // int L_burstLimit; 00151 // float L_NB1, L_S1; 00152 // float L_NB2, L_NB3, L_S2; 00153 // unsigned long L_outgoingTraffic; 00154 // static bool L_burst = false; 00155 00156 // long L_maxNbCreationPerPeriod ; 00157 // long L_desiredAverageRate ; 00158 // long L_createdCallNb ; 00159 // long L_nbCallCreatedInPeriod ; 00160 00161 // update (); 00162 // reset () ; 00163 00164 // m_sem_max->P(); 00165 // L_maxNbCreationPerPeriod = m_maxNbCreationPerPeriod ; 00166 // m_sem_max->V(); 00167 // m_sem_desired->P(); 00168 // L_desiredAverageRate = m_desiredAverageRate ; 00169 // m_sem_desired->V(); 00170 // m_sem_created_call->P(); 00171 // L_createdCallNb = m_createdCallNb ; 00172 // m_sem_created_call->V(); 00173 // m_sem_created_call_period->P(); 00174 // L_nbCallCreatedInPeriod = m_nbCallCreatedInPeriod ; 00175 // m_sem_created_call_period->V(); 00176 00177 00178 // // check m_currentTrafficDuration 00179 // if (m_currentTrafficDuration <= ms_setup_time) { 00180 // return (0); 00181 // } 00182 // L_outgoingTraffic = m_currentTrafficDuration - ms_setup_time; 00183 00184 // // compute L_callLimit 00185 00186 // GEN_DEBUG(0, "Outgoing Traffic Duration (ti-TO): " << (long) L_outgoingTraffic); 00187 // GEN_DEBUG(0, "Desired Call Rate (VO) : " << (long) L_desiredAverageRate); 00188 // GEN_DEBUG(0, "Calls Already Created (Ni) : " << (long) L_createdCallNb); 00189 00190 // L_NB1 = ( (float) ( (float) L_outgoingTraffic / (float) 1000.0) * 00191 // (float) L_desiredAverageRate); 00192 00193 // GEN_DEBUG(0, "NB1 = [ (ti - T0) * V0 ] : " << L_NB1); 00194 00195 // if ( (float) L_createdCallNb >= L_NB1 ) { 00196 // L_callLimit = 0; 00197 // } else { 00198 // L_S1 = L_NB1 - (float) L_createdCallNb; 00199 // L_callLimit = (int) (floor (L_S1) + (fmodf (L_S1, 1.0) > 0 ? 1 : 0)); 00200 // } 00201 // //GEN_DEBUG (C_Debug::E_LEVEL_5, "INFO", "L_callLimit = %d ", L_callLimit); 00202 00203 // if (!L_maxNbCreationPerPeriod) { 00204 // return (L_callLimit); // no burstLimit 00205 // } 00206 00207 // GEN_DEBUG(0, "Current Period Duration (ti-tp) : " << m_currentPeriodDuration << " ms"); 00208 // GEN_DEBUG(0, "Max Call Creation per Period (Vp) : " << L_maxNbCreationPerPeriod); 00209 // GEN_DEBUG(0, "Period Duration (D0) : " << m_periodDuration << " ms"); 00210 // GEN_DEBUG(0, "Calls Already Created during Period (Np) : " << m_nbCallCreatedInPeriod); 00211 00212 // // compute L_burstLimit 00213 // L_NB2 = (float) L_nbCallCreatedInPeriod; 00214 // //L_NB3 = (((float) m_currentPeriodDuration * (float) m_maxNbCreationPerPeriod) / 00215 // // (P1) ((float) m_periodDuration * (float) 1000.0)); 00216 00217 // L_NB3 = (((float) m_currentPeriodDuration * 00218 // (float) L_maxNbCreationPerPeriod) / 00219 // ((float) m_periodDuration)); 00220 00221 // GEN_DEBUG(0, "NB3 = [ ( (ti - tp) / D0 ) * Vp ] : " << L_NB3); 00222 00223 // if (L_NB2 >= L_NB3) { 00224 // L_burstLimit = 0; 00225 // } else { 00226 // L_S2 = L_NB3 - L_NB2; 00227 // L_burstLimit = (int) (floor (L_S2) + (fmodf (L_S2, 1.0) > 0 ? 1 : 0)); 00228 // } 00229 00230 // GEN_DEBUG(0, "L_burstLimit = " << L_burstLimit); 00231 // if (!L_callLimit) { 00232 // GEN_DEBUG(0, "End of burst mode : reached expected call rate"); 00233 // L_burst = false; 00234 // } else { 00235 // if (!L_burstLimit) { 00236 // // L_burstLimit may be null either if burst limit has been reached 00237 // // or at the beginning of a new period 00238 // if ((!L_burst) && (L_nbCallCreatedInPeriod)) { 00239 // GEN_DEBUG(0, "Burst control : reached burst limit"); 00240 // L_burst = true; 00241 // } 00242 // } 00243 // } 00244 // return ((L_callLimit < L_burstLimit) ? L_callLimit : L_burstLimit); 00245 // } /* end of authorize_new_call */ 00246 00247 00248 C_TrafficModel::C_TrafficModel () 00249 { 00250 NEW_VAR(m_sem_desired, C_Semaphore()); 00251 NEW_VAR(m_sem_max, C_Semaphore()); 00252 NEW_VAR(m_sem_created_call, C_Semaphore()); 00253 NEW_VAR(m_sem_created_call_period, C_Semaphore()); 00254 } 00255 00256 00257 C_TrafficModel::~C_TrafficModel() 00258 { 00259 DELETE_VAR(m_sem_desired); 00260 DELETE_VAR(m_sem_max); 00261 DELETE_VAR(m_sem_created_call); 00262 DELETE_VAR(m_sem_created_call_period); 00263 } 00264 00265 00266 unsigned long C_TrafficModel::get_desired_rate() { 00267 unsigned long L_return ; 00268 m_sem_desired->P(); 00269 L_return = m_desiredAverageRate ; 00270 m_sem_desired->V(); 00271 return (L_return); 00272 } 00273 00274 void C_TrafficModel::change_desired_rate (unsigned long P_rate) { 00275 m_sem_desired->P(); 00276 m_desiredAverageRate = P_rate ; 00277 re_init(); 00278 m_sem_desired->V(); 00279 } 00280 00281 void C_TrafficModel::change_rate_scale (long P_rateScale) { 00282 m_rateScale = P_rateScale ; 00283 } 00284 00285 00286 void C_TrafficModel::increase_desired_rate () { 00287 m_sem_desired->P(); 00288 m_desiredAverageRate += m_rateScale ; 00289 re_init(); 00290 m_sem_desired->V(); 00291 } 00292 00293 void C_TrafficModel::decrease_desired_rate () { 00294 m_sem_desired->P(); 00295 if (m_desiredAverageRate > m_rateScale) { 00296 m_desiredAverageRate -= m_rateScale ; 00297 re_init(); 00298 } 00299 m_sem_desired->V(); 00300 } 00301 00302 void C_TrafficModel::change_max_created_calls (unsigned long P_max) { 00303 m_sem_max->P(); 00304 m_maxNbCreationPerPeriod = P_max ; 00305 m_sem_max->V(); 00306 } 00307 00308 void C_TrafficModel::re_init() { 00309 m_sem_created_call->P(); 00310 m_createdCallNb = 0; 00311 GET_TIME (&m_startTrafficDate); 00312 GET_TIME (&m_startPeriodDate); 00313 m_sem_created_call->V(); 00314 } 00315 00316 00317 long C_TrafficModel::get_current_period_duration() { 00318 long L_currentPeriodDuration ; 00319 00320 m_sem_created_call->P(); 00321 L_currentPeriodDuration = m_currentPeriodDuration ; 00322 m_sem_created_call->V(); 00323 00324 return (L_currentPeriodDuration); 00325 }