//===================================================== file = ALR_util.c ===== //= A CSIM simulation of an adaptive service time M/M/1 queue = //= - Implements ALR utilization-threshold policy = //============================================================================= //= Notes: = //= 1. Can either generate Poisson arrivals or read arrivals from trace = //= 2. Buffer size can be set in either packets or bytes = //= 3. The following parameters are given in the command line = //= - Time to switch data rates (in seconds) = //= - Time period for utilization monitoring (in seconds) = //= - Target utilization for GEN_TYPE == POISSON. This input is = //= required but ignored when GEN_TYPE == FILE. = //= - Trace file with arrivals (only for GEN_TYPE == FILE ) = //= = //= To use generated Poisson arrivals = //= 1. Set GEN_TYPE == POISSON = //= 2. Arrival (lambda) and low service rate (mu) are set in main() = //= 3. High service rate is mu * MAX_RATE (the rate multiplier) = //= 4. Set DATA_RATE and corresponding PKT_SIZE = //= = //= To use arrivals read-in from traces = //= 1. Set GEN_TYPE == FILE = //= 2. Set FILE_FORMAT to appropriate file format = //= 3. If trace does not have packet sizes, set PKT_SIZE to required value = //= 4. Set DATA_RATE to the required value (in bits per second) = //= = //= To use packet based buffers: = //= 1. Uncomment #define BUFFER_PKT = //= 2. Set THRESH_MIN_PKT and THRESH_MAX_PKT = //= = //= To use byte based buffers: = //= 1. Comment out #define BUFFER_PKT = //= 2. Set BUFFER_SIZE to maximum buffer size (in bytes) = //= 3. Set THRESH_MIN_KBYTE and THRESH_MAX_KBYTE (in kilo bytes) = //= = //=---------------------------------------------------------------------------= //= Example input: = //= Packet based buffers: THRESH_MIN_PKT = 1, THRESH_MAX_PKT = 30 = //= GEN_TYPE == POISSON = //= T_switch = 0.0, T_util = 0.010, Target_Util = 0.09 (9% utilization) = //= mu = 8333.3333 = //= DATA_RATE = 100e6 (Set low data rate to 100 Mb/s) = //= PKT_SIZE = 1500 (corresponds to mu = 8333.33 at 100 Mb/s) = //= MAX_ARRIVALS = 10.0e6 = //=---------------------------------------------------------------------------= //= Example execution: = //= === BEGIN SIMULATION === = //= ============================================ ALR_util.c ======= = //= == *** CSIM simulation of an adaptive service time queue *** == = //= =============================================================== = //= = >>> Poisson = //= = lambda = 7499.999970 cust/sec = //= = mu = 8333.333300 cust/sec = //= = Target_Util = 9.00 % = //= = >>> UTIL THRESHOLD POLICY = //= = MAX_RATE = 10 = //= = T_switch = 0.000000 sec = //= = T_util = 0.010000 sec = //= = U_THRESH = 5.000000 % = //= = Thresh_max = 30 pkts = //= = Thresh_min = 1 pkts = //= = P_FIX = 0.000000 Watts = //= = P_LOW = 1.500000 Watts = //= = P_HIGH = 4.000000 Watts = //= =============================================================== = //= = Total CPU time = 21.015000 sec = //= = Total sim time = 1333.856748 sec = //= = Total completions = 10000000 cust = //= =-------------------------------------------------------------- = //= = Server utilization = 9.397180 % = //= = Mean num in system = 0.116709 cust = //= = Mean response time = 0.000016 sec 0.015567 ms = //= = Mean service time = 0.000013 sec 0.012534 ms = //= = Mean throughput = 7497.056946 cust/sec = //= = Max queue length = 30 pkts = //= = Total service time = 125.344908 sec = //= = Ideal low time = 1333.856748 sec = //= = Avg burst duration = 0.000000 sec = //= =-------------------------------------------------------------- = //= = Time in low rate = 6.65 sec 0.50 % = //= = Mean low rate time = 1.663396 sec = //= = Time in high rate = 1327.20 sec 99.50 % = //= = Mean high rate time = 331.800791 sec = //= = Num rate switches = 7 = //= =-------------------------------------------------------------- = //= = Total num samples = 133385 = //= = Num samples under = 3 = //= = Pct samples under = 0.00 % = //= =-------------------------------------------------------------- = //= = alpha metric = 1.003127 = //= = gamma metric = 1.003127 = //= =============================================================== = //= = //=---------------------------------------------------------------------------= //= Build: bcc32 -w-pro ALR_util.c csim19.obj csim19.lib = //=---------------------------------------------------------------------------= //= Execute: ALR_util T_switch T_util Target_Util < in.dat = //= T_switch - time to switch data rates (seconds) = //= T_util - time period for monitoring utilization (seconds) = //= Target_Util - target utilization - range is (0,1) = //= - (used in GEN_TYPE == POISSON ) = //= in.dat - input trace file (GEN_TYPE==FILE only) = //=---------------------------------------------------------------------------= //= Author: Chamara Gunaratne = //= University of South Florida = //= Email: pgunarat@csee.usf.edu = //=---------------------------------------------------------------------------= //= History: KJC (06/14/05) - Genesis (from adaptive5.c) = //= Aug 25, 2005 - Modified from adaptive5.c = //= Sep 26, 2005 - Modified from adaptive6.c = //= Sep 26, 2005 - Added byte based buffers = //= Oct 18, 2005 - Changed variable names = //= Mar 18, 2006 - Added dual-thresh policy and cleaned up junk = //= Aug 28, 2006 - Added BURST file format = //= Dec 25, 2006 - Renamed ALR_util.c = //= Jan 13, 2007 - Some minor modifications = //============================================================================= //----- Includes -------------------------------------------------------------- #include // Needed for printf() #include // needed for atof() #include // needed for atof() #include // Needed for assert() macro #include "csim.h" // Needed for CSIM18 stuff //----- Defines --------------------------------------------------------------- #define FALSE 0 // Boolean false #define TRUE 1 // Boolean true #define POISSON 0 // Poisson generator #define FILE 1 // Read in from trace file #define USF 0 // Delta time in seconds, packet size in bytes #define PSU 1 // Delat time in microseconds, packet size zero #define TIME_ONLY 2 // Delta time in seconds, no packet size #define BURST 3 // Similar to USF with burst begin, end marker #define BUFFER_PKT // Switch buffer to packet mode from byte mode #define FILE_FORMAT USF // data file format //#define FILE_FORMAT PSU // data file format //#define FILE_FORMAT TIME_ONLY // data file format //#define FILE_FORMAT BURST // data file format //#define GEN_TYPE POISSON // Generator type #define GEN_TYPE FILE // Generator type #define SIM_TIME 1.0e7 // Total simulation time in seconds #define MAX_ARRIVALS 10.0e6 // Maximum number of arrivals (for Poisson) #define PKT_SIZE 1518 // pkt size for traces without pkt size #define DATA_RATE 10e6 // low data rate of queue in bits/s #define MAX_RATE 10 // Rate multiplier #define BUFFER_SIZE 32768 // buffer size in bytes - 32KB #define THRESH_MIN_PKT 15 // Min threshold (k1) in packets #define THRESH_MAX_PKT 30 // Max threshold (k2) in packets #define THRESH_MIN_KBYTE 0 // Min threshold (k1) in kilo bytes #define THRESH_MAX_KBYTE 32 // Max threshold (k2) in kilo bytes #define RATE_SAMPLE_TIME 0.001 // rate sampling interval for printing rate #define U_THRESH 0.05 // Low utilization threshold #define P_FIX 0.0 // Power consumption fixed #define P_LOW 1.5 // Power consumption low data rate #define P_HIGH 4.0 // Power consumption high data rate //----- Globals --------------------------------------------------------------- FACILITY Server; // CSIM facility for server EVENT Done; // CSIM event for trace is done TABLE Table_rate1; // CSIM table for time in low rate TABLE Table_rateMax; // CSIM table for time in high rate TABLE Table_delay; // CSIM table for response times TABLE Table_burst_time; // CSIM table for recording burst duration int Rate_index; // Rate index double Rate_switch_time; // Time of last rate switch int Util_switch_flag; // Utilization switch flag long int Buffer_size; // Current buffer size - in bytes double Sample_byte_count; // Number of bytes counted during T_util interval int Rate_switch_count; // Rate switch counter long int Max_queue_length; // Maximum recorded queue length double Ideal_low_time; // Ideal low time with no delay impact double Total_serv_time; // Total time spent servicing arrivals long int Total_num_samples; // Total number of utilization samples taken long int Num_samples_under; // Number of samples under threshold // these variables are accepted from the command line double T_switch; // Time to switch between rates (sec) double T_util; // Utilization sampling interval (for dropping data rate) double Target_Util; // Targeted utilization level (Poisson only) long int Thresh_min; // Minimum threshold value long int Thresh_max; // Maximum threshold value //----- Prototypes ------------------------------------------------------------ void gen_poisson(double lambda, double mu); // Generator void gen_file(); // Generator void queue1(double service_time, double pkt_size, int pkt_type, double start_time); // Queue void sample_util(); // Compute utilization and change rate void print_rate(void); // periodically sample and print the data rate //============================================================================= //== Main program == //============================================================================= void sim(int argc, char *argv[]) { double lambda; // Mean arrival rate (cust/sec) double mu; // Mean service rate (cust/sec) double e_norm; // Energy used if only high data rate double e_save; // Energy used in savings mode double alpha_metric; // Singh energy metric (E/Es) double gamma_metric; // Green energy metric (E/Es)(D/Ds) // sanity check assert(argc == 4); // update T_switch from command line T_switch = (double)atof(argv[1]); T_util = (double)atof(argv[2]); Target_Util = (double)atof(argv[3]); // debug //printf("T_switch: %f D_BOUND: %f THRESH_DYNA: %d T_util: %f S_DELAY: %f Target_Util: %f \n", \ T_switch, D_BOUND, THRESH_DYNA, T_util, S_DELAY, Target_Util); // Set the maximum and minimum buffer thresholds #ifdef BUFFER_PKT // if counting buffer in packets // Set the minimum threshold Thresh_min = THRESH_MIN_PKT; // Set the maximum threshold Thresh_max = THRESH_MAX_PKT; #else // if counting buffer in bytes // Set the minimum threshold Thresh_min = (int)((double)THRESH_MIN_KBYTE * 1024.0); // Set the maximum threshold Thresh_max = (int)((double)THRESH_MAX_KBYTE * 1024.0); // sanity check assert(Thresh_max <= BUFFER_SIZE); #endif // sanity check - check that max is < min assert(Thresh_min < Thresh_max); // debug //printf("Thresh_min: %d Thresh_max: %d \n", Thresh_min, Thresh_max ); // Create the simulation create("sim"); // CSIM and variable initializations Server = facility("Server for single-server queue"); Table_rate1 = table("Rate index 1 time table"); Table_rateMax = table("Rate index RATE_MAX time table"); Table_delay = table("Response time delays"); Table_burst_time = table("Burst durations"); Done = event("Done"); max_processes((long)100000 ); Rate_index = 1; // start in low rate Rate_switch_count = 0; Rate_switch_time = 0.0; Util_switch_flag = FALSE; Max_queue_length = 0; Total_serv_time = 0.0; Buffer_size = 0; Ideal_low_time = 0.0; Sample_byte_count = 0.0; Total_num_samples = 0; Num_samples_under = 0; // Parameter initializaitons - for Poisson mu = 8333.3333; // Give lambda as a percentage of max rate of arrivals lambda = (double)mu * (double)MAX_RATE * (double)Target_Util; // Give lambda as pkts/ms at 1000 Mb/s at required utilization level //lambda = (double)83333.3333 * (double)Target_Util; // Output begin-of-simulation banner printf("=== BEGIN SIMULATION === \n"); // Initiate the utilization sample process sample_util(); // Initiate the rate printing process (for graphing data only) //print_rate(); // Initiate appropriate generate function if (GEN_TYPE == POISSON) gen_poisson(lambda, mu); else if (GEN_TYPE == FILE) gen_file(); // Hold for simulation time if (GEN_TYPE == POISSON) //hold(SIM_TIME); wait(Done); else if (GEN_TYPE == FILE) wait(Done); // Make last update to rate tables if (Rate_index == 1) record((clock - Rate_switch_time), Table_rate1); else if (Rate_index == MAX_RATE) record((clock - Rate_switch_time), Table_rateMax); // Compute Singh energy metric e_norm = clock * (P_FIX + P_HIGH); e_save = clock * P_FIX; e_save = e_save + (table_sum(Table_rate1) * P_LOW); e_save = e_save + (table_sum(Table_rateMax) * P_HIGH); alpha_metric = e_norm / e_save; // Compute Green energy metric - not used in this program /*if (resp(Server) <= D_BOUND) gamma_metric = alpha_metric; else gamma_metric = alpha_metric * (D_BOUND / resp(Server));*/ gamma_metric = alpha_metric; // Output results printf("============================================ ALR_util.c ======= \n"); printf("== *** CSIM simulation of an adaptive service time queue *** == \n"); printf("=============================================================== \n"); if (GEN_TYPE == POISSON) { printf("= >>> Poisson \n"); printf("= lambda = %f cust/sec \n", lambda); printf("= mu = %f cust/sec \n", mu); printf("= Target_Util = %.2f %% \n", ((double)Target_Util * 100) ); } else if (GEN_TYPE == FILE) { printf("= >>> FILE \n"); printf("= DATA_RATE (low) = %.2f Mb/s \n", (double)DATA_RATE/1e6); } printf("= >>> UTIL THRESHOLD POLICY \n"); printf("= MAX_RATE = %d \n", MAX_RATE); printf("= T_switch = %f sec \n", T_switch); printf("= T_util = %f sec \n", T_util); printf("= U_THRESH = %f %% \n", 100.0 * U_THRESH); #ifdef BUFFER_PKT printf("= Thresh_max = %d pkts \n", Thresh_max); printf("= Thresh_min = %d pkts \n", Thresh_min); #else printf("= BUFFER_SIZE = %d KB \n", (BUFFER_SIZE/1024) ); printf("= Thresh_max = %d KB \n", (Thresh_max/1024) ); printf("= Thresh_min = %d KB \n", (Thresh_min/1024) ); #endif printf("= P_FIX = %f Watts \n", P_FIX); printf("= P_LOW = %f Watts \n", P_LOW); printf("= P_HIGH = %f Watts \n", P_HIGH); printf("=============================================================== \n"); printf("= Total CPU time = %f sec \n", cputime()); printf("= Total sim time = %f sec \n", clock); printf("= Total completions = %ld cust \n", (unsigned long int)completions(Server)); printf("=-------------------------------------------------------------- \n"); printf("= Server utilization = %f %% \n", 100.0 * util(Server)); printf("= Mean num in system = %f cust \n", qlen(Server)); printf("= Mean response time = %f sec %f ms \n", resp(Server), resp(Server) * 1000); printf("= Mean service time = %f sec %f ms \n", serv(Server), serv(Server) * 1000); printf("= Mean throughput = %f cust/sec \n", tput(Server)); #ifdef BUFFER_PKT printf("= Max queue length = %d pkts \n", Max_queue_length); #else printf("= Max queue length = %d bytes \n", Max_queue_length); #endif printf("= Total service time = %f sec \n", Total_serv_time); printf("= Ideal low time = %f sec \n", Ideal_low_time); printf("= Avg burst duration = %f sec \n", table_mean(Table_burst_time) ); printf("=-------------------------------------------------------------- \n"); printf("= Time in low rate = %.2f sec\t %.2f %% \n", \ table_sum(Table_rate1), (table_sum(Table_rate1) * 100.0 / clock)); printf("= Mean low rate time = %f sec \n", table_mean(Table_rate1)); printf("= Time in high rate = %.2f sec\t %.2f %% \n", \ table_sum(Table_rateMax), (table_sum(Table_rateMax) * 100.0 / clock)); printf("= Mean high rate time = %f sec \n", table_mean(Table_rateMax)); printf("= Num rate switches = %d \n", Rate_switch_count); printf("=-------------------------------------------------------------- \n"); #ifndef NO_UTIL_THRESH printf("= Total num samples = %d \n", Total_num_samples); printf("= Num samples under = %d \n", Num_samples_under); printf("= Pct samples under = %.2f %% \n", \ (double)Num_samples_under / (double)Total_num_samples * 100); #endif printf("=-------------------------------------------------------------- \n"); printf("= alpha metric = %f \n", alpha_metric); printf("= gamma metric = %f \n", gamma_metric); printf("=============================================================== \n"); } //============================================================================= //== Process to generate Poisson customers == //============================================================================= void gen_poisson(double lambda, double mu) { int out_id; // To (destination) outport number double z; // Random number between 0.0 and 1.0 double inter_arrival_time; // Inter arrival time double service_time; // Service time for this customer int pkt_size = 1500; // pkt size double trace_time = 0.0; // total time in trace double temp1; unsigned long int counter = 0; create("gen_poisson"); // Packet generation loop while(TRUE) { // Hold for desired interarrival time inter_arrival_time = expntl(1.0 / lambda); hold(inter_arrival_time); // compute ideal low time temp1 = inter_arrival_time - ((double)T_switch * 2.0); if (temp1 > 0) Ideal_low_time = Ideal_low_time + temp1; // increment the running trace time value trace_time = trace_time + inter_arrival_time; // service time is exponentially distributed //service_time = exponential(1.0 / mu); // if generating service times using average packet sizes //pkt_size = (int)expntl((double)1500.00); //service_time = ((double)pkt_size * 8.0) / (double)DATA_RATE; // if generating service times using fixed packet sizes pkt_size = (int)PKT_SIZE; service_time = ((double)pkt_size * 8.0) / (double)DATA_RATE; // increment the input buffer size Buffer_size = Buffer_size + (long int)pkt_size; // enqueue packet queue1(service_time, (double)pkt_size, (int)1, (double)clock); // debug //printf("clock: %f trace_time: %f pkt_size: %d service_time: %f\n", \ clock, trace_time, pkt_size, service_time); counter = counter + 1; if ((double)counter > (double)MAX_ARRIVALS) break; } set(Done); } //============================================================================= //== Process to read trace file and generate customers == //============================================================================= void gen_file() { char seps[] = " \t,"; // possible token separators char *token; // temporary token holder char instring[1000]; // for reading in data from stdin double service_time; // Service time for this customer double inter_arrival_time; // pkt arrival time double pkt_size; // pkt size int pkt_type = 0; // Packet type in burst double trace_time = 0.0; // total time in trace double temp1; // Temporary variable create("gen_file"); // Loop forever to create customers while(1) { // read in the data line from file gets(instring); // if end-of-file exit loop if (feof(stdin)) break; // check for comments if ((instring[0] == '#') || (instring[0] == '&')) continue; // for traces with arrival time in seconds and pkt size in bytes if (FILE_FORMAT == USF) { token = (char *)strtok(instring, seps); inter_arrival_time = (double)atof(token); token = (char *)strtok(NULL, seps); pkt_size = (double)atof(token); } // For Singh's traces - arrival time is in us, no pkt size else if (FILE_FORMAT == PSU) { token = (char *)strtok(instring, seps); inter_arrival_time = (double)atof(token) / 1e6; pkt_size = PKT_SIZE; } // For traces with arrival time only is seconds, no pkt size else if (FILE_FORMAT == TIME_ONLY) { token = (char *)strtok(instring, seps); inter_arrival_time = (double)atof(token); pkt_size = (double)PKT_SIZE; } // for traces with arrival time in seconds, pkt size in bytes and pkt type else if (FILE_FORMAT == BURST) { token = (char *)strtok(instring, seps); inter_arrival_time = (double)atof(token); token = (char *)strtok(NULL, seps); pkt_size = (double)atof(token); token = (char *)strtok(NULL, seps); pkt_type = (int)atoi(token); } // sanity check - sometimes negative numbers exist in delta times if (inter_arrival_time < 0) inter_arrival_time = 0.0; // compute ideal low time temp1 = inter_arrival_time - ((double)T_switch * 2.0); if (temp1 > 0) Ideal_low_time = Ideal_low_time + temp1; // increment the running trace time value trace_time = trace_time + inter_arrival_time; // calculate the service time for packet at 'low' data rate service_time = (pkt_size * 8) / DATA_RATE; // hold for arrival time hold(inter_arrival_time); // increment the input buffer size Buffer_size = Buffer_size + (long int)pkt_size; // enqueue packet queue1(service_time, pkt_size, pkt_type, (double)clock); // debug //printf("clock: %.3f trace_time: %.3f arrival_time: %.6f pkt_size: %.1f service_time: %f Buffer_size: %d \n", \ clock, trace_time, inter_arrival_time, pkt_size, \ service_time, Buffer_size); } set(Done); } //============================================================================= //== Process for single server queue with adaptive rate change == //============================================================================= void queue1(double service_time, double pkt_size, int pkt_type, double start_time) { double t_queue; // for computing queueing time double t_response; // for computing response time static double t_last_depart = 0.0; // for computing inter-departure CoV static double t_burst_start = 0.0; // for computing burst time for FILE_TYPE == BURST create("queue1"); // update max queue length #ifdef BUFFER_PKT if (qlength(Server) > Max_queue_length) Max_queue_length = qlength(Server); #else if (Buffer_size > Max_queue_length) Max_queue_length = Buffer_size; #endif // Update byte count during T_util time period Sample_byte_count = Sample_byte_count + (double)pkt_size; // debug //printf("clock: %f enqueuing packet. Buffer_size: %d \n", clock, (int)Buffer_size ); // identify the beginning of a burst if ((FILE_FORMAT == BURST) && (pkt_type == 0)) t_burst_start = clock; // Reserve the server reserve(Server); // Check for need for a switch delay if rate has been decreased if (Util_switch_flag == TRUE) { // debug //printf("clock: %f - rate change to lower rate detected \n", clock); assert(Rate_index == 1); if ((clock - Rate_switch_time) <= T_switch) hold( T_switch - (clock - Rate_switch_time) ); Util_switch_flag = FALSE; } // Increase the rate if queue length is at threshold #ifdef BUFFER_PKT if ( (qlength(Server) >= (Thresh_max - 1) ) && (Rate_index == 1)) #else if ( (Buffer_size >= Thresh_max) && (Rate_index == 1)) #endif { // debug //printf("clock: %f - changing to higher data rate. qlength(Server): %d \n", \ clock, (int)qlength(Server) ); //printf("clock: %f - changing to higher data rate. Buffer_size: %d \n", \ clock, Buffer_size ); // this assert triggers on equal - it should trigger on < only // -- 0.999999999 is a hack to stop this assert triggering on equal if (clock > T_switch) assert ((clock - Rate_switch_time) >= (T_switch * 0.999999)); record((clock - Rate_switch_time), Table_rate1); Rate_index = MAX_RATE; Rate_switch_time = clock; Rate_switch_count++; hold(T_switch); } // compute the queueing time t_queue = (double)clock - start_time; // Service the customer hold(service_time / Rate_index); // compute the response time (waiting time + processing time) t_response = (double)clock - start_time; // record the delay time in table for intermediate calculations tabulate(Table_delay, t_response); // print the data for calculating 99% delay and CoV of departures //printf("t_queue: %.10f t_response: %.10f \n", t_queue, t_response); //printf("t_inter_packet: %.10f \n", (clock - t_last_depart) ); // update last departure time t_last_depart = clock; // decrement the buffer and sanity check Buffer_size = Buffer_size - pkt_size; assert(Buffer_size >= 0); // debug //printf("clock: %f dequeueed packet. Buffer_size: %d \n", \ clock, (int)Buffer_size); // compute total service time Total_serv_time = Total_serv_time + (service_time / Rate_index); // identify and record the duration of a burst if ((FILE_FORMAT == BURST) && (pkt_type == 2)) tabulate(Table_burst_time, (clock - t_burst_start) ); // Release the server release(Server); } //============================================================================= //== Process for sampling utilization == //============================================================================= void sample_util() { double max_byte_count; // Maximum bytes during T_util int num_in_sys; // Number of packets in the system create("sample_util"); // compute max_byte_count during T_util max_byte_count = ( (double)DATA_RATE * (double)T_util * (double)MAX_RATE ) / (double)8.0; max_byte_count = max_byte_count * (double)U_THRESH; // compute max packet count during T_util // debug //printf("max_byte_count: %f \n", max_byte_count ); // Utilization sampling loop while(1) { hold(T_util); // debug //printf("clock: %f Sample_byte_count: %f max_byte_count: %f Buffer_size: %d Thresh_min: %d \n", \ clock, Sample_byte_count, max_byte_count, (int)Buffer_size, (int)Thresh_min ); // compute the number in the system num_in_sys = qlength(Server) + num_busy(Server); // Update the number of samples under threshold and total number of samples if (Sample_byte_count <= max_byte_count) Num_samples_under = Num_samples_under + 1; Total_num_samples = Total_num_samples + 1; // Reduce the rate if utilization is low #ifdef BUFFER_PKT if ( (Sample_byte_count <= max_byte_count) && (Rate_index == MAX_RATE) && (num_in_sys < Thresh_min) ) #else if ( (Sample_byte_count <= max_byte_count) && (Rate_index == MAX_RATE) && (Buffer_size <= Thresh_min) ) #endif { record((clock - Rate_switch_time), Table_rateMax); Rate_index = 1; Rate_switch_time = clock; Rate_switch_count++; Util_switch_flag = TRUE; // debug //printf("clock: %f - changed to lower rate. Buffer_size: %d num_in_sys: %d \n", \ clock, Buffer_size, num_in_sys); } // Initialize sample count back to zero Sample_byte_count = 0.0; } // -- end of while loop } //============================================================================= //== Process for printing the data rate (for graphing purposes) == //============================================================================= void print_rate(void) { create("print_rate"); // rate printing loop while(1) { // Hold for a RATE_SAMPLE_TIME hold(RATE_SAMPLE_TIME); if (Rate_index == MAX_RATE) printf("%f %f %f print_rate\n", clock, (double)0, (double)1.0); else if (Rate_index == 1) printf("%f %f %f print_rate\n", clock, (double)1.0, (double)0); } }