/* $Id: perf.c,v 10.1 92/10/06 23:06:57 ca Exp $ */ /* * MaRS Maryland Routing Simulator * Copyright (c) 1991 University of Maryland * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of U.M. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. U.M. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Authors: Cengiz Alaettinoglu, Klaudia Dussa-Zieger, Ibrahim Matta * Systems Design and Analysis Group * Department of Computer Science * University of Maryland at College Park. */ /* * Performance Monitor to collect statistics about the network. * * * pm is not a part of * the network so do not connect it to a component in the network. If an * interaction is needed btw pm and components it can be done in two ways * 1) pm can poll * at start time the component should issue * pm(comp, comp_type, NEW_COMPONENT) * so the pm knows the component. Notice that this will work fine * when we have dynamically changing networks. * 2) pm can be called in an event driven way like * pm(link, LINK, LINK_DOWN) * 3) pm_util_update calculates the utilization (load) of the network * in a time-driven manner. * pm_util_update(link, ROUT_UTIL) * TNT, AvgDelayPerPacket are done by polling. LinkCnt, ITNT, ConnCnt * are done by the event driven way. * * TNT and ITNT are in terms of data/msec. AvgDelayPerPacket is in msecs. * */ #include #include #include #include "sim.h" #include "simx.h" #include "q.h" #include "list.h" #include "component.h" #include "log.h" #include "comptypes.h" #include "packet.h" #include "eventdefs.h" #include "event.h" #include "perf.h" #include "link.h" #include "node.h" #ifdef DEBUG extern Log debug_log; #endif extern list *comps; Pmt *pm_adr; /* address of the performance monitor */ static caddr_t pm_create(), pm_start(), pm_delete(), pm_reset(), pm_util_update(), pm_perf_update(), pm_stop(); caddr_t pm_action(src, g, type, pkt, arg) Component *src; register Pmt *g; int type; Packet *pkt; caddr_t arg; { caddr_t result = NULL; dbg_set_level(DBG_ERR); /* Just a big switch on type of event */ switch (type) { case EV_RESET: #ifdef DEBUG dbg_write(debug_log, DBG_INFO, (Component *)g, "reset"); #endif result = pm_reset(g); break; case EV_CREATE: /* Minor sanity check first-- g should be NULL when initializing. */ #ifdef DEBUG if (g) dbg_write(debug_log, DBG_INFO, (Component *)NULL, "PM Generator initialization called with non-null pointer."); #endif result = pm_create((char *)arg); break; case EV_DEL: result = (caddr_t) pm_delete(g); break; case EV_NEIGHBOR: result = (caddr_t) NULL; break; case EV_UNEIGHBOR: result = (caddr_t) NULL; break; case EV_MK_PEER: result = (caddr_t) NULL; break; case EV_START: result = pm_start(g); break; case EV_STOP: result = pm_stop(g); break; /********** The preceding were the commands. Following are the actual events that the application/transport module expects to receive. */ case EV_PERF_UPDATE: result = pm_perf_update(g); result = pm_util_update(g); break; default: #ifdef DEBUG dbg_write(debug_log, DBG_ERR, (Component *)g, "got unexpected event of type %x", type); #endif break; } return(result); } /****************************************/ static caddr_t pm_create(name) register char *name; { Pmt *g; if (pm_adr) { return (caddr_t) NULL; } /* Memory for the component structure. */ pm_adr = g = (Pmt *)sim_malloc(sizeof(Pmt)); /* First things first-- copy name into the new structure. */ strncpy(g->pm_name, "Monitor", 40); /* have to create a neighbor list */ g->pm_neighbors = l_create(); g->pm_params = q_create(); g->pm_class = AUXILIARY_CLASS; g->pm_type = PERF_MONITOR; g->pm_action = pm_action; g->pm_menu_up = FALSE; /* Initialize the parameters */ (void)param_init((Component *)g, "Monitor", (PFD)NULL, make_name_text, make_short_name_text, (PFI)NULL, 0, DisplayMask, 0.0); g->TNT = param_init((Component *)g, "Total network throughput", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->TNT->u.d = 0.0; g->ITNT = param_init((Component *)g, "Inst network acked rate", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 100.0); g->ITNT->u.d = 0.0; g->ITNT_SD = param_init((Component *)g, "Time var of inst acked rate", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->ITNT_SD->u.d = 0.0; g->AvgDelay = param_init((Component *)g, "Average delay/packet", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->AvgDelay->u.d = 0.0; g->InstDelay = param_init((Component *)g, "Inst ave delay/packet", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->InstDelay->u.d = 0.0; g->InstDelay_SD = param_init((Component *)g, "Time var of inst delay", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->InstDelay_SD->u.d = 0.0; g->MaxDelay = param_init((Component *)g, "Max delay/packet", int_calc, make_int_text, make_short_int_text, param_input_int, TIME_HISTORY, DisplayMask | ModifyMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->MaxDelay->u.i = 0; g->ConnCnt = param_init((Component *)g, "Connection count", int_calc, make_int_text, make_short_int_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->ConnCnt->u.i = 0; /* The following are statistics for the selected connections */ g->sTNT = param_init((Component *)g, "Total selected net throughput", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->sTNT->u.d = 0.0; g->sITNT = param_init((Component *)g, "Inst selected net acked rate", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 100.0); g->sITNT->u.d = 0.0; g->sITNT_SD = param_init((Component *)g, "Time var of inst sel. acked rate", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->sITNT_SD->u.d = 0.0; g->sAvgDelay = param_init((Component *)g, "Selected avg delay/packet", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->sAvgDelay->u.d = 0.0; g->sInstDelay = param_init((Component *)g, "Inst sel. ave delay/packet", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->sInstDelay->u.d = 0.0; g->sInstDelay_SD = param_init((Component *)g, "Time var of sel. inst delay", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->sInstDelay_SD->u.d = 0.0; g->sMaxDelay = param_init((Component *)g, "Max sel. delay/packet", int_calc, make_int_text, make_short_int_text, param_input_int, TIME_HISTORY, DisplayMask | ModifyMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->sMaxDelay->u.i = 0; g->sConnCnt = param_init((Component *)g, "Selected connection count", int_calc, make_int_text, make_short_int_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->sConnCnt->u.i = 0; g->sPktDropped = param_init((Component *)g, "Selected packets Dropped", int_calc, make_int_text, make_short_int_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->sPktDropped->u.i = 0; /* The following are used to compute ITNT */ g->srecent_pkts_acked = 0; g->srecent_bytes_acked = 0; /* The above are statistics for the selected connections */ g->FTP_avg_conn_size = param_init((Component *)g, "FTP Avg Pkts/Conn", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->FTP_avg_conn_size->u.i = 0.0; g->FTP_avg_conn_size_SD = param_init((Component *)g, "FTP SD : Pkts/Conn", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->FTP_avg_conn_size_SD->u.i = 0.0; g->FTP_avg_conn_duration = param_init((Component *)g, "FTP Avg Time of a Conn", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->FTP_avg_conn_duration->u.i = 0.0; g->FTP_avg_conn_duration_SD = param_init((Component *)g, "FTP SD : Time of a Conn", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->FTP_avg_conn_duration_SD->u.i = 0.0; g->TELNET_avg_conn_size = param_init((Component *)g, "TELNET Avg Pkts/Conn", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->TELNET_avg_conn_size->u.i = 0.0; g->TELNET_avg_conn_size_SD = param_init((Component *)g, "TELNET SD : Pkts/Conn", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->TELNET_avg_conn_size_SD->u.i = 0.0; g->TELNET_avg_conn_duration = param_init((Component *)g, "TELNET Avg Time of a Conn", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->TELNET_avg_conn_duration->u.i = 0.0; g->TELNET_avg_conn_duration_SD = param_init((Component *)g, "TELNET SD : Time of a Conn", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->TELNET_avg_conn_duration_SD->u.i = 0.0; g->LinkFailCnt = param_init((Component *)g, "Link failure count", int_calc, make_int_text, make_short_int_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->LinkFailCnt->u.i = 0; g->PktDropped = param_init((Component *)g, "Packets Dropped", int_calc, make_int_text, make_short_int_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->PktDropped->u.i = 0; g->RoutingPkts = param_init((Component *)g, "Routing Packets in net", int_calc, make_int_text, make_short_int_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->RoutingPkts->u.i = 0; g->DataLoad = param_init((Component *)g, "Data Packet Load", double_calc, make_double_text, make_short_double_text, (PFI)NULL, BAR_GRAPH, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.1); g->DataLoad->u.d = 0.0; g->IDataLoad = param_init((Component *)g, "Inst. Data Packet Load", double_calc, make_double_text, make_short_double_text, (PFI)NULL, BAR_GRAPH, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.1); g->IDataLoad->u.d = 0.0; g->DataLoadSD = param_init((Component *)g, "Time var. of Data Load", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->DataLoadSD->u.d = 0.0; g->RoutLoad = param_init((Component *)g, "Routing Packet Load", double_calc, make_double_text, make_short_double_text, (PFI)NULL, BAR_GRAPH, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.1); g->RoutLoad->u.d = 0.0; g->IRoutLoad = param_init((Component *)g, "Inst. Routing Packet Load", double_calc, make_double_text, make_short_double_text, (PFI)NULL, BAR_GRAPH, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.1); g->IRoutLoad->u.d = 0.0; g->RoutLoadSD = param_init((Component *)g, "Time var. of Routing Load", double_calc, make_double_text, make_short_double_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->RoutLoadSD->u.d = 0.0; g->max_buffer_space = param_init((Component *)g, "Max occupied buffer space in net", int_calc, make_int_text, make_short_int_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->max_buffer_space->u.i = 0; g->min_buffer_space = param_init((Component *)g, "Min occupied buffer space", int_calc, make_int_text, make_short_int_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->min_buffer_space->u.i = 0; g->ave_buffer_space = param_init((Component *)g, "Ave occupied buffer space", int_calc, make_int_text, make_short_int_text, (PFI)NULL, TIME_HISTORY, DisplayMask | CanHaveMeterMask | CanHaveLogMask, 0.0); g->ave_buffer_space->u.i = 0; g->netlinkl = (LinkList *) NULL; /* The following are used to compute ITNT */ g->recent_pkts_acked = 0; g->recent_bytes_acked = 0; #ifdef DEBUG dbg_write(debug_log, DBG_INFO, (Component *)g, "pm generator initialized"); #endif return((caddr_t)g); } static caddr_t pm_reset(g) Pmt *g; { LinkList *netlink; int i; g->TNT->u.d = 0.0; g->ITNT->u.d = 0.0; g->ITNT_SD->u.d = 0.0; g->AvgDelay->u.d = 0.0; g->MaxDelay->u.i = 0; g->InstDelay->u.d = 0.0; g->InstDelay_SD->u.d = 0.0; g->ConnCnt->u.i = 0; g->LinkFailCnt->u.i = 0; g->PktDropped->u.i = 0; g->RoutingPkts->u.i = 0; g->DataLoad->u.d = 0.0; g->IDataLoad->u.d = 0.0; g->DataLoadSD->u.d = 0.0; g->RoutLoad->u.d = 0.0; g->IRoutLoad->u.d = 0.0; g->RoutLoadSD->u.d = 0.0; g->FTP_avg_conn_size->u.d = 0.0; g->FTP_avg_conn_duration->u.d = 0.0; g->FTP_avg_conn_size_SD->u.d = 0.0; g->FTP_avg_conn_duration_SD->u.d = 0.0; g->TELNET_avg_conn_size->u.d = 0.0; g->TELNET_avg_conn_duration->u.d = 0.0; g->TELNET_avg_conn_size_SD->u.d = 0.0; g->TELNET_avg_conn_duration_SD->u.d = 0.0; log_param((Component *)g, g->TNT); log_param((Component *)g, g->ITNT); log_param((Component *)g, g->ITNT_SD); log_param((Component *)g, g->AvgDelay); log_param((Component *)g, g->MaxDelay); log_param((Component *)g, g->InstDelay); log_param((Component *)g, g->InstDelay_SD); log_param((Component *)g, g->ConnCnt); log_param((Component *)g, g->LinkFailCnt); log_param((Component *)g, g->PktDropped); log_param((Component *)g, g->RoutingPkts); log_param((Component *)g, g->DataLoad); log_param((Component *)g, g->IDataLoad); log_param((Component *)g, g->DataLoadSD); log_param((Component *)g, g->RoutLoad); log_param((Component *)g, g->IRoutLoad); log_param((Component *)g, g->RoutLoadSD); log_param((Component *)g, g->FTP_avg_conn_size); log_param((Component *)g, g->FTP_avg_conn_duration); log_param((Component *)g, g->FTP_avg_conn_size_SD); log_param((Component *)g, g->FTP_avg_conn_duration_SD); log_param((Component *)g, g->TELNET_avg_conn_size); log_param((Component *)g, g->TELNET_avg_conn_duration); log_param((Component *)g, g->TELNET_avg_conn_size_SD); log_param((Component *)g, g->TELNET_avg_conn_duration_SD); /* Following are for TNT, AvgDelay etc */ g->tot_bytes_acked = 0.0; g->tot_delay = 0.0; g->recent_delay = 0.0; g->tot_pkts_acked = 0; /* The following are used to compute ITNT */ g->recent_pkts_acked = 0; g->recent_bytes_acked = 0; /* The following to compute standard dev of ITNT */ g->sX = 0.0; g->sX2 = 0.0; g->ITNT_pnt = 0; /* The following to compute standard dev of InstDelay */ g->sY = 0.0; g->sY2 = 0.0; /* The following are for the selected connections */ g->sTNT->u.d = 0.0; g->sITNT->u.d = 0.0; g->sITNT_SD->u.d = 0.0; g->sAvgDelay->u.d = 0.0; g->sMaxDelay->u.i = 0; g->sInstDelay->u.d = 0.0; g->sInstDelay_SD->u.d = 0.0; g->sConnCnt->u.i = 0; g->sPktDropped->u.i = 0; log_param((Component *)g, g->sTNT); log_param((Component *)g, g->sITNT); log_param((Component *)g, g->sITNT_SD); log_param((Component *)g, g->sAvgDelay); log_param((Component *)g, g->sMaxDelay); log_param((Component *)g, g->sInstDelay); log_param((Component *)g, g->sInstDelay_SD); log_param((Component *)g, g->sConnCnt); log_param((Component *)g, g->sPktDropped); /* Following are for TNT, AvgDelay etc */ g->stot_bytes_acked = 0.0; g->stot_delay = 0.0; g->srecent_delay = 0.0; g->stot_pkts_acked = 0; /* The following are used to compute ITNT */ g->srecent_pkts_acked = 0; g->srecent_bytes_acked = 0; /* The following to compute standard dev of ITNT */ g->ssX = 0.0; g->ssX2 = 0.0; g->sITNT_pnt = 0; /* The following to compute standard dev of InstDelay */ g->ssY = 0.0; g->ssY2 = 0.0; /* The above are for the selected connections */ /* The following are required to computer SD of RoutLoad and of DataLoad */ while (g->netlinkl != (LinkList *) NULL) { /* empty netlinkl */ netlink = g->netlinkl; g->netlinkl = g->netlinkl->next; free(netlink); } g->Pnt = 0; g->DatasX = 0.0; g->DatasX2 = 0.0; g->RoutsX = 0.0; g->RoutsX2 = 0.0; /* The following are used to compute max, min, and average "max occupied buffer space" for all nodes in the network */ g->max_buffer_space->u.i = 0; g->min_buffer_space->u.i = 0; g->ave_buffer_space->u.i = 0; g->sum_buffer_space = 0; g->total_no_of_nodes = 0; log_param((Component *)g, g->max_buffer_space); log_param((Component *)g, g->min_buffer_space); log_param((Component *)g, g->ave_buffer_space); /* following for conn statistics */ g->FTP_ConnTotSize = 0.0; g->FTP_ConnTotDuration = 0.0; g->FTP_ConnTotSize2 = 0.0; g->FTP_ConnTotDuration2 = 0.0; g->FTP_ConnTotCnt = 0; g->TELNET_ConnTotSize = 0.0; g->TELNET_ConnTotDuration = 0.0; g->TELNET_ConnTotSize2 = 0.0; g->TELNET_ConnTotDuration2 = 0.0; g->TELNET_ConnTotCnt = 0; return (caddr_t) g; } static caddr_t pm_start(g) register Pmt *g; { ev_enqueue(EV_PERF_UPDATE, (Component *)g, (Component *)g, (tick_t)(ev_now() + perf_update_dt_usecs / USECS_PER_TICK), g->pm_action, (Packet *)NULL, (caddr_t)NULL); return((caddr_t)g); } static caddr_t pm_delete(g) register Pmt *g; { LinkList *netlink; /* empty netlinkl */ while (g->netlinkl != (LinkList *) NULL) { netlink = g->netlinkl; g->netlinkl = g->netlinkl->next; free(netlink); } comp_delete((Component *)g); pm_adr = (Pmt *) NULL; return((caddr_t)g); } /* pm_util_update Time-driven calculation of the link utilizations and the network utilization */ static caddr_t pm_util_update(g) register Pmt *g; { Link *aux_link; /* pointer to a link */ LinkList *aux_list; /* pointer to a linklist */ double idataload; /* Data and ack network load */ double iroutload; /* Routing network load */ double helpdata; /* auxilliary variable */ double helprout; /* auxilliary variable */ int no_links; /* no of uni-directional links */ int update; /* latest update */ idataload = 0.0; iroutload = 0.0; helpdata = 0.0; helprout = 0.0; no_links = 0; update = ev_now(); aux_list = pm_adr->netlinkl; /* Calculation of the link utilization now happens in the perf module */ /* While going through the link_list the instantaneous utilization of every*/ /* link (routing and data) is calculated */ /* The network utilization and the standard deviation is calculated */ while ( aux_list != (LinkList *) NULL) { aux_link = ((Link *)(aux_list->comp)); /* Calculation of the data/ack/token and routing utilization of the link in one direction */ if (aux_link->data_bytes_1 > aux_link->bytes_in_dt) { aux_link->data_bytes_1 = aux_link->data_bytes_1 - aux_link->bytes_in_dt; aux_link->idata_util_1->u.d = 1.0; } else { aux_link->idata_util_1->u.d = ((double)(aux_link->data_bytes_1) * 1000000.0 ) / ( (double)(aux_link->link_bandwidth->u.i) * (double)(perf_update_dt_usecs) ); aux_link->data_bytes_1 = 0; } if (aux_link->rout_bytes_1 > aux_link->bytes_in_dt) { aux_link->rout_bytes_1 = aux_link->rout_bytes_1 - aux_link->bytes_in_dt; aux_link->irout_util_1->u.d = 1.0; } else { aux_link->irout_util_1->u.d = ((double)(aux_link->rout_bytes_1) * 1000000.0 ) / ( (double)(aux_link->link_bandwidth->u.i) * (double)(perf_update_dt_usecs) ); aux_link->rout_bytes_1 = 0; } /* Calculation of the data/ack/token and routing utilization of the link in the second direction */ if (aux_link->data_bytes_2 > aux_link->bytes_in_dt) { aux_link->data_bytes_2 = aux_link->data_bytes_2 - aux_link->bytes_in_dt; aux_link->idata_util_2->u.d = 1.0; } else { aux_link->idata_util_2->u.d = ((double)(aux_link->data_bytes_2) * 1000000.0 ) / ( (double)(aux_link->link_bandwidth->u.i) * (double)(perf_update_dt_usecs) ); aux_link->data_bytes_2 = 0; } if (aux_link->rout_bytes_2 > aux_link->bytes_in_dt) { aux_link->rout_bytes_2 = aux_link->rout_bytes_2 - aux_link->bytes_in_dt; aux_link->irout_util_2->u.d = 1.0; } else { aux_link->irout_util_2->u.d = ((double)(aux_link->rout_bytes_2) * 1000000.0 ) / ( (double)(aux_link->link_bandwidth->u.i) * (double)(perf_update_dt_usecs) ); aux_link->rout_bytes_2 = 0; } /* Calculation of the instanteous network load (not normed by the number of links) */ idataload = idataload + aux_link->idata_util_1->u.d + aux_link->idata_util_2->u.d; iroutload = iroutload + aux_link->irout_util_1->u.d + aux_link->irout_util_2->u.d; no_links += 2; log_param((Component *)aux_link, aux_link->idata_util_1); log_param((Component *)aux_link, aux_link->idata_util_2); log_param((Component *)aux_link, aux_link->irout_util_1); log_param((Component *)aux_link, aux_link->irout_util_2); aux_list = aux_list->next; } /* Calculation of the instantaneous network data/ack/token load */ idataload = idataload / (double)(no_links); pm_adr->IDataLoad->u.d = idataload; /* Calculation of the instantaneous network routing load */ iroutload = iroutload / (double)(no_links); pm_adr->IRoutLoad->u.d = iroutload; /* Logging the instantaneous data load and routing load */ log_param((Component *)pm_adr, pm_adr->IDataLoad); log_param((Component *)pm_adr, pm_adr->IRoutLoad); /* If the simulation is already in the measurement interval, the average values for data load and routing load, as well as their standard deviations, are calculated */ if ( update > skip_time_in_ticks){ update = update - skip_time_in_ticks; /* I assign the correct value to update here; instead of subtracting it in every formula */ /* Calculation of the network data/ack/token load */ helpdata = pm_adr->DataLoad->u.d; helpdata = helpdata * ((double)(update) * (double)(USECS_PER_TICK) - (double)(perf_update_dt_usecs)); helpdata = helpdata + idataload * (double)(perf_update_dt_usecs); helpdata = helpdata / ((double)(update) * (double)(USECS_PER_TICK)); pm_adr->DataLoad->u.d = helpdata; log_param((Component *)pm_adr, pm_adr->DataLoad); /* Calculation of the standard deviation of the network data/ack/token load */ pm_adr->Pnt++; pm_adr->DatasX += helpdata; pm_adr->DatasX2 += helpdata * helpdata; #ifndef OFFLINE pm_adr->DataLoadSD->u.d = sqrt((pm_adr->DatasX2 - ((pm_adr->DatasX * pm_adr->DatasX) / (double)(pm_adr->Pnt))) / ((double)(pm_adr->Pnt) - 1.0) ); log_param((Component *)pm_adr, pm_adr->DataLoadSD); #endif /* Calculation of the network routing load */ helprout = pm_adr->RoutLoad->u.d; helprout = helprout * ((double)(update) * (double)(USECS_PER_TICK) - (double)(perf_update_dt_usecs)); helprout = helprout + iroutload * (double)(perf_update_dt_usecs); helprout = helprout / ((double)(update) * (double)(USECS_PER_TICK)); pm_adr->RoutLoad->u.d = helprout; log_param((Component *)pm_adr, pm_adr->RoutLoad); /* Calculation of the standard deviation of the network routing load */ pm_adr->RoutsX += helprout; pm_adr->RoutsX2 += helprout * helprout; #ifndef OFFLINE pm_adr->RoutLoadSD->u.d = sqrt((pm_adr->RoutsX2 - ((pm_adr->RoutsX * pm_adr->RoutsX) / (double)(pm_adr->Pnt))) / ((double)(pm_adr->Pnt) - 1.0) ); log_param((Component *)pm_adr, pm_adr->RoutLoadSD); #endif } return((caddr_t)g); } void pm(comp, comp_type, req_type, arg1, arg2, arg3, arg4) Component *comp; int comp_type; int req_type; int arg1, arg2, arg3; int arg4; /* Flag indicates whether the conn is selected */ { LinkList *netlink; if (pm_adr) switch (req_type) { case NEW_COMPONENT : if (comp_type == LINK) { netlink = (LinkList*) sim_malloc(sizeof(LinkList)); netlink->comp = comp; netlink->next = pm_adr->netlinkl; pm_adr->netlinkl = netlink; } break; case LINK_FAILURE : pm_adr->LinkFailCnt->u.i++; log_param((Component *)pm_adr, pm_adr->LinkFailCnt); break; case LINK_WAKEUP : pm_adr->LinkFailCnt->u.i--; log_param((Component *)pm_adr, pm_adr->LinkFailCnt); break; case CONN_UP : pm_adr->ConnCnt->u.i++; #ifdef PERF_DEBUG fprintf(stderr, "CONN_UP, Connection Count : %d\n", pm_adr->ConnCnt->u.i); fprintf(stderr, "comp_type, req_type, arg1, arg2, arg3 : %d %d %d %d %d\n", comp_type, req_type, arg1, arg2, arg3); #endif log_param((Component *)pm_adr, pm_adr->ConnCnt); if (arg4) { pm_adr->sConnCnt->u.i++; log_param((Component *)pm_adr, pm_adr->sConnCnt); } break; case CONN_DOWN : pm_adr->ConnCnt->u.i -= arg3; #ifdef PERF_DEBUG fprintf(stderr, "CONN_DOWN, Connection Count : %d\n", pm_adr->ConnCnt->u.i); fprintf(stderr, "comp_type, req_type, arg1, arg2, arg3 : %d %d %d %d %d\n", comp_type, req_type, arg1, arg2, arg3); #endif log_param((Component *)pm_adr, pm_adr->ConnCnt); if (comp_type == FTP_SOURCE && ev_now() >= skip_time_in_ticks) { pm_adr->FTP_ConnTotSize += arg2; pm_adr->FTP_ConnTotSize2 += (double)arg2 * (double)arg2; pm_adr->FTP_ConnTotDuration += arg1; pm_adr->FTP_ConnTotDuration2 += (double)arg1 * (double)arg1; pm_adr->FTP_ConnTotCnt += arg3; #ifndef OFFLINE pm_adr->FTP_avg_conn_size->u.d = pm_adr->FTP_ConnTotSize / (double)pm_adr->FTP_ConnTotCnt; pm_adr->FTP_avg_conn_duration->u.d = pm_adr->FTP_ConnTotDuration / (double)pm_adr->FTP_ConnTotCnt; pm_adr->FTP_avg_conn_size_SD->u.d = sqrt((pm_adr->FTP_ConnTotSize2 - pm_adr->FTP_ConnTotSize * pm_adr->FTP_ConnTotSize / (double)pm_adr->FTP_ConnTotCnt) / ((double)pm_adr->FTP_ConnTotCnt - 1.0)); pm_adr->FTP_avg_conn_duration_SD->u.d = sqrt((pm_adr->FTP_ConnTotDuration2 - pm_adr->FTP_ConnTotDuration * pm_adr->FTP_ConnTotDuration / (double)pm_adr->FTP_ConnTotCnt) / ((double)pm_adr->FTP_ConnTotCnt - 1.0)); log_param((Component *)pm_adr, pm_adr->FTP_avg_conn_size); log_param((Component *)pm_adr, pm_adr->FTP_avg_conn_duration); log_param((Component *)pm_adr, pm_adr->FTP_avg_conn_size_SD); log_param((Component *)pm_adr, pm_adr->FTP_avg_conn_duration_SD); #endif } if (comp_type == TELNET_SOURCE && ev_now() >= skip_time_in_ticks) { pm_adr->TELNET_ConnTotSize += arg2; pm_adr->TELNET_ConnTotSize2 += (double)arg2 * (double)arg2; pm_adr->TELNET_ConnTotDuration += arg1; pm_adr->TELNET_ConnTotDuration2 += (double)arg1 * (double)arg1; pm_adr->TELNET_ConnTotCnt += arg3; #ifndef OFFLINE pm_adr->TELNET_avg_conn_size->u.d = pm_adr->TELNET_ConnTotSize / (double)pm_adr->TELNET_ConnTotCnt; pm_adr->TELNET_avg_conn_duration->u.d = pm_adr->TELNET_ConnTotDuration / (double)pm_adr->TELNET_ConnTotCnt; pm_adr->TELNET_avg_conn_size_SD->u.d = sqrt((pm_adr->TELNET_ConnTotSize2 - pm_adr->TELNET_ConnTotSize * pm_adr->TELNET_ConnTotSize / (double)pm_adr->TELNET_ConnTotCnt) / ((double)pm_adr->TELNET_ConnTotCnt - 1.0)); pm_adr->TELNET_avg_conn_duration_SD->u.d = sqrt((pm_adr->TELNET_ConnTotDuration2 - pm_adr->TELNET_ConnTotDuration * pm_adr->TELNET_ConnTotDuration / (double)pm_adr->TELNET_ConnTotCnt) / ((double)pm_adr->TELNET_ConnTotCnt - 1.0)); log_param((Component *)pm_adr, pm_adr->TELNET_avg_conn_size); log_param((Component *)pm_adr, pm_adr->TELNET_avg_conn_duration); log_param((Component *)pm_adr, pm_adr->TELNET_avg_conn_size_SD); log_param((Component *)pm_adr, pm_adr->TELNET_avg_conn_duration_SD); #endif } if (arg4) { pm_adr->sConnCnt->u.i -= arg3; } break; case PKT_RETRANSMITTED : pm_adr->PktDropped->u.i++; /* no log_param here for efficiency * it is done in periodic part */ if (arg4) { pm_adr->sPktDropped->u.i++; } break; case ROUTING_PKT : pm_adr->RoutingPkts->u.i += arg1;/* no log_param here for efficiency*/ break; case ACK_RECEIVED : pm_adr->recent_pkts_acked++; pm_adr->recent_bytes_acked += arg1; pm_adr->recent_delay+= arg2; if (ev_now() >= skip_time_in_ticks) { pm_adr->tot_pkts_acked ++; pm_adr->tot_bytes_acked += arg1; pm_adr->tot_delay+= arg2; if (TICKS_TO_USECS(arg2) > pm_adr->MaxDelay->u.i) { pm_adr->MaxDelay->u.i = TICKS_TO_USECS(arg2); log_param((Component *)pm_adr, pm_adr->MaxDelay); } } if (arg4) { pm_adr->srecent_pkts_acked++; pm_adr->srecent_bytes_acked += arg1; pm_adr->srecent_delay+= arg2; if (ev_now() >= skip_time_in_ticks) { pm_adr->stot_pkts_acked ++; pm_adr->stot_bytes_acked += arg1; pm_adr->stot_delay+= arg2; if (TICKS_TO_USECS(arg2) > pm_adr->sMaxDelay->u.i) { pm_adr->sMaxDelay->u.i = TICKS_TO_USECS(arg2); log_param((Component *)pm_adr, pm_adr->sMaxDelay); } } } break; default: ; } /* switch */ } static caddr_t pm_perf_update(g) register Pmt *g; { int recent_pkts, srecent_pkts; #ifndef OFFLINE g->TNT->u.d = g->tot_bytes_acked * 1000.0 / ((double) ((ev_now()- skip_time_in_ticks) * USECS_PER_TICK)); if (g->tot_pkts_acked) g->AvgDelay->u.d = (g->tot_delay * (double)USECS_PER_TICK) / ((double)g->tot_pkts_acked) / ((double)1000); log_param((Component *)g, g->TNT); log_param((Component *)g, g->AvgDelay); #endif log_param((Component *)g, g->PktDropped); log_param((Component *)g, g->RoutingPkts); /* The following to compute ITNT */ g->ITNT->u.d = (((double)(g->recent_bytes_acked))* 1000.0) / ((double) perf_update_dt_usecs); log_param((Component *)g , g->ITNT); /* The following to compute InstDelay */ g->InstDelay->u.d = (g->recent_pkts_acked) ? g->recent_delay * (double)USECS_PER_TICK / 1000.0 / (double) g->recent_pkts_acked : 0.0; log_param((Component *)g, g->InstDelay); g->recent_delay = 0; recent_pkts = g->recent_pkts_acked; g->recent_pkts_acked = 0; g->recent_bytes_acked = 0; /* The following are for the selected connections */ #ifndef OFFLINE g->sTNT->u.d = g->stot_bytes_acked * 1000.0 / ((double) ((ev_now()- skip_time_in_ticks) * USECS_PER_TICK)); if (g->stot_pkts_acked) g->sAvgDelay->u.d = (g->stot_delay * (double)USECS_PER_TICK) / ((double)g->stot_pkts_acked) / ((double)1000); log_param((Component *)g, g->sTNT); log_param((Component *)g, g->sAvgDelay); #endif log_param((Component *)g, g->sPktDropped); /* The following to compute ITNT */ g->sITNT->u.d = (((double)(g->srecent_bytes_acked))* 1000.0) / ((double) perf_update_dt_usecs); log_param((Component *)g , g->sITNT); /* The following to compute InstDelay */ g->sInstDelay->u.d = (g->srecent_pkts_acked) ? g->srecent_delay * (double)USECS_PER_TICK / 1000.0 / (double) g->srecent_pkts_acked : 0.0; log_param((Component *)g, g->sInstDelay); g->srecent_delay = 0; srecent_pkts = g->srecent_pkts_acked; g->srecent_pkts_acked = 0; g->srecent_bytes_acked = 0; /* The above are for the selected connections */ ev_enqueue(EV_PERF_UPDATE, (Component *)g, (Component *)g, (tick_t)(ev_now() + perf_update_dt_usecs / USECS_PER_TICK), g->pm_action, (Packet *)NULL, (caddr_t)NULL); if (ev_now() <= skip_time_in_ticks) return((caddr_t)g); /* The following to compute standard dev of InstDelay */ g->sY += (g->InstDelay->u.d) * recent_pkts; g->sY2 += (g->InstDelay->u.d * g->InstDelay->u.d) * recent_pkts; /* The following to compute standard dev of ITNT */ g->ITNT_pnt ++; g->sX += g->ITNT->u.d; g->sX2 += g->ITNT->u.d * g->ITNT->u.d; #ifndef OFFLINE g->InstDelay_SD->u.d = sqrt((g->sY2 - ((g->sY * g->sY) / (double)(g->tot_pkts_acked))) / ((double)(g->tot_pkts_acked) - 1.0)); log_param((Component *)g, g->InstDelay_SD); g->ITNT_SD->u.d = sqrt((g->sX2 - ((g->sX * g->sX) / (double)(g->ITNT_pnt))) / ((double)(g->ITNT_pnt) - 1.0)); log_param((Component *)g, g->ITNT_SD); #endif /* The following are for the selected connections */ /* The following to compute standard dev of InstDelay */ g->ssY += (g->sInstDelay->u.d) * srecent_pkts; g->ssY2 += (g->sInstDelay->u.d * g->sInstDelay->u.d) * srecent_pkts; /* The following to compute standard dev of ITNT */ g->sITNT_pnt ++; g->ssX += g->sITNT->u.d; g->ssX2 += g->sITNT->u.d * g->sITNT->u.d; #ifndef OFFLINE g->sInstDelay_SD->u.d = sqrt((g->ssY2 - ((g->ssY * g->ssY) / (double)(g->stot_pkts_acked))) / ((double)(g->stot_pkts_acked) - 1.0)); log_param((Component *)g, g->sInstDelay_SD); g->sITNT_SD->u.d = sqrt((g->ssX2 - ((g->ssX * g->ssX) / (double)(g->sITNT_pnt))) / ((double)(g->sITNT_pnt) - 1.0)); log_param((Component *)g, g->sITNT_SD); #endif /* The above are for the selected connections */ return((caddr_t)g); } /****************************************/ static caddr_t pm_stop(g) Pmt *g; { Component *cc; g->max_buffer_space->u.i = 0; g->min_buffer_space->u.i = 999999999; g->ave_buffer_space->u.i = 0; g->total_no_of_nodes = 0; g->sum_buffer_space = 0; for (cc = (COMPONENT *) comps->l_head; cc; cc = cc->co_next) { if (cc->co_class == NODE_CLASS) { if (((Nodee *)cc)->max_occupied_space->u.i > g->max_buffer_space->u.i) g->max_buffer_space->u.i = ((Nodee *)cc)->max_occupied_space->u.i; if (((Nodee*)cc)->max_occupied_space->u.i < g->min_buffer_space->u.i) g->min_buffer_space->u.i = ((Nodee *)cc)->max_occupied_space->u.i; g->sum_buffer_space += ((Nodee *)cc)->max_occupied_space->u.i; g->total_no_of_nodes++; } } g->ave_buffer_space->u.i = g->sum_buffer_space / g->total_no_of_nodes; g->TNT->u.d = g->tot_bytes_acked * 1000.0 / ((double) ((ev_now() - skip_time_in_ticks) * USECS_PER_TICK)); if (g->tot_pkts_acked) g->AvgDelay->u.d = (g->tot_delay * (double)USECS_PER_TICK) / ((double)g->tot_pkts_acked) / ((double)1000); g->ITNT_SD->u.d = sqrt((g->sX2 - ((g->sX * g->sX) / (double)(g->ITNT_pnt))) / ((double)(g->ITNT_pnt) - 1.0)); g->InstDelay_SD->u.d = sqrt((g->sY2 - ((g->sY * g->sY) / (double)(g->tot_pkts_acked))) / ((double)(g->tot_pkts_acked) - 1.0)); g->DataLoadSD->u.d = sqrt((g->DatasX2 - ((g->DatasX * g->DatasX) / (double)(g->Pnt))) / ((double)(g->Pnt) - 1.0) ); g->RoutLoadSD->u.d = sqrt((g->RoutsX2 - ((g->RoutsX * g->RoutsX) / (double)(g->Pnt))) / ((double)(g->Pnt) - 1.0) ); if (g->FTP_ConnTotCnt) { g->FTP_avg_conn_size->u.d = g->FTP_ConnTotSize / (double)g->FTP_ConnTotCnt; g->FTP_avg_conn_duration->u.d = g->FTP_ConnTotDuration / (double)g->FTP_ConnTotCnt; g->FTP_avg_conn_size_SD->u.d = sqrt((g->FTP_ConnTotSize2 - g->FTP_ConnTotSize * g->FTP_ConnTotSize / (double)g->FTP_ConnTotCnt) / ((double)g->FTP_ConnTotCnt - 1.0)); g->FTP_avg_conn_duration_SD->u.d = sqrt((g->FTP_ConnTotDuration2 - g->FTP_ConnTotDuration * g->FTP_ConnTotDuration / (double)g->FTP_ConnTotCnt) / ((double)g->FTP_ConnTotCnt - 1.0)); log_param((Component *)g, g->FTP_avg_conn_size); log_param((Component *)g, g->FTP_avg_conn_duration); log_param((Component *)g, g->FTP_avg_conn_size_SD); log_param((Component *)g, g->FTP_avg_conn_duration_SD); } if (g->TELNET_ConnTotCnt) { g->TELNET_avg_conn_size->u.d = g->TELNET_ConnTotSize / (double)g->TELNET_ConnTotCnt; g->TELNET_avg_conn_duration->u.d = g->TELNET_ConnTotDuration / (double)g->TELNET_ConnTotCnt; g->TELNET_avg_conn_size_SD->u.d = sqrt((g->TELNET_ConnTotSize2 - g->TELNET_ConnTotSize * g->TELNET_ConnTotSize / (double)g->TELNET_ConnTotCnt) / ((double)g->TELNET_ConnTotCnt - 1.0)); g->TELNET_avg_conn_duration_SD->u.d = sqrt((g->TELNET_ConnTotDuration2 - g->TELNET_ConnTotDuration * g->TELNET_ConnTotDuration / (double)g->TELNET_ConnTotCnt) / ((double)g->TELNET_ConnTotCnt - 1.0)); log_param((Component *)g, g->TELNET_avg_conn_size); log_param((Component *)g, g->TELNET_avg_conn_duration); log_param((Component *)g, g->TELNET_avg_conn_size_SD); log_param((Component *)g, g->TELNET_avg_conn_duration_SD); } log_param((Component *)g, g->max_buffer_space); log_param((Component *)g, g->min_buffer_space); log_param((Component *)g, g->ave_buffer_space); log_param((Component *)g, g->TNT); log_param((Component *)g, g->AvgDelay); log_param((Component *)g, g->ITNT_SD); log_param((Component *)g, g->InstDelay_SD); log_param((Component *)g, g->DataLoadSD); log_param((Component *)g, g->RoutLoadSD); /* The following are for the selected connections */ g->sTNT->u.d = g->stot_bytes_acked * 1000.0 / ((double) ((ev_now() - skip_time_in_ticks) * USECS_PER_TICK)); if (g->stot_pkts_acked) g->sAvgDelay->u.d = (g->stot_delay * (double)USECS_PER_TICK) / ((double)g->stot_pkts_acked) / ((double)1000); g->sITNT_SD->u.d = sqrt((g->ssX2 - ((g->ssX * g->ssX) / (double)(g->sITNT_pnt))) / ((double)(g->sITNT_pnt) - 1.0)); g->sInstDelay_SD->u.d = sqrt((g->ssY2 - ((g->ssY * g->ssY) / (double)(g->stot_pkts_acked))) / ((double)(g->stot_pkts_acked) - 1.0)); log_param((Component *)g, g->sTNT); log_param((Component *)g, g->sAvgDelay); log_param((Component *)g, g->sITNT_SD); log_param((Component *)g, g->sInstDelay_SD); /* The above are for the selected connections */ return ((caddr_t)g); }