Alex Bikfalvi
SimStream Documentation
ModelPush.cpp
00001 #include "Headers.h" 00002 #include "ModelPush.h" 00003 #include "Shuffle.h" 00004 #include "Rand.h" 00005 #include "Debug.h" 00006 00007 #include "EventServerStart.h" 00008 #include "EventClientArrive.h" 00009 #include "EventClientWatch.h" 00010 #include "EventClientLeave.h" 00011 00012 #pragma warning(disable : 4996) 00013 00014 CModelPush::CModelPush( 00015 char* name, 00016 __time maxTime, 00017 CTopo* topology, 00018 __uint32 topologyNumber, 00019 CModelChannel* modelChannel, 00020 __uint32 numHosts, 00021 __uint32 numGateways, 00022 __uint32 bwAccessBins, 00023 __bitrate* bwAccessUpLink, 00024 __bitrate* bwAccessDownLink, 00025 double* bwAccessRatio, 00026 __time delayAccessUpLink, 00027 __time delayAccessDownLink, 00028 __bitrate bwServerUpLink, 00029 __bitrate bwServerDownLink, 00030 __time delayServerUpLink, 00031 __time delayServerDownLink, 00032 __uint32 queueLink, 00033 __uint32 queueLinkServer, 00034 __uint32 numChannelsMcast, 00035 __uint32 numChannelsUcast, 00036 __bitrate channelBw, 00037 __byte channelFps, 00038 __byte mpegGopDistanceItoI, 00039 __byte mpegGopDistanceItoP, 00040 __uint32 streamBufferSize, 00041 __uint32 streamBufferSizeHistory, 00042 __uint32 streamBufferSizeBuffering, 00043 __time streamBufferUnderrunTimeout, 00044 double streamBwMargin, 00045 __uint32 bootQueryMax, 00046 __uint32 bootRefreshThreshold, 00047 __time bootQueryTimeout, 00048 __time bootRegisterDelay 00049 ) : CModel(maxTime, topology) 00050 { 00051 assert(name); 00052 assert(numHosts > 0); 00053 assert(numGateways > 0); 00054 assert(bwAccessBins > 0); 00055 00056 // Simulator 00057 this->name = name; 00058 this->sim = NULL; 00059 this->topology = topology; 00060 this->topologyNumber = topologyNumber; 00061 this->modelChannel = modelChannel; 00062 00063 // Nodes 00064 this->numHosts = numHosts; 00065 this->numServers = 1; 00066 this->numGateways = (numGateways <= this->topology->Nodes())?numGateways:this->topology->Nodes(); 00067 this->bwAccessBins = bwAccessBins; 00068 this->bwAccessUpLink = bwAccessUpLink; 00069 this->bwAccessDownLink = bwAccessDownLink; 00070 this->bwAccessRatio = bwAccessRatio; 00071 this->delayAccessUpLink = delayAccessUpLink; 00072 this->delayAccessDownLink = delayAccessDownLink; 00073 this->bwServerUpLink = bwServerUpLink; 00074 this->bwServerDownLink = bwServerDownLink; 00075 this->delayServerUpLink = delayServerUpLink; 00076 this->delayServerDownLink = delayServerDownLink; 00077 this->queueLink = queueLink; 00078 this->queueLinkServer = queueLinkServer; 00079 00080 this->hosts = NULL; 00081 this->routers = NULL; 00082 this->server = NULL; 00083 this->linksCore = NULL; 00084 this->linksAccess = NULL; 00085 this->linkServer = NULL; 00086 00087 // Channels 00088 this->numChannels = numChannelsUcast + numChannelsMcast; 00089 this->numChannelsUcast = numChannelsUcast; 00090 this->numChannelsMcast = numChannelsMcast; 00091 this->channelBw = channelBw; 00092 this->channelFps = channelFps; 00093 00094 // Stream 00095 this->streamBufferSize = streamBufferSize; 00096 this->streamBufferSizeHistory = streamBufferSizeHistory; 00097 this->streamBufferSizeBuffering = streamBufferSizeBuffering; 00098 this->streamBufferUnderrunTimeout = streamBufferUnderrunTimeout; 00099 this->streamBwMargin = streamBwMargin; 00100 00101 // Bootstrap 00102 this->bootQueryMax = bootQueryMax; 00103 this->bootRefreshThreshold = bootRefreshThreshold; 00104 this->bootQueryTimeout = bootQueryTimeout; 00105 this->bootRegisterDelay = bootRegisterDelay; 00106 00107 // Generate gateways 00108 this->gateways = new __uint32[this->numHosts]; 00109 00110 // Generate gateway links (the number of access links for each gateway) 00111 this->routerAccessLinks = new __uint32[this->topology->Nodes()]; 00112 00113 for(__uint32 index = 0; index < this->topology->Nodes(); index++) 00114 this->routerAccessLinks[index] = 0; 00115 00116 // Generate gateway for server 00117 this->gatewayServer = CRand::Generate(this->topology->Nodes()); 00118 00119 // Shuffle routers 00120 CShuffle shuffleRouters(this->topology->Nodes()); 00121 00122 // Assign a gateway for each host 00123 for(__uint32 index = 0; index < this->numHosts; index++) 00124 { 00125 __uint32 gw = shuffleRouters[CRand::Generate(this->numGateways-1)]; 00126 assert(gw < this->topology->Nodes()); 00127 00128 this->gateways[index] = gw; 00129 this->routerAccessLinks[gw]++; 00130 } 00131 00132 // Generate route 00133 this->routeNodes = this->topology->Nodes(); 00134 this->routeDst = this->topology->Nodes() + this->numHosts + this->numServers; 00135 00136 this->route = new int*[this->routeNodes]; 00137 00138 for(__uint32 index = 0; index < this->routeNodes; index++) 00139 { 00140 this->route[index] = new int[this->routeDst]; 00141 } 00142 00143 // Addresses for the multicast RP for each channel 00144 this->mcastRp = new CAddress[this->numChannelsMcast]; 00145 00146 for(__uint32 index = 0; index < this->numChannelsMcast; index++) 00147 this->mcastRp[index] = ROUTER_ADDR(this->gatewayServer); 00148 00149 // Create channels 00150 this->channelsMcast = new CChannel[this->numChannelsMcast]; 00151 00152 for(__uint32 index = 0; index < this->numChannelsMcast; index++) 00153 this->channelsMcast[index] = CChannel(index, CChannel::CHANNEL_MULTICAST, CAddress::Multicast(index), this->channelBw, this->channelFps); 00154 00155 this->channelsUcast = new CChannel[this->numChannelsUcast]; 00156 00157 for(__uint32 index = 0; index < this->numChannelsUcast; index++) 00158 this->channelsUcast[index] = CChannel(index + this->numChannelsMcast, CChannel::CHANNEL_UNICAST, SERVER_ADDR(0), this->channelBw, this->channelFps); 00159 00160 // Create stream sources for all channels 00161 this->streamSources = new CStreamSourceMpeg*[this->numChannels]; 00162 00163 // Create stream sources 00164 for(__uint32 index = 0; index < this->numChannels; index++) 00165 { 00166 this->streamSources[index] = new CStreamSourceMpeg( 00167 this->Channel(index), 00168 mpegGopDistanceItoI, 00169 mpegGopDistanceItoP); 00170 } 00171 00172 // Generate access bandwidth 00173 this->bwAccessHostUpLink = new __bitrate[this->numHosts]; 00174 this->bwAccessHostDownLink = new __bitrate[this->numHosts]; 00175 00176 // Randomize Hosts 00177 CShuffle shuffleHosts(this->numHosts); 00178 00179 __uint32 index = 0; 00180 for(unsigned bin = 0; (bin < this->bwAccessBins) && (index < this->numHosts); bin++) 00181 { 00182 __uint32 binSize = (__uint32)ceil(this->bwAccessRatio[bin] * this->numHosts); 00183 for(__uint32 idx = 0; idx < binSize; idx++, index++) 00184 { 00185 this->bwAccessHostUpLink[shuffleHosts[index]] = this->bwAccessUpLink[bin]; 00186 this->bwAccessHostDownLink[shuffleHosts[index]] = this->bwAccessDownLink[bin]; 00187 } 00188 } 00189 00190 // Data 00191 this->data = new CData( 00192 this->name, 00193 this->topologyNumber, 00194 this->numChannelsMcast 00195 ); 00196 } 00197 00198 CModelPush::~CModelPush() 00199 { 00200 // Delete gateways 00201 delete[] this->gateways; 00202 delete[] this->routerAccessLinks; 00203 00204 // Delete routes 00205 for(__uint32 index = 0; index < this->routeNodes; index++) 00206 delete[] this->route[index]; 00207 delete[] this->route; 00208 00209 // Delete multicast RP addresses 00210 delete[] this->mcastRp; 00211 00212 // Delete stream sources 00213 for(__uint32 index = 0; index < this->numChannels; index++) 00214 delete this->streamSources[index]; 00215 delete[] this->streamSources; 00216 00217 // Delete channels 00218 delete[] this->channelsMcast; 00219 delete[] this->channelsUcast; 00220 00221 // Delete access bandwidth 00222 delete[] this->bwAccessHostUpLink; 00223 delete[] this->bwAccessHostDownLink; 00224 00225 // Delete data 00226 delete this->data; 00227 00228 // Delete multicast 00229 delete this->multicast; 00230 } 00231 00232 void CModelPush::Init(CSimHandler* sim) 00233 { 00234 this->sim = sim; 00235 00236 // Generate hosts 00237 this->hosts = new CHostClientPush*[this->numHosts]; 00238 00239 for(__uint32 index = 0; index < this->numHosts; index++) 00240 { 00241 this->hosts[index] = new CHostClientPush( 00242 HOST_ID(index), 00243 this->sim, 00244 HOST_ADDR(index), 00245 this, 00246 this->data, 00247 this->bwAccessHostUpLink[index] 00248 ); 00249 } 00250 00251 // Generate server 00252 this->server = new CHostServerPush( 00253 SERVER_ID(0), 00254 this->sim, 00255 SERVER_ADDR(0), 00256 this, 00257 this->data); 00258 00259 // Generate routers 00260 this->routers = new CRouter*[this->topology->Nodes()]; 00261 00262 for(__uint32 index = 0; index < this->topology->Nodes(); index++) 00263 { 00264 this->routers[index] = new CRouter( 00265 ROUTER_ID(this->topology->Node(index)->Id()), 00266 this->sim, 00267 ROUTER_ADDR(index), 00268 this->topology->Node(index)->Degree() + this->routerAccessLinks[index] + ((index == this->gatewayServer)?1:0), 00269 this, 00270 this, 00271 this->mcastRp 00272 ); 00273 } 00274 00275 // Generate core links 00276 this->linksCore = new CLink*[this->topology->Edges()]; 00277 00278 for(__uint32 index = 0; index < this->topology->Edges(); index++) 00279 { 00280 assert(this->topology->Edge(index)->Nodes()[0] < this->topology->Nodes()); 00281 assert(this->topology->Edge(index)->Nodes()[1] < this->topology->Nodes()); 00282 00283 this->linksCore[index] = new CLink( 00284 LINK_CORE_ID(this->topology->Edge(index)->Id()), 00285 this->sim, 00286 this->queueLink, 00287 this->topology->Edge(index)->Bandwidth(), 00288 this->topology->Edge(index)->Bandwidth(), 00289 this->topology->Edge(index)->Delay(), 00290 this->topology->Edge(index)->Delay()); 00291 } 00292 00293 // Generate access links 00294 this->linksAccess = new CLink*[this->numHosts]; 00295 00296 for(__uint32 index = 0; index < this->numHosts; index++) 00297 { 00298 this->linksAccess[index] = new CLink( 00299 LINK_ACCESS_ID(index), 00300 this->sim, 00301 this->queueLink, 00302 this->bwAccessHostUpLink[index], 00303 this->bwAccessHostDownLink[index], 00304 this->delayAccessUpLink, 00305 this->delayAccessDownLink 00306 ); 00307 } 00308 00309 // Generate server link 00310 this->linkServer = new CLink( 00311 LINK_SERVER_ID(0), 00312 this->sim, 00313 this->queueLinkServer, 00314 this->bwServerUpLink, 00315 this->bwServerDownLink, 00316 this->delayServerUpLink, 00317 this->delayServerDownLink 00318 ); 00319 00320 // Generate node-link mappings 00321 // Generate for routers and core links 00322 for(__uint32 index = 0; index < this->topology->Nodes(); index++) 00323 for(__uint32 idx = 0; idx < this->topology->Node(index)->Degree(); idx++) 00324 this->routers[index]->AddLink(this->linksCore[this->topology->Node(index)->Edge(idx)]); 00325 00326 // Generate for hosts, gateway routers and access links 00327 for(__uint32 index = 0; index < this->numHosts; index++) 00328 { 00329 // Add link to the host: entry 0 corresponds to the host (uplink) 00330 this->hosts[index]->AddLink(this->linksAccess[index]); 00331 00332 // Add link to the corresponding gateway: entry 1 corresponds to the router (downlink) 00333 this->routers[this->gateways[index]]->AddLink(this->linksAccess[index]); 00334 } 00335 00336 // Generate for server : add link to server 00337 this->server->AddLink(this->linkServer); 00338 // Generate for server gateway 00339 this->routers[this->gatewayServer]->AddLink(this->linkServer); 00340 00341 // Calculate routes 00342 for(__uint32 node = 0; node < this->routeNodes; node++) 00343 { 00344 // Routes: node to node 00345 for(__uint32 dst = 0; dst < this->routeNodes; dst++) 00346 if(dst == node) this->route[ROUTER_ADDR(node)][ROUTER_ADDR(dst)] = -1; 00347 else this->route[ROUTER_ADDR(node)][ROUTER_ADDR(dst)] = this->routers[node]->LinkIndex(this->linksCore[this->topology->Route()->NextEdge(node, dst)]->Id()); 00348 00349 // Routes: node to host 00350 for(__uint32 host = 0; host < this->numHosts; host++) 00351 { 00352 if(this->gateways[host] == node) 00353 { 00354 // If the node is the gateway of the destination 00355 this->route[ROUTER_ADDR(node)][HOST_ADDR(host)] = this->routers[node]->LinkIndex(this->linksAccess[host]->Id()); 00356 } 00357 else 00358 { 00359 // Else: the route to the gateway 00360 this->route[ROUTER_ADDR(node)][HOST_ADDR(host)] = this->routers[node]->LinkIndex(this->linksCore[this->topology->Route()->NextEdge(node, this->gateways[host])]->Id()); 00361 } 00362 } 00363 00364 // Routes: node to server 00365 if(this->gatewayServer == node) 00366 // If the node is the gateway of the server 00367 this->route[ROUTER_ADDR(node)][SERVER_ADDR(0)] = this->routers[node]->LinkIndex(this->linkServer->Id()); 00368 else 00369 // Else: the route to the server gateway 00370 this->route[ROUTER_ADDR(node)][SERVER_ADDR(0)] = this->routers[node]->LinkIndex(this->linksCore[this->topology->Route()->NextEdge(node, this->gatewayServer)]->Id()); 00371 } 00372 00373 // Multicast 00374 this->multicast = new CMulticast(this->numChannelsMcast, this->topology, this->gatewayServer); 00375 00376 #if DEBUG_TOPOLOGY 00377 // Verify routers 00378 for(__uint32 index = 0; index < this->topology->Nodes(); index++) 00379 { 00380 // Check the links 00381 for(__uint32 idx = 0; idx < this->routers[index]->NumLinks(); idx++) 00382 { 00383 CLink* link = this->routers[index]->Link(idx); 00384 __uint32 entry = this->routers[index]->LinkEntry(idx); 00385 00386 assert(link); 00387 assert(link->Node(entry) == this->routers[index]); 00388 assert(link->NodeEntry(entry) == idx); 00389 } 00390 } 00391 // Verify hosts 00392 for(__uint32 index = 0; index < this->numHosts; index++) 00393 { 00394 CLink* link = this->hosts[index]->Link(); 00395 __uint32 entry = this->hosts[index]->LinkEntry(); 00396 00397 assert(link); 00398 assert(link->Node(entry) == this->hosts[index]); 00399 assert(link->NodeEntry(entry) == 0); 00400 } 00401 // Verify core links 00402 for(__uint32 index = 0; index < this->topology->Edges(); index++) 00403 { 00404 for(__uint32 idx = 0; idx < 2; idx++) 00405 { 00406 CRouter* router = type_cast<CRouter*>(this->linksCore[index]->Node(idx)); 00407 __uint32 entry = this->linksCore[index]->NodeEntry(idx); 00408 00409 assert(router); 00410 assert(router->Link(entry) == this->linksCore[index]); 00411 assert(router->LinkEntry(entry) == idx); 00412 } 00413 } 00414 // Verify access links 00415 for(__uint32 index = 0; index < this->numHosts; index++) 00416 { 00417 CHost* host = type_cast<CHost*>(this->linksAccess[index]->Node(0)); 00418 __uint32 entryHost = this->linksAccess[index]->NodeEntry(0); 00419 CRouter* router = type_cast<CRouter*>(this->linksAccess[index]->Node(1)); 00420 __uint32 entryRouter = this->linksAccess[index]->NodeEntry(1); 00421 00422 assert(host); 00423 assert(host->Link() == this->linksAccess[index]); 00424 assert(host->LinkEntry() == 0); 00425 assert(router); 00426 assert(router->Link(entryRouter) == this->linksAccess[index]); 00427 assert(router->LinkEntry(entryRouter) == 1); 00428 } 00429 // Verify routes 00430 // router-to-router 00431 00432 for(__uint32 src = 0; src < this->routeNodes; src++) 00433 for(__uint32 dst = 0; dst < this->routeNodes; dst++) 00434 { 00435 CNode* node = this->routers[src]; 00436 CLink* link; 00437 __uint32 linkEntry; 00438 int index; 00439 00440 while(node != this->routers[dst]) 00441 { 00442 index = this->route[node->Address().Address()][this->routers[dst]->Address().Address()]; 00443 link = type_cast<CRouter*>(node)->Link(index); 00444 linkEntry = type_cast<CRouter*>(node)->LinkEntry(index); 00445 node = type_cast<CNode*>(link->Node(linkEntry ^ 1)); 00446 } 00447 // Check the destination was reached 00448 assert(node == this->routers[dst]); 00449 } 00450 00451 // router-to-hosts 00452 for(__uint32 src = 0; src < this->routeNodes; src++) 00453 for(__uint32 dst = 0; dst < this->numHosts; dst++) 00454 { 00455 CNode* node = this->routers[src]; 00456 CLink* link; 00457 __uint32 linkEntry; 00458 int index; 00459 00460 while(node != this->hosts[dst]) 00461 { 00462 index = this->route[node->Address().Address()][this->hosts[dst]->Address().Address()]; 00463 link = type_cast<CRouter*>(node)->Link(index); 00464 linkEntry = type_cast<CRouter*>(node)->LinkEntry(index); 00465 node = type_cast<CNode*>(link->Node(linkEntry ^ 1)); 00466 } 00467 // Check the destination was reached 00468 assert(node == this->hosts[dst]); 00469 } 00470 #endif 00471 } 00472 00473 __uint32 CModelPush::Events() 00474 { 00475 return 1 + this->numHosts; 00476 } 00477 00478 CSimEvent* CModelPush::Event(__uint32 index, __time& time) 00479 { 00480 switch(index) 00481 { 00482 case 0: // Server init event 00483 time = 0; 00484 return new CEventServerStart(this->server); 00485 default: // Peer arrive 00486 time = 0; 00487 return new CEventClientArrive(this->hosts[index-1]); 00488 } 00489 } 00490 00491 void CModelPush::Finalize() 00492 { 00493 FILE* out; 00494 char fileName[1024]; 00495 00496 /* 00497 * Simple statistics 00498 */ 00499 00500 // Calculate data 00501 00502 // Data : bandwidth 00503 this->dataBwTotal = 0; 00504 00505 // Data : bandwidth core 00506 this->dataBwCoreTotal = 0; 00507 00508 // Data : bandwidth access 00509 this->dataBwAccessTotal = 0; 00510 00511 // Data : bandwidth access uplink 00512 this->dataBwAccessUpTotal = 0; 00513 00514 // Data : bandwidth access downlink 00515 this->dataBwAccessDownTotal = 0; 00516 00517 // Data : bandwidth server 00518 this->dataBwServerTotal = 0; 00519 00520 // Data : bandwidth stream 00521 this->dataBwStreamTotal = 0; 00522 00523 // Data : bandwidth core stream 00524 this->dataBwCoreStreamTotal = 0; 00525 00526 // Data : bandwidth access stream 00527 this->dataBwAccessStreamTotal = 0; 00528 00529 // Data : bandwidth access uplink stream 00530 this->dataBwAccessUpStreamTotal = 0; 00531 00532 // Data : bandwidth access downlink stream 00533 this->dataBwAccessDownStreamTotal = 0; 00534 00535 // Data : bandwidth server stream 00536 this->dataBwServerStreamTotal = 0; 00537 00538 // Data : bandwidth control 00539 this->dataBwControlTotal = 0; 00540 00541 // Data : bandwidth core control 00542 this->dataBwCoreControlTotal = 0; 00543 00544 // Data : bandwidth access control 00545 this->dataBwAccessControlTotal = 0; 00546 00547 // Data : bandwidth access uplink control 00548 this->dataBwAccessUpControlTotal = 0; 00549 00550 // Data : bandwidth access downlink control 00551 this->dataBwAccessDownControlTotal = 0; 00552 00553 // Data : bandwidth server control 00554 this->dataBwServerControlTotal = 0; 00555 00556 // Data : multicast entries 00557 this->dataRouterMcastEntries = 0; 00558 this->dataRouterMcastEntriesIgmp = 0; 00559 this->dataRouterMcastEntriesPimSm = 0; 00560 00561 // Server link 00562 this->dataBwTotal += this->linkServer->StatBits(0,0) + this->linkServer->StatBits(0,1) + this->linkServer->StatBits(1,0) + this->linkServer->StatBits(1,1); 00563 this->dataBwServerTotal += this->linkServer->StatBits(0,0) + this->linkServer->StatBits(0,1) + this->linkServer->StatBits(1,0) + this->linkServer->StatBits(1,1); 00564 this->dataBwStreamTotal += this->linkServer->StatBits(1,0) + this->linkServer->StatBits(1,1); 00565 this->dataBwServerStreamTotal += this->linkServer->StatBits(1,0) + this->linkServer->StatBits(1,1); 00566 this->dataBwServerControlTotal += this->linkServer->StatBits(0,0) + this->linkServer->StatBits(0,1); 00567 00568 // Core links 00569 for(__uint32 index = 0; index < this->topology->Edges(); index++) 00570 { 00571 this->dataBwTotal += this->linksCore[index]->StatBits(0,0) + this->linksCore[index]->StatBits(0,1) + this->linksCore[index]->StatBits(1,0) + this->linksCore[index]->StatBits(1,1); 00572 this->dataBwCoreTotal += this->linksCore[index]->StatBits(0,0) + this->linksCore[index]->StatBits(0,1) + this->linksCore[index]->StatBits(1,0) + this->linksCore[index]->StatBits(1,1); 00573 this->dataBwStreamTotal += this->linksCore[index]->StatBits(1,0) + this->linksCore[index]->StatBits(1,1); 00574 this->dataBwCoreStreamTotal += this->linksCore[index]->StatBits(1,0) + this->linksCore[index]->StatBits(1,1); 00575 this->dataBwControlTotal += this->linksCore[index]->StatBits(0,0) + this->linksCore[index]->StatBits(0,1); 00576 this->dataBwCoreControlTotal += this->linksCore[index]->StatBits(0,0) + this->linksCore[index]->StatBits(0,1); 00577 } 00578 00579 // Access links 00580 for(__uint32 index = 0; index < this->numHosts; index++) 00581 { 00582 this->dataBwTotal += this->linksAccess[index]->StatBits(0,0) + this->linksAccess[index]->StatBits(0,1) + this->linksAccess[index]->StatBits(1,0) + this->linksAccess[index]->StatBits(1,1); 00583 this->dataBwAccessTotal += this->linksAccess[index]->StatBits(0,0) + this->linksAccess[index]->StatBits(0,1) + this->linksAccess[index]->StatBits(1,0) + this->linksAccess[index]->StatBits(1,1); 00584 this->dataBwAccessUpTotal += this->linksAccess[index]->StatBits(0,0) + this->linksAccess[index]->StatBits(1,0); 00585 this->dataBwAccessDownTotal += this->linksAccess[index]->StatBits(0,1) + this->linksAccess[index]->StatBits(1,1); 00586 this->dataBwStreamTotal += this->linksAccess[index]->StatBits(1,0) + this->linksAccess[index]->StatBits(1,1); 00587 this->dataBwAccessStreamTotal += this->linksAccess[index]->StatBits(1,0) + this->linksAccess[index]->StatBits(1,1); 00588 this->dataBwAccessUpStreamTotal += this->linksAccess[index]->StatBits(1,0); 00589 this->dataBwAccessDownStreamTotal += this->linksAccess[index]->StatBits(1,1); 00590 this->dataBwControlTotal += this->linksAccess[index]->StatBits(0,0) + this->linksAccess[index]->StatBits(0,1); 00591 this->dataBwAccessControlTotal += this->linksAccess[index]->StatBits(0,0) + this->linksAccess[index]->StatBits(0,1); 00592 this->dataBwAccessUpControlTotal += this->linksAccess[index]->StatBits(0,0); 00593 this->dataBwAccessDownControlTotal += this->linksAccess[index]->StatBits(0,1); 00594 } 00595 00596 this->dataBwAvg = this->dataBwTotal/this->maxTime; 00597 this->dataBwCoreAvg = this->dataBwCoreTotal/this->maxTime; 00598 this->dataBwAccessAvg = this->dataBwAccessTotal/this->maxTime; 00599 this->dataBwAccessUpAvg = this->dataBwAccessUpTotal/this->maxTime; 00600 this->dataBwAccessDownAvg = this->dataBwAccessDownTotal/this->maxTime; 00601 this->dataBwServerAvg = this->dataBwServerTotal/this->maxTime; 00602 this->dataBwStreamAvg = this->dataBwStreamTotal/this->maxTime; 00603 this->dataBwCoreStreamAvg = this->dataBwCoreStreamTotal/this->maxTime; 00604 this->dataBwAccessStreamAvg = this->dataBwAccessStreamTotal/this->maxTime; 00605 this->dataBwAccessUpStreamAvg = this->dataBwAccessUpStreamTotal/this->maxTime; 00606 this->dataBwAccessDownStreamAvg = this->dataBwAccessDownStreamTotal/this->maxTime; 00607 this->dataBwServerStreamAvg = this->dataBwServerStreamTotal/this->maxTime; 00608 this->dataBwControlAvg = this->dataBwControlTotal/this->maxTime; 00609 this->dataBwCoreControlAvg = this->dataBwCoreControlTotal/this->maxTime; 00610 this->dataBwAccessControlAvg = this->dataBwAccessControlTotal/this->maxTime; 00611 this->dataBwAccessUpControlAvg = this->dataBwAccessUpControlTotal/this->maxTime; 00612 this->dataBwAccessDownControlAvg = this->dataBwAccessDownControlTotal/this->maxTime; 00613 this->dataBwServerControlAvg = this->dataBwServerControlTotal/this->maxTime; 00614 00615 // Routers 00616 for(__uint32 index = 0; index < this->topology->Nodes(); index++) 00617 { 00618 this->routers[index]->Finalize(); 00619 this->dataRouterMcastEntries += (this->routers[index]->StatMcastEntriesIgmp() + this->routers[index]->StatMcastEntriesPimSm()); 00620 this->dataRouterMcastEntriesIgmp += this->routers[index]->StatMcastEntriesIgmp(); 00621 this->dataRouterMcastEntriesPimSm += this->routers[index]->StatMcastEntriesPimSm(); 00622 } 00623 00624 // Global file 00625 sprintf(fileName, "network_%s_%u.out", this->name, this->topologyNumber); 00626 if(FILE_OPEN(out, fileName, "a")) printf("\nCannot write to file %s.", fileName); 00627 else 00628 { 00629 fprintf(out, "%u %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %llu %.9lf %.9lf %.9lf %.9lf\n", 00630 this->numChannelsMcast, // 1 00631 this->dataBwTotal, // 2 00632 this->dataBwAvg, // 3 00633 this->dataBwCoreTotal, // 4 00634 this->dataBwCoreAvg, // 5 00635 this->dataBwAccessTotal, // 6 00636 this->dataBwAccessAvg, // 7 00637 this->dataBwAccessUpTotal, // 8 00638 this->dataBwAccessUpAvg, // 9 00639 this->dataBwAccessDownTotal, // 10 00640 this->dataBwAccessDownAvg, // 11 00641 this->dataBwServerTotal, // 12 00642 this->dataBwServerAvg, // 13 00643 this->dataBwStreamTotal, // 14 00644 this->dataBwStreamAvg, // 15 00645 this->dataBwCoreStreamTotal, // 16 00646 this->dataBwCoreStreamAvg, // 17 00647 this->dataBwAccessStreamTotal, // 18 00648 this->dataBwAccessStreamAvg, // 19 00649 this->dataBwAccessUpStreamTotal, // 20 00650 this->dataBwAccessUpStreamAvg, // 21 00651 this->dataBwAccessDownStreamTotal, // 22 00652 this->dataBwAccessDownStreamAvg, // 23 00653 this->dataBwServerStreamTotal, // 24 00654 this->dataBwServerStreamAvg, // 25 00655 this->dataBwControlTotal, // 26 00656 this->dataBwControlAvg, // 27 00657 this->dataBwCoreControlTotal, // 28 00658 this->dataBwCoreControlAvg, // 29 00659 this->dataBwAccessControlTotal, // 30 00660 this->dataBwAccessControlAvg, // 31 00661 this->dataBwAccessUpControlTotal, // 32 00662 this->dataBwAccessUpControlAvg, // 33 00663 this->dataBwAccessDownControlTotal, // 34 00664 this->dataBwAccessDownControlAvg, // 35 00665 this->dataBwServerControlTotal, // 36 00666 this->dataBwServerControlAvg, // 37 00667 this->dataRouterMcastEntries, // 38 00668 this->dataRouterMcastEntriesIgmp, // 39 00669 this->dataRouterMcastEntriesPimSm // 40 00670 ); 00671 00672 fclose(out); 00673 } 00674 00675 #ifdef STAT_VERBOSE 00676 00677 /* 00678 * Advanced statistics 00679 */ 00680 00681 // Statistics file in user form 00682 00683 sprintf(fileName, "stat_%s_%u_%u.stat", this->name, this->topologyNumber, this->numChannelsMcast); 00684 if(FILE_OPEN(out, fileName, "w")) printf("\nCannot write to file %s.", fileName); 00685 else 00686 { 00687 // Save host statistics 00688 fprintf(out, "\n\nHosts\n"); 00689 fprintf(out, "\nHost Gw Read Write"); 00690 fprintf(out, "\n======================================================================="); 00691 00692 fprintf(out, "\nSERVER %3u %10llu %10llu", 00693 this->gatewayServer, 00694 this->server->StatPacketsRead(), 00695 this->server->StatPacketsWrite()); 00696 00697 for(__uint32 index = 0; index < this->numHosts; index++) 00698 { 00699 fprintf(out, "\nHOST %3u %3u %10llu %10llu", 00700 index, 00701 this->gateways[index], 00702 this->hosts[index]->StatPacketsRead(), 00703 this->hosts[index]->StatPacketsWrite() 00704 ); 00705 } 00706 00707 // Save router statistics 00708 fprintf(out, "\n\nRouters\n"); 00709 fprintf(out, "\nRouter Read Write Entr IGMP Entr PIMSM "); 00710 fprintf(out, "\n============================================================="); 00711 00712 for(__uint32 index = 0; index < this->topology->Nodes(); index++) 00713 { 00714 fprintf(out, "\nROUTER %3u %10llu %10llu %10.5lf %10.5lf", 00715 index, 00716 this->routers[index]->StatPacketsRead(), 00717 this->routers[index]->StatPacketsWrite(), 00718 this->routers[index]->StatMcastEntriesIgmp(), 00719 this->routers[index]->StatMcastEntriesPimSm() 00720 ); 00721 } 00722 00723 00724 // Save link statistics : server 00725 fprintf(out, "\n\nServer link (00-hi/up 01-hi/down 10-low/up 11-low/down)\n"); 00726 fprintf(out, "\nLink Bw0 Bw1 Util00 Util01 Util10 Util11 Pack00 Disc00 Pack01 Disc01 Pack10 Disc10 Pack11 Disc11 Bits00 Bits01 Bits10 Bits11 Que00 Que01 Que10 Que11"); 00727 fprintf(out, "\n========================================================================================================================================================================"); 00728 00729 this->linkServer->Finalize(); 00730 fprintf(out, "\n%3u %10.0lf %10.0lf : %6.4lf %6.4lf %6.4lf %6.4lf %6llu %6llu %6llu %6llu %6llu %6llu %6llu %6llu %6llu %6llu %6llu %6llu %6.2lf %6.2lf %6.2lf %6.2lf ", 00731 0, 00732 this->linkServer->Bandwidth(0), 00733 this->linkServer->Bandwidth(1), 00734 this->linkServer->StatUtilization(0, 0), 00735 this->linkServer->StatUtilization(0, 1), 00736 this->linkServer->StatUtilization(1, 0), 00737 this->linkServer->StatUtilization(1, 1), 00738 this->linkServer->StatPackets(0, 0), 00739 this->linkServer->StatDiscard(0, 0), 00740 this->linkServer->StatPackets(0, 1), 00741 this->linkServer->StatDiscard(0, 1), 00742 this->linkServer->StatPackets(1, 0), 00743 this->linkServer->StatDiscard(1, 0), 00744 this->linkServer->StatPackets(1, 1), 00745 this->linkServer->StatDiscard(1, 1), 00746 this->linkServer->StatBits(0, 0), 00747 this->linkServer->StatBits(0, 1), 00748 this->linkServer->StatBits(1, 0), 00749 this->linkServer->StatBits(1, 1), 00750 this->linkServer->StatQueue(0, 0), 00751 this->linkServer->StatQueue(0, 1), 00752 this->linkServer->StatQueue(1, 0), 00753 this->linkServer->StatQueue(1, 1) 00754 ); 00755 00756 00757 // Save link statistics : access 00758 fprintf(out, "\n\nAccess links (00-hi/up 01-hi/down 10-low/up 11-low/down)\n"); 00759 fprintf(out, "\nLink Bw0 Bw1 Util00 Util01 Util10 Util11 Pack00 Disc00 Pack01 Disc01 Pack10 Disc10 Pack11 Disc11 Bits00 Bits01 Bits10 Bits11 Que00 Que01 Que10 Que11"); 00760 fprintf(out, "\n========================================================================================================================================================================"); 00761 for(__uint32 index = 0; index < this->numHosts; index++) 00762 { 00763 this->linksAccess[index]->Finalize(); 00764 fprintf(out, "\n%3u %10.0lf %10.0lf : %6.4lf %6.4lf %6.4lf %6.4lf %6llu %6llu %6llu %6llu %6llu %6llu %6llu %6llu %6llu %6llu %6llu %6llu %6.2lf %6.2lf %6.2lf %6.2lf ", 00765 index, 00766 this->linksAccess[index]->Bandwidth(0), 00767 this->linksAccess[index]->Bandwidth(1), 00768 this->linksAccess[index]->StatUtilization(0, 0), 00769 this->linksAccess[index]->StatUtilization(0, 1), 00770 this->linksAccess[index]->StatUtilization(1, 0), 00771 this->linksAccess[index]->StatUtilization(1, 1), 00772 this->linksAccess[index]->StatPackets(0, 0), 00773 this->linksAccess[index]->StatDiscard(0, 0), 00774 this->linksAccess[index]->StatPackets(0, 1), 00775 this->linksAccess[index]->StatDiscard(0, 1), 00776 this->linksAccess[index]->StatPackets(1, 0), 00777 this->linksAccess[index]->StatDiscard(1, 0), 00778 this->linksAccess[index]->StatPackets(1, 1), 00779 this->linksAccess[index]->StatDiscard(1, 1), 00780 this->linksAccess[index]->StatBits(0, 0), 00781 this->linksAccess[index]->StatBits(0, 1), 00782 this->linksAccess[index]->StatBits(1, 0), 00783 this->linksAccess[index]->StatBits(1, 1), 00784 this->linksAccess[index]->StatQueue(0, 0), 00785 this->linksAccess[index]->StatQueue(0, 1), 00786 this->linksAccess[index]->StatQueue(1, 0), 00787 this->linksAccess[index]->StatQueue(1, 1) 00788 ); 00789 } 00790 00791 // Save link statistics : core 00792 fprintf(out, "\n\nCore links (00-hi/up 01-hi/down 10-low/up 11-low/down)\n"); 00793 fprintf(out, "\nLink Bw0 Bw1 Util00 Util01 Util10 Util11 Pack00 Disc00 Pack01 Disc01 Pack10 Disc10 Pack11 Disc11 Bits00 Bits01 Bits10 Bits11 Que00 Que01 Que10 Que11"); 00794 fprintf(out, "\n========================================================================================================================================================================"); 00795 for(__uint32 index = 0; index < this->topology->Edges(); index++) 00796 { 00797 this->linksCore[index]->Finalize(); 00798 fprintf(out, "\n%3u %10.0lf %10.0lf : %6.4lf %6.4lf %6.4lf %6.4lf %6llu %6llu %6llu %6llu %6llu %6llu %6llu %6llu %6llu %6llu %6llu %6llu %6.2lf %6.2lf %6.2lf %6.2lf ", 00799 index, 00800 this->linksCore[index]->Bandwidth(0), 00801 this->linksCore[index]->Bandwidth(1), 00802 this->linksCore[index]->StatUtilization(0, 0), 00803 this->linksCore[index]->StatUtilization(0, 1), 00804 this->linksCore[index]->StatUtilization(1, 0), 00805 this->linksCore[index]->StatUtilization(1, 1), 00806 this->linksCore[index]->StatPackets(0, 0), 00807 this->linksCore[index]->StatDiscard(0, 0), 00808 this->linksCore[index]->StatPackets(0, 1), 00809 this->linksCore[index]->StatDiscard(0, 1), 00810 this->linksCore[index]->StatPackets(1, 0), 00811 this->linksCore[index]->StatDiscard(1, 0), 00812 this->linksCore[index]->StatPackets(1, 1), 00813 this->linksCore[index]->StatDiscard(1, 1), 00814 this->linksCore[index]->StatBits(0, 0), 00815 this->linksCore[index]->StatBits(0, 1), 00816 this->linksCore[index]->StatBits(1, 0), 00817 this->linksCore[index]->StatBits(1, 1), 00818 this->linksCore[index]->StatQueue(0, 0), 00819 this->linksCore[index]->StatQueue(0, 1), 00820 this->linksCore[index]->StatQueue(1, 0), 00821 this->linksCore[index]->StatQueue(1, 1) 00822 ); 00823 } 00824 fclose(out); 00825 } 00826 00827 // Statistics file in computer form 00828 00829 // Hosts 00830 00831 sprintf(fileName, "hosts_%s_%u_%u.stat", this->name, this->topologyNumber, this->numChannelsMcast); 00832 if(FILE_OPEN(out, fileName, "w")) printf("\nCannot write to file %s.", fileName); 00833 else 00834 { 00835 // Save host statistics 00836 fprintf(out, "0 %u %llu %llu\n", 00837 this->gatewayServer, 00838 this->server->StatPacketsRead(), 00839 this->server->StatPacketsWrite()); 00840 00841 for(__uint32 index = 0; index < this->numHosts; index++) 00842 { 00843 fprintf(out, "%u %u %llu %llu\n", 00844 index, 00845 this->gateways[index], 00846 this->hosts[index]->StatPacketsRead(), 00847 this->hosts[index]->StatPacketsWrite() 00848 ); 00849 } 00850 00851 fclose(out); 00852 } 00853 // Routers 00854 00855 sprintf(fileName, "routers_%s_%u_%u.stat", this->name, this->topologyNumber, this->numChannelsMcast); 00856 if(FILE_OPEN(out, fileName, "w")) printf("\nCannot write to file %s.", fileName); 00857 else 00858 { 00859 for(__uint32 index = 0; index < this->topology->Nodes(); index++) 00860 { 00861 fprintf(out, "%u %llu %llu %.9lf %.9lf\n", 00862 index, 00863 this->routers[index]->StatPacketsRead(), 00864 this->routers[index]->StatPacketsWrite(), 00865 this->routers[index]->StatMcastEntriesIgmp(), 00866 this->routers[index]->StatMcastEntriesPimSm() 00867 ); 00868 } 00869 00870 fclose(out); 00871 } 00872 // Server link 00873 00874 sprintf(fileName, "slink_%s_%u_%u.stat", this->name, this->topologyNumber, this->numChannelsMcast); 00875 if(FILE_OPEN(out, fileName, "w")) printf("\nCannot write to file %s.", fileName); 00876 else 00877 { 00878 fprintf(out, "%u %.0lf %.0lf %.9lf %.9lf %.9lf %.9lf %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %.9lf %.9lf %.9lf %.9lf\n", 00879 0, 00880 this->linkServer->Bandwidth(0), 00881 this->linkServer->Bandwidth(1), 00882 this->linkServer->StatUtilization(0, 0), 00883 this->linkServer->StatUtilization(0, 1), 00884 this->linkServer->StatUtilization(1, 0), 00885 this->linkServer->StatUtilization(1, 1), 00886 this->linkServer->StatPackets(0, 0), 00887 this->linkServer->StatDiscard(0, 0), 00888 this->linkServer->StatPackets(0, 1), 00889 this->linkServer->StatDiscard(0, 1), 00890 this->linkServer->StatPackets(1, 0), 00891 this->linkServer->StatDiscard(1, 0), 00892 this->linkServer->StatPackets(1, 1), 00893 this->linkServer->StatDiscard(1, 1), 00894 this->linkServer->StatBits(0, 0), 00895 this->linkServer->StatBits(0, 1), 00896 this->linkServer->StatBits(1, 0), 00897 this->linkServer->StatBits(1, 1), 00898 this->linkServer->StatQueue(0, 0), 00899 this->linkServer->StatQueue(0, 1), 00900 this->linkServer->StatQueue(1, 0), 00901 this->linkServer->StatQueue(1, 1) 00902 ); 00903 00904 fclose(out); 00905 } 00906 // Access links 00907 00908 sprintf(fileName, "alink_%s_%u_%u.stat", this->name, this->topologyNumber, this->numChannelsMcast); 00909 if(FILE_OPEN(out, fileName, "w")) printf("\nCannot write to file %s.", fileName); 00910 else 00911 { 00912 for(__uint32 index = 0; index < this->numHosts; index++) 00913 { 00914 fprintf(out, "%u %.0lf %.0lf %.9lf %.9lf %.9lf %.9lf %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %.9lf %.9lf %.9lf %.9lf\n", 00915 index, 00916 this->linksAccess[index]->Bandwidth(0), 00917 this->linksAccess[index]->Bandwidth(1), 00918 this->linksAccess[index]->StatUtilization(0, 0), 00919 this->linksAccess[index]->StatUtilization(0, 1), 00920 this->linksAccess[index]->StatUtilization(1, 0), 00921 this->linksAccess[index]->StatUtilization(1, 1), 00922 this->linksAccess[index]->StatPackets(0, 0), 00923 this->linksAccess[index]->StatDiscard(0, 0), 00924 this->linksAccess[index]->StatPackets(0, 1), 00925 this->linksAccess[index]->StatDiscard(0, 1), 00926 this->linksAccess[index]->StatPackets(1, 0), 00927 this->linksAccess[index]->StatDiscard(1, 0), 00928 this->linksAccess[index]->StatPackets(1, 1), 00929 this->linksAccess[index]->StatDiscard(1, 1), 00930 this->linksAccess[index]->StatBits(0, 0), 00931 this->linksAccess[index]->StatBits(0, 1), 00932 this->linksAccess[index]->StatBits(1, 0), 00933 this->linksAccess[index]->StatBits(1, 1), 00934 this->linksAccess[index]->StatQueue(0, 0), 00935 this->linksAccess[index]->StatQueue(0, 1), 00936 this->linksAccess[index]->StatQueue(1, 0), 00937 this->linksAccess[index]->StatQueue(1, 1) 00938 ); 00939 } 00940 00941 fclose(out); 00942 } 00943 00944 // Core links 00945 00946 sprintf(fileName, "clink_%s_%u_%u.stat", this->name, this->topologyNumber, this->numChannelsMcast); 00947 if(FILE_OPEN(out, fileName, "w")) printf("\nCannot write to file %s.", fileName); 00948 else 00949 { 00950 for(__uint32 index = 0; index < this->topology->Edges(); index++) 00951 { 00952 fprintf(out, "%u %.0lf %.0lf %.9lf %.9lf %.9lf %.9lf %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %.9lf %.9lf %.9lf %.9lf\n", 00953 index, 00954 this->linksCore[index]->Bandwidth(0), 00955 this->linksCore[index]->Bandwidth(1), 00956 this->linksCore[index]->StatUtilization(0, 0), 00957 this->linksCore[index]->StatUtilization(0, 1), 00958 this->linksCore[index]->StatUtilization(1, 0), 00959 this->linksCore[index]->StatUtilization(1, 1), 00960 this->linksCore[index]->StatPackets(0, 0), 00961 this->linksCore[index]->StatDiscard(0, 0), 00962 this->linksCore[index]->StatPackets(0, 1), 00963 this->linksCore[index]->StatDiscard(0, 1), 00964 this->linksCore[index]->StatPackets(1, 0), 00965 this->linksCore[index]->StatDiscard(1, 0), 00966 this->linksCore[index]->StatPackets(1, 1), 00967 this->linksCore[index]->StatDiscard(1, 1), 00968 this->linksCore[index]->StatBits(0, 0), 00969 this->linksCore[index]->StatBits(0, 1), 00970 this->linksCore[index]->StatBits(1, 0), 00971 this->linksCore[index]->StatBits(1, 1), 00972 this->linksCore[index]->StatQueue(0, 0), 00973 this->linksCore[index]->StatQueue(0, 1), 00974 this->linksCore[index]->StatQueue(1, 0), 00975 this->linksCore[index]->StatQueue(1, 1) 00976 ); 00977 } 00978 00979 fclose(out); 00980 } 00981 00982 #ifdef MULTICAST 00983 // Multicast statistics 00984 sprintf(fileName, "multicast_%s_%u.out", this->name, this->topologyNumber); 00985 if(FILE_OPEN(out, fileName, "w")) printf("\nCannot write to file %s.", fileName); 00986 else 00987 { 00988 for(__uint32 index = 0; index < this->multicast->Groups(); index++) 00989 { 00990 (*this->multicast)[index]->Finalize(this->sim->Time()); 00991 00992 fprintf(out, "%u %.9lf %.9lf\n", index, (*this->multicast)[index]->SizeCore(), (*this->multicast)[index]->SizeEdge()); 00993 } 00994 fclose(out); 00995 } 00996 #endif 00997 00998 #endif 00999 01000 /* 01001 * Cleanup objects created during simulation (objects that cannot be deleted in the destructor because they depend on the simulator) 01002 */ 01003 01004 // Delete hosts 01005 if(this->hosts) 01006 { 01007 for(__uint32 index = 0; index < this->numHosts; index++) 01008 delete this->hosts[index]; 01009 delete[] this->hosts; 01010 } 01011 01012 // Delete routers 01013 if(this->routers) 01014 { 01015 for(__uint32 index = 0; index < this->topology->Nodes(); index++) 01016 delete this->routers[index]; 01017 delete[] this->routers; 01018 } 01019 01020 // Delete server 01021 if(this->server) delete this->server; 01022 01023 // Delete links core 01024 if(this->linksCore) 01025 { 01026 for(__uint32 index = 0; index < this->topology->Edges(); index++) 01027 delete this->linksCore[index]; 01028 delete[] this->linksCore; 01029 } 01030 01031 // Delete links access 01032 if(this->linksAccess) 01033 { 01034 for(__uint32 index = 0; index < this->numHosts; index++) 01035 delete this->linksAccess[index]; 01036 delete[] this->linksAccess; 01037 } 01038 01039 // Delete link server 01040 if(this->linkServer) delete this->linkServer; 01041 } 01042 01043 int CModelPush::Forward(CAddress node, CAddress dst) 01044 { 01045 // Calculates the outgoing link when the router receives a packet with a certain destination 01046 assert(node.Address() <= this->routeNodes); 01047 assert(dst.Address() <= this->routeDst); 01048 01049 return this->route[node.Address()][dst.Address()]; 01050 } 01051 01052 CChannel* CModelPush::Channel(__uint32 index) 01053 { 01054 assert(index < this->numChannelsMcast + this->numChannelsUcast); 01055 01056 return (index < this->numChannelsMcast)?&this->channelsMcast[index]:&this->channelsUcast[index - this->numChannelsMcast]; 01057 } 01058 01059 #ifdef MULTICAST 01060 01061 void CModelPush::MulticastJoin(__uint32 host, __uint32 group) 01062 { 01063 // Add host to multicast group 01064 (*this->multicast)[group]->Add(this->sim->Time(), HOST_INDEX(host), this->gateways[HOST_INDEX(host)]); 01065 } 01066 01067 void CModelPush::MulticastLeave(__uint32 host, __uint32 group) 01068 { 01069 // Remove host from multicast group 01070 (*this->multicast)[group]->Remove(this->sim->Time(), HOST_INDEX(host), this->gateways[HOST_INDEX(host)]); 01071 } 01072 01073 #endif
Last updated: February 8, 2011