Lab Exercices OPNET Modeler
Lab Exercices OPNET Modeler
This thesis is presented as a part of the Master of Science Degree in Electrical Engineering with emphasis on Telecommunications and Signal Processing. Blekinge Institute of Technology June 2003
Master of Science Programme in Electrical Engineering Blekinge Institute of Technology Department of Telecommunications and Signal Processing I.T.S Supervisor: Prof: Arne Nilsson and Docent: Adrian Popescu I.T.S Examiner: Prof: Arne Nilsson and Docent: Adrian Popescu I.T.S
Abstract
The primary purpose of this thesis is to develop laboratory exercises for use with several courses at the Blekinge Institute of Technology and to offer an insight in how real networks and protocols behave. All laboratories are developed in OPNET Modeler 9.0 simulation environment which is a network simulator that offers the tools for model design, simulation, data mining and analysis. The software package is licensed by OPNET technologies Inc [1]. The instructional material consists of a set of laboratory exercises, namely: Introduction to OPNET Modeler 9.0 environment, M/M/1, Aloha, CSMA, CSMA-CD, Slow Start, Congestion Avoidance, Fast Retransmit, Fast Recovery and OSPF, Queuing policies , Selfsimilar.
Keywords: OPNET Modeler, Lab, M/M/1, Aloha, CSMA, CSMA-CD, Slow Start, Congestion Avoidance, Fast Retransmit, Fast Recovery, OSPF, Areas, Balanced traffic flow, Ethernet, FIFO, Preemptive priority queuing, Non preemptive queuing, WFQ, Selfsimilar.
Table of contents
Abstract ...........................................................................................................................................................2 Introduction .....................................................................................................................................................6 General ........................................................................................................................................................6 Purpose ........................................................................................................................................................6 Laboratory 1 ....................................................................................................................................................7 Introduction to Opnet ......................................................................................................................................7 Objective .....................................................................................................................................................7 Overview .....................................................................................................................................................7 Preparations .................................................................................................................................................8 Project Editor...........................................................................................................................................9 The Process Model Editor .....................................................................................................................11 The Link Model Editor ..........................................................................................................................12 The Path Editor......................................................................................................................................13 The Packet Format Editor......................................................................................................................14 The Probe Editor....................................................................................................................................15 The Simulation Sequence Editor ...........................................................................................................16 The Analysis Tool .................................................................................................................................17 The Project Editor Workspace...............................................................................................................18 Begin the laboratory ..................................................................................................................................20 Laboratory 2 ..................................................................................................................................................41 M/M/1 Queue simulation ..............................................................................................................................41 Objective ...................................................................................................................................................41 Overview ...................................................................................................................................................41 Procedure...................................................................................................................................................42 Creation of the node model ...................................................................................................................43 Laboratory 3 ..................................................................................................................................................62 Ethernet simulation........................................................................................................................................62 Objective ...................................................................................................................................................62 Overview ...................................................................................................................................................62 Procedure...................................................................................................................................................63 Designing the Aloha Transmitter Process Model ......................................................................................63 Creating the Aloha Transmitter Node Model ............................................................................................70 Creating the Generic Receiver Node Process Model.................................................................................73 Creating the Generic Receiver Node Model..............................................................................................77 Creating a new link model.........................................................................................................................79 Creating the network model ......................................................................................................................80 Executing the Aloha Simulation................................................................................................................83 Creating the CSMA transmitter process model .........................................................................................87 Creating the CSMA transmitter node model .............................................................................................89 Redefining the network model ..................................................................................................................91 Configuring CSMA Simulations ...............................................................................................................92 Analyzing the CSMA results.....................................................................................................................93 Viewing Both Results on the Same Graph ................................................................................................94 Ethernet network model.............................................................................................................................97 Laboratory 4 ................................................................................................................................................104 TCP simulation............................................................................................................................................104 Objective .................................................................................................................................................104 Overview .................................................................................................................................................104 Procedure.................................................................................................................................................104 Slow start and congestion avoidance ...................................................................................................104 Slow start and congestion avoidance simulation .................................................................................106 Create the network...............................................................................................................................107 Create the Paris subnet ........................................................................................................................110 Tommy Svensson Alex Popescu 3
Master thesis MEE 03:24 Create the Stockholm subnet ...............................................................................................................112 Create the IP Cloud..............................................................................................................................114 Choose Statistics..................................................................................................................................115 Slow start and Congestion avoidance simulation ................................................................................117 View the results ...................................................................................................................................117 Fast retransmit .....................................................................................................................................118 Fast recovery .......................................................................................................................................118 Fast Retransmit and Fast Recovery simulation....................................................................................119 Create the Tahoe scenario....................................................................................................................119 Create the Reno scenario .....................................................................................................................119 Simulate the scenarios .........................................................................................................................120 View results .........................................................................................................................................120 Laboratory 5 ................................................................................................................................................123 OSPF simulation..........................................................................................................................................123 Objective .................................................................................................................................................123 Overview .................................................................................................................................................123 Procedure.................................................................................................................................................123 Create the network...............................................................................................................................124 Configure router interfaces ..................................................................................................................126 Assign addresses to the router interfaces.............................................................................................128 Configure routing cost .........................................................................................................................129 Configure the traffic demands .............................................................................................................132 Configure Simulation ..........................................................................................................................132 Duplicate the scenario .........................................................................................................................132 Run the simulation...............................................................................................................................134 View the results ...................................................................................................................................135 Laboratory 6 ................................................................................................................................................139 Queuing policies..........................................................................................................................................139 Objective .................................................................................................................................................139 Overview .................................................................................................................................................139 Procedure.................................................................................................................................................139 Copy files ............................................................................................................................................140 FIFO queuing.......................................................................................................................................141 Create the FIFO network .....................................................................................................................142 Duplicate scenario ...............................................................................................................................145 Collect statistics...................................................................................................................................146 Run the simulation...............................................................................................................................147 View the results ...................................................................................................................................148 Priority queuing ...................................................................................................................................152 Create the Non-preemptive priority network, infinite buffer...............................................................152 Create the Preemptive priority network, infinite buffer.......................................................................156 Run the infinite buffer simulation........................................................................................................157 View the infinite buffer simulation results ..........................................................................................158 Create the Preemptive priority network, Finite buffer.........................................................................163 Create the Preemptive priority network, Finite buffer.........................................................................163 Run the finite buffer simulation...........................................................................................................164 View the finite buffer simulation results .............................................................................................164 Weighted Fair Queuing .......................................................................................................................169 Create the Weighted Fair Queuing infinite buffer network ..............................................................169 Run the Weighted Fair Queuing infinite buffer simulation ..............................................................173 View the Weighted Fair Queuing infinite buffer results...................................................................173 Create the Weighted Fair Queuing finite buffer network .................................................................175 Run the Weighted Fair Queuing finite buffer simulation .................................................................176 View the Weighted Fair Queuing finite buffer results......................................................................176 Laboratory 7 ................................................................................................................................................178 Self-Similar .................................................................................................................................................178 Tommy Svensson Alex Popescu 4
Master thesis MEE 03:24 Objective .................................................................................................................................................178 Overview .................................................................................................................................................178 Procedure.................................................................................................................................................179 Create the self similar network model .................................................................................................180 Run the simulation...............................................................................................................................190 View the results ...................................................................................................................................191 Conclusions throughput.......................................................................................................................195 Conclusions delay................................................................................................................................195 Concluding Remarks ...................................................................................................................................196 Acknowledgments .......................................................................................................................................196 Glossary.......................................................................................................................................................197 References ...................................................................................................................................................198 Appendix 1 ..................................................................................................................................................199 Appendix 2 ..................................................................................................................................................221 Appendix 3 ..................................................................................................................................................244 Appendix 4 ..................................................................................................................................................255
Introduction
General
Today the field of computer networks all over the world has entered an exponential growth phase. These demands have made the necessity of capable network engineers extremely covet. It is therefore crucial for universities to offer networking courses that are both educational and up to date. Due to different obstacles it is unpractical for a university to be able to offer several types of networks to its students. An invaluable tool in this case consists of the network simulator OPNET Modeler that offers the tools for model design, simulation, data mining and analysis for, considering the alternatives, a reasonable cost. OPNET Modeler can simulate a wide variety of different networks which are link to each other. The students can therefore just by sitting at their workstations exercise various options available to network nodes and visually see the impact of their actions. Data message flows, packet losses, control/routing message flows, link failures, bit errors; etc can be seen by the students at visible speed. This is the most cost effective solution for universities to demonstrate the behavior of different networks and protocols.
Purpose
This thesis will implement five laboratory exercises using the OPNET Modeler simulation environment, namely: Lab1 Introduction (Introduction to OPNET environment) Lab2 M/M/1 (Construct an M/M/1 queue model) Lab3 Ethernet (Aloha, CSMA, CSMA-CD) Lab4 TCP (SlowStart, Congestion Avoidance, Fast Retransmit, Fast Recovery) Lab5 OSPF (Areas, Balanced traffic flow)
Finally after concluding these laboratory exercises the students comprehension of protocols, networks and routing implementation and interaction will be expanded. This plays a fundamental roll in understanding how Internet works.
Objective
This laboratory is about basics of using Optimized Network Engineering Tools (OPNET).
Overview
The OPNET is a very powerful network simulator. Main purposes are to optimize cost, performance and availability. The goal of this laboratory is to learn the basics of how to use Modeler interface, as well as some basic modeling theory. The following tasks are considered: Build and analyze models. Configure the object palette with the needed models. Set up application and profile configurations. Model a LAN as a single node. Specify background utilization that changes over a time on a link. Simulate multiple scenarios simultaneously. Apply filter to graphs of results and analyze the results. Before starting working on the Exercise part of this laboratory, one has to read the Preparations part.
Preparations
To build a network model the workflow centers on the Project Editor. This is used to create network models, collect statistics directly from each network object or from the network as a hole, execute a simulation and view results. See Fig.1.
Figure 1 - Workflow
Project Editor
The main staging area for creating a network simulation is the Project Editor. This is used to create a network model using models from the standard library, collect statistics about the network, run the simulation and view the results. Using specialized editors accessible from the Project Editor via File New one can create node and process models, build packet formats and create filters and parameters.
Depending on the type of network being modeled, a network model may consist of subnetworks and nodes connected by point-to-point, bus, or radio links. Subnetworks, nodes, and links can be placed within subnetworks, which can then be treated as single objects in the network model. This is useful for separating the network diagram into manageable pieces and provides a quick way of duplicating groups of nodes and links.
11
12
13
14
15
16
17
Buttons
Several of the more commonly used menu bar can also be activated through buttons. Each editor has its own set of buttons. The buttons shown below appear in the Project Editor.
Tommy Svensson Alex Popescu 18
10
11
1. Open object palette 2. Check link consistency 3. Fail selected objects 4. Recover selected object 5. Return to parent subnet 6. Zoom in 7. Zoom out 8. Configure discrete event simulation 9. View simulation results 10. View web-based reports 11. Hide or show all graphs
Occasionally, the messages Modeler generates may be larger than the message area. You next to the message area to open the message buffer, where can left-click on the icon the entire message displays.
Tool tips
If you place your cursor over a button or a menu selection, a help balloon soon appears.
19
20
To work with Modelers full set of node and link models would be overwhelming, so the object palette can be configured to show only a specific subset, or model list. Further you can use the standard model list, adapt them for your own needs, or make your own list. For this lab we created LAN_Mod_Model_List. Now you will adapt that model list by adding the LAN node model to it. 9) To open the Configure Palette dialog box click the Configure Palette button in the object palette.
The Configure Palette dialog box lets you change the object palette and then save it 10) Click the Node Models button in the Configure Palette dialog box. Select Included Entries dialog box appears. 11) Find 10BaseT_LAN in the list and change its status from not included to included.
21
The 10BaseT_LAN icon appears in the object palette. 13) Click OK to close the Configuration Palette dialog box, then click OK again to save the model list as <initials>_LAN_Mod_Model_List-no_back_util.
22
You will now configure the Application Configuration Object and the Profile Configuration Object. Before you begin constructing the network its a good idea to predefine the profiles and applications that will be used by the LAN. 14) To configure the Application Configuration Object, open the object palette in the case it is not already open and drag an Application Config object to the project workspace. 15) Right click and select Edit Attributes from the pop up menu. 15) Click on the question mark next to the name attribute to see a description of the attribute. When done close the attribute description dialog box.
16) Set the name attribute to Application Configuration. 17) Now change the Application Definitions attribute to Default by clicking in the attributes Value column and selecting Default from the pop-up list.
23
Selecting Default configures the application definition object to have the eight standard applications which are: Database Access, Email, File Transfer, File Print, Telnet Session, Video conferencing, Voice over IP Call and Web Browsing. 18) Close the Attributes dialog box by clicking OK. Now you will configure the Profile Configuration Object. 19) Drag a Profile Configuration object from the object palette to project workspace. 20) Right-click on the object and select Edit Attributes.
21) Set the name attribute to Profile Configuration as shown in the box above.
Tommy Svensson Alex Popescu 24
22) Change now the Profile Configuration attribute by clicking in its value column and selecting Edit from the drop down menu. The Profile Configuration Table box appears.
Define a new profile and add it to the table. 23) First change the number of rows to 1. 24) Name the new profile LAN Client. 25) Click in the profiles Start Time (seconds) cell to open the Start Time Specification dialog box. 26) Select constant from the Distribution Name pull-down menu.
Figure 23 - LAN Client Start Time Attributes Tommy Svensson Alex Popescu 25
27) Set Mean Outcome to 100, the click OK. Since you will be modeling FTP performance, that application should be included in the profile. 28) Click in the LAN Clients Applications column and choose Edit from the pop-up menu 29) Change the number of rows to 1. 30) Set the name to File Transfer (Heavy) by clicking in the cell and selecting the application from the pop-up menu. By selecting Default as the value for the Application Definition attribute in this object, you enable this list of applications. The list includes 16 entries, a heavy and a light version for each of the eight standard applications. 31) Set the Start Time Offset to Uniform (0,300). 32) The completed dialog box should look like this. Verify and then click OK to close the Applications Table dialog box.
33) Click OK to close the Profile Configuration Table, then click OK once again to close the Attributes dialog box. You are now ready to begin the construction of the WAN. In this scenario the network contains 2 identical subnets in Karlskrona and Karlshamn. You can create the first subnet in Karlskrona , with its nodes inside it, and then copy the subnet to Karlshamn. You will also copy it to Ronneby and modify it further.
26
Hint: A subnet is a single network object that contains other network objects (links, nodes and other subnets). Subnetworks allow you to simplify the display of a complex network through abstraction. Subnets are useful when organizing your network model. Subnets can be nested within subnets to an unlimited degree. 34) Open the object palette. 35) Place a subnet over Karlskrona, Right-click to turn off node creation. 36) Right-click on the subnet and select set name. Change the name to Karlskrona. The extent of the subnet needs to be modified. The subnet extent is the geographic area covered by the subnet, which may be much larger than the actual area you wish to model. 37) Right-click on the Karlskrona subnet and select Advanced Edit Attributes. 38) Change the x span and y span attributes to 0,25. The unit of measure of these attributes is determined by the unit of measure of the toplevel area, degrees in this case. 39) Click OK. In order to see whats inside subnets just double-click on that subnet icon and the Modeler will change the view. By default a subnets grid properties is based on its parent subnet. You can change them to fit your network. 40) Double-click on the Karlskrona Subnet. 41) Select View => Set View Properties 42) Set units to Meters. 43) Set resolution to 10 pixels/m. 45) Uncheck the Visible checkbox for Satellite orbits. 46) Verify that Drawing is set to Dashed. 47) Set division to 10.
27
48) Click the Close button. The network in BTH does not require modeling the precise nature of each node in each subnet, so you can represent the subnets with a LAN model. 49) Place a 10BaseT_LAN in the workspace. 50) Right-click on the 10BaseT_LAN and choose the Edit Attribute menu item. You can change the attributes so that it represents a network with a certain number of workstations and a particular traffic profile. 51) Change the LAN models name attribute to Office_LAN. 52) Choose Edit for the Application: Supported Profiles attribute. 53) Change the number of rows to 1. 54) Change the Profile Name to LAN Client, then click OK. This LAN will now use the LAN Client profile you created earlier. This profile includes the File Transfer (Heavy) application. The LAN will send traffic that models heavy FTP use.
Tommy Svensson Alex Popescu 28
55) Change the Number of Workstations attribute to 10, then click OK. 56) Close the Edit Attributes dialog box. You have now modeled a 10 workstation LAN inside the Karlskrona subnet. Further because this LAN model is composed of workstations and links only, it must be connected to a router. The router can then be connected to other routers in the network. 57) To create an router drag a BN_BLN_4s_e4_f_sl8_tr4 node from the object palette to the workstation near the Office_LAN node. 58) After naming the new node router connect it to the Office_LAN nodes with a 10BaseT link. Right click to turn off link creation. The Karlskrona subnet is now configured. Because the subnets in Karlshamn and Ronneby are identical, you can copy the Karlskrona subnet and place it appropriately. 59) To copy the subnet you must first return to the parent subnet, this is done either by clicking on the Go to Parent Subnetwork button or right click on the workspace to bring up the workspace pop-up menu, then choose Go to Parent subnetwork from the menu. 60) After returning to the parent subnet, select the subnet and copy it, this is done either by clicking Edit=>Copy or by pressing <Control>+c. 61) Now paste the subnet to Karlshamn and Ronneby by selecting Edit=>Paste or by pressing <Control>+v and then click on the Karlshamn and Ronneby region. When done the new subnets appears. 62) You will now have to rename the subnets. To do so right-click on each of the two subnets and choose set name. 63) Next you should connect the Karlshamn and the Karlskrona subnets to Ronneby. To do so select the LAN_Mod_PPP_DS0 link in the object palette. 64) Draw a LAN_Mod_PPP_DS0 link from Karlskrona to Ronneby. Next a Select Nodes dialog box appears asking which nodes in each subnet are to be endpoints of the link. 65) For node a, choose the Karlskrona.router node. 66) For node b, choose the Ronneby.router node.
29
68) Repeat this process, drawing link from Karlshamn to Ronneby as well. Specify the citys router as the links endpoints. 69) When done right-click to turn of link creation. The network should resemble the one shown in the picture below.
30
To complete the network, the main office in Ronneby needs to have a switch and a server added to it. 70) To configure the network in Ronneby double-click on the Ronneby subnet to enter its subnet view. 71) Place one <Bay Network Accelar1050> switch and one ethernet_server node in the workspace. 72) Rename the <Bay Network Accelar1050> node to switch. This is done by right-clicking on each icon and select Set name from the menu. 73) Rename the ethernet_server to FTP. 74) Connect the router and the server to the switch with 10BaseT links. Right-click to turn off link creation, and close the object palette. The Server needs to be configured to support the FTP Application. 75) Open the Attributes dialog box for the FTP server. 76) Choose Edit for the Application: Supported Services 77) Change number of rows to 1. 78) Select File Transfer (Heavy) from the Name column pop-up menu.
79) Click OK to close the Supported Services dialog box, and then click OK to close the FTP Attributes dialog box.
31
80) Return to the parent subnet view. 81) Save the project. File => Save. You have now created a model to act as a baseline for the performance of the network. Background traffic will now be added to the links connecting the cities. The results from the two scenarios will be compared. We begin with duplicating a scenario to be able to compare the results later. 82) Select Scenarios => Duplicate Scenario 83) Name the scenario back_util and click OK.
32
84) Select the link between Karlskrona-Ronneby. Right-click on the link and choose Similar Links from the pop-up menu. 85) Display the Edit Attributes dialog box for the link between Karlskrona-Ronneby. 86) Click in the Value cell for the Background Utilization attribute and select Edit... from the pop-up menu. 87) Click on the Rows value and change it to 3. Press Return. Network studies show that traffic rises gradually over the course of the day as employees/students arrive. 88) Complete the dialog box as shown. Then Click OK.
The last step in setting background utilization is to apply the changes made to the Karlskrona-Ronneby link to all the selected links. 89) Check the Apply Changes to Selected objects check box in the Karlskorna-Ronneby Attributes dialog box.
33
90) Click OK to close the dialog box. Note that 2 objects changed appears in the message area. 91) Save the project. File => Save. Now you have configured two scenarios, one without background utilization and one with background utilization. You are ready to collect data and analyze it. The relevant statistics for this network are: Utilization statistics for the links. Global FTP download time for the network. You will now collect statistics in the back_util scenario. 92) Right-click in the workspace to display the workspace pop-up menu, and select Choose Individual Statistics. 93) Select the Global Statistics => Ftp => Download Response Time (sec) statistic.
34
94) Select the Link Statistics => point-to-point => untilization --> Statistic.
95) Click OK to close the dialog box. In order to compare the statistics in the back_util scenario to the no_back_util scenario, the same statistics must be collected in the no_back_util scenario. Change scenario and collect statistics.
Tommy Svensson Alex Popescu 35
97) Collect the same statistics that you did in the back_util scenario: Global Statistics => Ftp => Download Response Time (sec) Link Statistics => point-to-point => untilization --> 98) Close the Choose Results dialog box. 99) Save the project. The statistics are now ready to be collected by running the simulations. Instead of running each simulation separately, you can batch them together to run consecutively. 100) Select Scenarios => Manage Scenarios 101) Click on the Results value for the no_back_util and back_util scenarios and change the value to <collect>. 102) Set the Sim Duration value for each scenario to 30 and the Time Units to minutes.
36
103) Click OK. Modeler will now run simulations for both scenarios. A simulation Sequence dialog box shows the simulation progress. Shut down the dialog box when the simulations are done. Hint: You are now ready to view the results of the two scenarios. To view the results from two or more different scenarios against each other, you can use the Compare Results feature. With this topic you can also apply different built-in filters to the graphs. 104) Continue by comparing the results, to do so display the workspace pop-up menu and choose Compare Results. 105) In the Compare Results dialog box, select Object Statistics => Choose From Maps Network => Karlshamn <-> Ronneby[0] => point to point => utilization ->. 106) Further you will also have to change the filter from menu from As Is to time_average. This must be done because utilization varies over the course of a simulation and it is therefore helpful to look at time average for this statistic.
37
107) Click Show to display the graph. The graph should resemble the one below, though it will not match exactly.
38
You may want to look at the utilization of other links to determine the maximum utilization of any link. Lets look at Global FTP response time. 108) Click the Unselect button in the Compare Results dialog box. 109) Check the Global Statistics => FTP => Download Response Time statistic in the Compare Statistics dialog box. 110) Verify that the filter menu shows time_average, then click Show. The graph should resemble the one below, though it will not match exactly.
39
The laboration is now completed. Before you leave please remove your saved project from the computer. By default it is located on: C:\Documents and Settings\[your login name]\op_models Remove all your saved files.
40
Overview
The task is to construct an M/M/1 queue model and observe the performance of the queuing system as the packet arrival rates, packet sizes, and service capacities change. Two classes of statistics will be measured, Queue Delay and Queue Size. A graph of the confidence interval will also be produced. This laboratory also introduces the use of: Node Model Probe Model Simulation Tool Analysis Tool
41
Procedure
An M/M/1 queue consists of a First-in First-Out (FIFO) buffer (queue) with packet arriving randomly according to a Poisson arrival process, and a processor, that retrieves packets from the buffer at a specified service rate. Three main parameters affects the performance of an M/M/1 queue, namely: Packet arrival rate, Packet size, 1/ Service capacity, C [7]
OPNET models are hierarchical. At the lowest level, the behavior of an algorithm or a protocol is encoded by a state/transition diagram, called state machine, with embedded code based on C-type language constructs. At the middle level, discrete functions such as buffering, processing, transmitting and receiving data packets are performed by separate objects. Some of these objects rely on underlying process models. In OPNET, these objects are called modules and they are created, modified and edited in the Node Editor. Modules are connected to form a higher-level node model. At the highest level, node objects are deployed and connected by links to form a network model. The network model defines the purpose of the simulation. The lower-level objects for M/M/1 queue are provided by OPNET, but they need to be combined to form a node model.
42
5) Click on the Create Processor button. 6) Place a processor module in the workspace. Right-click to end the operation. 7) Right-click on the processor and select Edit attributes. 8) Change the name attribute to Source. 9) Change the process model attribute to simple_source. Some new generator attributes appears in the attribute list. 10) Left-click in the Value Column of the Packet Interarrival Time attribute to open the Packet Interarrival Time Specification dialog box. 11) From the Distribution Name pop-up menu select Exponential, as in a Poisson process. 12) Set the Mean Outcome to 1.0 and click OK. This sets the mean interarrival time, , of a packet to 1 second.
43
13) Change the Packet Size attribute so that Distribution Name is exponential and Mean Outcome is 1024. Click OK.
14) Click OK to close the Attributes dialog box. In your design you will somehow have to represent the infinite buffer and the server, this will be done by the queue module. 15) To create the queue model click first on the Create Queue Module button and place then a module in the workspace to the right of the generator. 16) When done right click to end the operation. 17) Further right-click on the queue module and select Edit Attributes to bring up its attributes.
44
18) Change the name attribute to queue. 19) Change the process model attribute to acb_fifo The acb_fifo process is an OPNET-supplied process model that provides service in the packets arriving in the queue according to FIFO discipline. Note that when a process model is assigned to a module, the process model attributes appear in the modules attribute menu. The acb_fifo process model has an attribute called service_rate. When you select the acb_fifo process model, the service_rate attribute appears in the queue modules attribute menu with the default value 9600 bits per second. The name of the model acb_fifo reflects its major characteristics: Characteristics A C Indicates Active, acts as its own server Concentrates multiple incoming packet streams into its single internal queuing resource B Service time is a function of the number of bits in the packet fifo First in first out service ordering discipline 20) Right click on service rate in the attribute column. 21) Select Promote attribute to higher level. The value for this will be set later in the Simulation Set dialog box. 22) Click OK to close the dialog box. Further a sink module should be used although it is not a part of the M/M/1 queue system. The reason for using a sink is for proper memory management, packets should be
Tommy Svensson Alex Popescu 45
destroyed when no longer needed. The OPNET-supplied sink process module destroys the packet sent to it. 23) To create the sink module, activate the Create Processor Module button and then place a processor module to the right of the queue model on the workspace. 24) Open the attribute box for the processor module by right clicking the icon. 25) Change the name attribute to sink. Notice that the default value for the process model attribute is sink. 26) Close the dialog box.
To transfer packets between the generator module, the queue module and the sink module, it will be necessary to connect them together. This is done by packet streams that provide a path for the transfer of packets between modules. They serve as one-way paths and are depicted by solid arrowed lines. 27) Activate the Create Packet Stream button. 28) Connect the source module with the queue module by clicking the source icon, then clicking the queue icon. Remember that the first module you click becomes the source, and the second one the destination. 29) Connect the queue module and the sink module. Remember to end the Create Packet Stream operation by right-clicking anywhere in the window. 30) Select Interface => Node Interfaces.
46
31) In the Node Types table, click in the Supported cell for the fixed node type. This toggles the value to yes. Make sure mobile and satellite nodes are not supported. 32) Click OK to close the Node Interfaces dialog box. The M/M/1 node model definition is complete. You are now ready to create the network model, but first you should save your work. 33) To save select File => Save. Name the node <initials>_mm1, then click OK and close the Node Editor. The first step in creating the network model is to create a new model list. You can customize the palette to display only the models needed. 34) Click on Open Object Palette button. 35) Click on the Configure Palette button in the object palette. 36) Click on the Model List radio button. 37) Click on the Clear button. 38) Click on the Node Models button. A list on available node models appears. 39) Scroll in the table until you find the <initials>_mm1 node model. Change the status from not included to included. 40) Click OK to close the table. 41) Click the Save button. Enter the name <initials>_mm1_palette. 42) Click OK.
Tommy Svensson Alex Popescu 47
The node model you created is now included in the object palette. Now you can create the network model. 43) Click and drag the <initials>_mm1 node model to the workspace. Right-click to end the operation. 44) Change the name. Right-click and select Set Name. 45) Enter the name m1 and choose OK.
46) Save your model. File => Save. We will use the Probe Editor to set the statistics to collect during simulation. This could also be done by the Choose Result option in the object pop-up menu. The Probe Editor is a more powerful collection tool. The Probe Editor will be used to collect queue delay and queue size statistics. 47) Select File => New ,then select Probe Model and click OK. You must specify the network model from which the Probe Model should collect statistics. 48) Select Objects => Set Network Model. 49) Choose the <initials>_mm1net-mm1 network model. We will now set the probes. Specifying appropriate probes causes the statistics to be recorded at simulation time.
We will use the automatic selection method to type in the attributes for the probe.
Tommy Svensson Alex Popescu 48
51) Right-click on the probe and select Choose Probed Object from the pop-up menu. 52) Expand the m1 node. 53) Select the queue module and click OK.
54) Right click on the probe and select Edit Attributes from the pop-up menu. 55) Set the name to Queue Delay. 56) Set the submodule attribute to Subqueue[0]. 57) Left-click in the Value column of the statistics row. The Available Statistics dialog box shows the statistics, the group it belongs to and a description. 58) Select queue.queuing delay from the list and click OK. The group attributes changes to queue and the statistics attribute changes to queuing delay in the Edit Attributes dialog box. 59) Set scalar data to enable. 60) Set scalar type to sample mean. 61) Set scalar start to 14400. This is done to eliminate the unwanted initial oscillations. 62) Set scalar stop to 18000. This equals one hour.
Tommy Svensson Alex Popescu 49
63) Set capture mode to all values. 64) Click OK to close the probes Attribute dialog box. 65) Click the Create Node Statistics Probe button and a probe appears below.
66) You will now have to set new values to the attributes of the probe, to do so right click on the new probe and select Edit Attributes. The values should be set as follows: name = Queue Size subnet = top node = mm1 module = queue submodule = subqueue [0] group = queue statistic = queue size (packets) scalar data = enabled scalar start = 14400 scalar stop = 18000 capture mode = all values 67) When done close the probes Attribute dialog box by clicking OK. The changes will then appear in the Probe Editor.
69) Right click and select choose attributed object in the pop-up menu.
Tommy Svensson Alex Popescu 50
70) Select top => mm1 =>queue then click OK. 71) Right click on the attribute probe and select edit attributes. 72) Set attribute to service_rate. The probes are now set up correctly and will collect the desired statistics. 73) Save the probe file. File => Save. Name it <initials>_mm1probe. 74) Close the Probe Editor. Its time to begin the simulation. We will use the Simulation Sequence Editor instead of running the simulation form the Project Editor. 75) To open the Simulation Sequence Editor choose Simulation => Configure Discrete Event Simulation (Advanced). 76) Now place the simulation set icon in the workspace and change its values by selecting Edit Attributes. 77) The simulation Duration should be set to 7 hours and the Seed to 321. 78) Change the value per statistic to 10000. The seed is an initial value for the random generator. You can choose your own arbitrary value. 79) Now select the Advanced tab and then set the probe file to <your initials>_mm1probe. 80) Set Scalar File to <initials>_mm1scalar. 81) Select the Object Attributes tab. 82) Click the Add button. An Add Attributes dialog box appears. 83) Mark Add in the column next to m1.queue.service_rate. 84) Click OK to close the dialog box. 85) Select the m1.queue.service_rate attribute in the Simulation Set dialog box and click the values button.
Tommy Svensson Alex Popescu 51
An Attribute: m1.queue.service_rate dialog box appears. 86) Set the value to 1050. 87) Set the Limit to 1200. 88) Set Step to 50.
89) Click OK to close the Attribute: m1.queue.service_rate dialog box. Notice that the number of runs has changed to 4.
90) Click OK to close the Simulation Set dialog box. 91) Click on the scenario to mark it. 92) Select Edit => Copy in the menu. 93) Select Edit => Paste. 94) Place the new scenario to the right of its parent. 95) Right click on the new scenario and select Edit Attributes. 96) Change the Seed number to a different value, when done click OK to close the dialog box.
Tommy Svensson Alex Popescu 52
97) Create eight more scenarios by repeating steps 91 to 96. Notice: Its very important that each scenario has different Seed numbers. 98) When finished creating all the scenarios begin the simulation by clicking on the Execute Simulation Sequence button. Wait until the simulation is completed. In this last portion of lab you will learn how to view your results. The tool used for this task is the Analysis Tool. 99) Select File => New from the Project Editor. 100) From the pull-down menu in the dialog box change the file type to Analysis Configuration, then click OK. The Analysis Tool opens in a new window. During the simulation the packets always experience some delay. This delay is named the mean queuing delay and is the first statistic that we are going to take a closer look at. 101) To view the mean queuing delay left-click on the create a graph of a statistic button. 102) When done the View Results dialog box opens. Expand now the following hierarchy: File Statistics => <your initials>_mm1net-mm1 => Object Statistics => mm1 => queue => subqueue [0] => queue. 103) Select the queuing delay statistic. 104) From the list of filters select average. 105) Finally to show the graph click on the Show button.
53
54
The large deviations early in the simulation depends on the sensitivity of averages to the relatively small number of samples collected, as you can see the average stabilizes towards the end of the simulation. The results need to be validated. Calculate the following: Mean arrival rate, =
1 = meanint erarrivaltime 1
Mean service requirement, Service capacity, C = Mean service rate, C = Mean Delay, W =
1 = C
Another statistic of interest is the time-averaged queue size. 106) In the View results dialog box, remove the check next to the queuing delay. 107) Place a check next to the queue size (packets) statistic. 108) Select time-average from the pull-down list. 109) Click Show.
From this graph we can draw the conclusion that the system is stable. It reaches steady state after about 2 hours. Validate the result. Calculate the following:
Ratio of Load to Capacity = Average Queue Size
= C
Does the analytic value agree with the simulated results? We will produce a queue size versus time averaged queue size graph. 110) Set focus on the time averaged queue size window. 111) Right-click on the graph and choose Add statistics. 112) Place a check next to File Statistics => <initials>_mm1net-mm1 => Object Statistics => m1 => queue => subqueue [0] => queue => queue size (packets). 113) Left-click on the Add box. 114) Save the analysis configuration as <initials>_mm1net-mm1.
57
Its important to know the confidence intervals of the simulation results. We will now graph the confidence interval. 115) Load the Scalar file. File => Load output scalar file 116) Select <initials>_mm1scalar. 117) Click the Create graph of two scalars button. 118) Select top.queue.service_rate on the Horizontal roll-down menu. 119) Select top.queue.subqueue[0].queue.queue size (packets).mean on the Vertical roll-down menu. 120) Right click on the graph and select Edit Graph Properties.
58
59
60
In order to get better confidence intervals you need to run more scenarios. The graph below shows the confidence interval of 40 scenarios. The service rate is between 1024 and 1300 with step size 10.
61
Objective
Networks can be generally divided into two broad categories, which are based on using point-to-point connections and on using broadcast channels. In the broadcast channel case, there could be competition for the use of the channel between two or more stations. In the common literature, broadcast channels are referred to as multi-access channels, or random-access channels. The problem of media access is therefore the most important one for this case. Multiple access protocols are implemented primarily in Local Area Networks (LANs). Todays personal computers and workstations are connected by Local Area Networks (LANs), which use a multi-access channel as the basis of their communication. An example of a popular LAN is the Ethernet which uses a random-access scheme for media access. The random-access technique was first used by the ALOHA protocol developed at the University of Hawaii in the 1970s. Another popular random-access protocol is the Carrier Sensing Multiple Access (CSMA) scheme which was developed by XEROX Parc. Further the Ethernet, which is using the Carrier Sensing Multiple Access with Collision Detection (CSMA-CD) scheme, was developed by Dr. Robert M. Metcalfe in 1978. [4]
Overview
In this laboratory we will study Multiple Access Protocols. We will look at the ALOHA, CSMA and Ethernet (CSMA-CD) protocols. The ALOHA is the simplest Multiple Access Protocol and implements therefore only the most basic functionality, which is to send packets. ALOHA has no built mechanism to check if the channel is free before it continues transmitting packets, neither the possibility to detect any collisions on the channel. These flaws limit the use of the bus. By adding carrier sense capability to the Aloha random access protocol the performance is improved. The carrier sense capability is employed in the CSMA (Carrier Sense Multiple Access) protocol. The process waits until the channel is free before transmitting a packet. Because of finite signal propagation times, it is possible for a node to be transmitting before it detects an existing transmission signal. This results in some collisions. [4] Finally the Ethernet protocol implements the capability of both transmitting and monitoring a connected bus link at the same time. It has fullduplex capability. By monitoring the bus link it can determine whether a collision condition exists. If that is the
Tommy Svensson Alex Popescu 62
case a retransmission sequence will commence. This operational mode is commonly referred to as Carrier-Sense Multiple Access with Collision Detection (or CSMA/CD). The objectives of our study are:
To take a look at the performance, whichs main objective is the throughput. To study various parameters that characterizes the multi-access protocols. To assess via simulation the performance of ALOHA, CSMA and CSMA-CD protocols and to study the throughput of each of them.
Procedure
OPNET uses the Finite State Machine (FSM) to implement the behavior of a module. FSMs determine a modules behavior when an event occurs, detailing the actions taken in response to every possible event. A process model is a Finite State Machine (FSM). It represents a modules logic and behavior. An FSM consists of any number of states that a module may be in and the necessary criteria for changing states. A state is the condition of a module. For example the module may be waiting for a link to recover. A transition is a change of state in response of an event.
63
The first state created is automatically the initial state and indicated by a heavy black arrow pointed towards it (figure 60). Any state can be changed to initial state by right clicking on the state and choose Make Initial state in the pop-up menu.
4) Right click on the initial state and choose Edit attributes. 5) Change the name to idle. 6) Make sure the status is unforced.
7) Click OK to accept the changes. 8) Right click on the other state and choose Edit attributes. 9) Change the name to tx_pkt and the status to forced. It is now time to specify the code for the process model starting with the header block. In the header block one usually specify macros to replace more complicated expressions in transition conditions and executives. The use of macros saves place but the key advantage is that it simplifies the task of interpreting an FSM diagram. The header block may also contain #include statements, struct and typedef definitions, extern and global variable declarations, function declarations and C-style comments. 10) Click on the Header Block button. 11) Type in the definitions shown below.
64
/* Input stream from generator module */ #define IN_STRM 0 /* Output stream to bus transmitter module */ #define OUT_STRM 0 /* Conditional macros */ #define PKT_ARVL (op_intrpt_type () == OPC_INTRPT_STRM) /* Global variable */ extern int subm_pkts;
13) Create two transitions, one from idle state to tx_pkt state and the second one from
tx_pkt state to idle state. Use the create transition button.
15) Change the condition attribute to PKT_ARVL. The finished configuration should look like in figure 62.
65
The condition PKT_ARVL is the macro that just has been defined in the header block. The next step is to create state executives needed in the FSM. OPNET allows one to attach code to each part of an FSM. This code is called Proto-C. There are three primary places to use Proto-C, namely:
Enter Executives: Code executed when the module moves into a state. Exit Executives: Code executed when the module leaves a state. Transition Executives: Code executed in response to a given event. Although the enter executives and exit executives of forced states are executed without interruption, standard practice is to place all forced state executives in the enter executives block. To bring up the enter executives editor one double clicks on the upper half of the state. Double clicking on the lower half of the state will bring up the exit executives editor. (figure 63)
66
Next step is to define the actions for the idle state. 16) Double-click on the top of the idle state to open the enter executives block 17) Enter the code shown below.
/* Get the maximum packet count, */ /* set at simulation run-time. */ op_ima_sim_attr_get (OPC_IMA_INTEGER,"max packet \ count", &max_packet_count);
The max_packet_count variable is not yet defined. The variable will hold the maximum number of packets to be processed in the simulation before it terminates. Variables can be declared in two places. Variables declared in the temporary variables block do not retain their values between invocations of the FSM. Variables declared in the state variables block retain their values from invocation to invocation. The max_packet_count variable value should be retained between invocations and therefore declared in the state variable block.
19) Click the state variable block button. 20) Add the max_packet_count variable. The default type, int, is acceptable. When you are finished click OK to close the dialog box.
67
This value is set later in the simulation attributes. To be able to set the value at simulation run-time it needs to be defined. 21) Select Interface box table.
Simulation Attributes and enter an attribute into the dialog
22) To save your changes click on the OK button. Specify the actions for the tx_pkt state. 23) Double-click on the upper half of the tx_pkt state to open the enter executives block. 24) Enter the code shown below.
/* A packet has arrived for transmission. Acquire */ /* the packet from the input stream, send the packet*/ /* and update the global submitted packet counter.*/ out_pkt = op_pk_get (IN_STRM); op_pk_send (out_pkt, OUT_STRM); ++subm_pkts; /*Compare the total number of packets submitted with*/ /*the maximum set for this simulation run.If equal*/ /* end the simulation run. */ if (subm_pkts == max_packet_count) { op_sim_end ("Simulation ended when max packet count \ reached.", "", "", ""); }
68
The out_pkt variable is a packet pointer. This variable has not been declared yet. Since the process model acquires packets from the generator stream and immediately transmits them, it is not necessary to retain the packet pointer between process invocations. This variable will be declared in the temporary variable block. Enter the temporary variable block and state variables.
25) Click the temporary variable block button. 26) Enter the following declarations.
/* Outgoing packet */ Packet* out_pkt;
27) Save your changes to close the text edit pad. The out_pkt entry in the temporary variable block creates a temporary packet pointer. This is used to extract packets from one stream and insert them into another. The packet pointers existence is only temporary. Since the packet is sent directly there is no need for the pointer to be retained between process invocations. The model is now complete, except for the model interface attribute. To control the attributes visible at the node level, edit the Process Interfaces. You can set initial attribute values or hide attributes. 28) Select Interface
Process Interfaces.
29) Change the Initial Value for the begsim intrpt attribute to enabled.
Tommy Svensson Alex Popescu 69
30) Verify that the Initial Value for each of the following attributes is set to disabled. endsim intrpt failure intrpts intrpt interval recovery intrpts super priority 31) Verify that the Initial value of the priority attribute is 0. 32) Change the status attribute to hidden for all attributes
33) Click OK to close the dialog box. All process models must be compiled before they can be used in a simulation. Compiling a model makes its object code available to a processor modules process model attribute. 34) Compile the model by clicking on the compile process model action button. 35) Save the model as <initials>_aloha_tx. 36) Close the Process Model Editor when the compilation of the process model has finished.
39) Create one bus transmitter by using the bus transmitter action button
Tommy Svensson Alex Popescu
40) Connect the modules with packet streams using the packet stream action button.
41) Right click on the first processor module and select Edit attribites. 42) Set the name to gen and process model to simple_source. The value for the generators interarrival time needs to be promoted to make it possible to assign different values at simulation time. 43) Click on Packet Interarrival Time in the left column to highlight the Attribute name, then right-click and select Promote Attribute to Higher Level from the pop-up menu. 44) Click OK.
45) Right click on the second processor module and select Edit attributes 46) Set the name to tx_proc and process model to <initials>_aloha_tx. 47) Click OK. 48) Change the bus transmitters name to bus_tx.
71
Double check the module connectivity to make sure all objects in the model has been connected in the correct order. 49) Right click on the tx_proc module and choose Show Connectivity from the Object pop-up menu. The objects should be connected as shown in figure 70.
Figure 70 Connectivity
51) In the Node Types table, change the Supported value to no for the mobile and satellite types. 52) Change the Status of all the attributes to hidden, except for the one with promoted status, gen.Packet Interarrival Time. 53) Click OK to save the changes. 54) Save the node model as <initials>_cct_tx. Aloha node model is completed. 55) Close the editor.
72
58) Right click on the initial state and choose Edit attributes. 59) Change the name to init and the status to forced. Click OK. 60) Right click on the second state and choose Edit attributes. 61) Change the name to idle and leave the status as unforced. Click OK. 62) Draw the transitions as shown below.
Enter the code for the header block. 63) Click the header block action button. 64) Type in the definitions shown below.
/* Input stream from bus receiver */ #define IN_STRM 0 /* Conditional macros */ #define PKT_RCVD (op_intrpt_type () == OPC_INTRPT_STRM) #define END_SIM (op_intrpt_type () == OPC_INTRPT_ENDSIM) /* Global variable */ int subm_pkts = 0;
66) Click the state variable action button. 67) Set the name to rcvd_pkts. 68) Set the type to int. 69) Click OK. The rcvd_pkts variable is used to keep track of the number of valid received packets. It needs to be initiated at simulation start. 70) Double-click on the top of the init state to open the enter executives block, and enter the following code:
/* Initialize accumulator */ rcvd_pkts = 0;
71) Save the changes to close the dialog. Two functions are needed. One that receives packets and one to write statistics to a scalar file.
Tommy Svensson Alex Popescu 74
72) Open the function block and enter the following code.
/* This function gets the received packet, destroys it, */ /* and then logs the incremented received packet total. */ void proc_pkt () { Packet* in_pkt; /* Get packet from bus receiver input stream */ in_pkt = op_pk_get (IN_STRM); /* Destroy the received packet */ op_pk_destroy (in_pkt); /* Increment the count of received packets */ ++rcvd_pkts; } /* This function writes the end-of-simulation channel */ /* traffic and channel throughput statistics to a */ /* scalar file */ void record_stats () { /* Record final statistics */ op_stat_scalar_write ("Channel Traffic G", (double) subm_pkts / op_sim_time ()); op_stat_scalar_write ("Channel Throughput S", (double) rcvd_pkts / op_sim_time ()); }
The proc_pkt() function acquires each received packet as it arrives, destroys it, and increments the count of received packets. The record_stats() function is called when the simulation terminates. The op_stat_scalar_write function sends the channel throughput and traffic data to a scalar file that is specified in the simulation attributes. The macro definitions and the functions have been defined. There is now a good idea to change the transition conditions. 73) For the first transition between the states, change the condition attribute to PKT_RCVD and the executive attribute to proc_pkt(). 74) For the second transition between the states, change the condition attribute to END_SIM and the executive attribute to record_stats(). 75) For the first transition from idle back to itself, change the condition attribute to PKT_RCVD and the executive attribute to proc_pkt(). 76) For the second transition from idle back to itself, change the condition attribute to default.
Tommy Svensson Alex Popescu 75
77) For the third transition from idle back to itself, change the condition attribute to END_SIM and the executive attribute to record_stats(). Define the process interfaces. 78) Select Interfaces
Process Interfaces
79) Change the Initial value of the endsim intrpt attribute to enabled. 80) Change the status of all the attributes to hidden.
81) Click OK. 82) Click on the Compile Process Model action button. 83) Supply the filename <initials>_cct_rx and click OK. 84) Close the process model editor.
76
86) Click on the create processor action button and place one processor in the workspace. 87) Create also a bus receiver module in the workspace to the right of the processor by clicking on its action button .
88) Connect the two modules from the bus receiver to the processor by using a packet stream. 89) Change the name of the processor to rx_proc and the name of the bus receiver to bus_rx. The finished configuration should look like the picture below:
90) Open the processors attribute dialog box and set the process model attribute to <initials>_cct_rx. Close the dialog box when finished. The interface attributes remains to be set before the node model is completed. 91) Select Interfaces
Node Interfaces.
92) The supported value should be changed to no for the mobile and satellite types in the Node types table.
77
93) Further, in the Attributes table change the status to hidden for all the attributes.
94) Close the node model editor after saving the node model as <initials>_cct_rx.
78
This link model supports only the bus and bus tap types. 96) In the Link Types table, change the Supported value to no for the ptsimp and ptdup types.
97) Save the file as <initials>_cct_link and close the Link Model Editor.
79
99) Name the project <initials>_cct_network and the scenario aloha, then click OK. 100) In the Startup Wizard, use the following settings:
Dialog Box Name Initial Topology Choose Network Scale Specify Size Select Technologies Review Value Default value: Create Empty Scenario Office (Use Metric Units enabled) 700 m x 700 m None Check values, then click OK
In order to easily build your network, one needs a custom palette that contains the necessary objects for your network. 101) Open the Object palette if its not already opened. 102) Click on the Configure Palette button. 103) Click on the Clear button in the Configure Palette dialog. 104) Click on the Node Models button and add <initials>_cct_tx and <initials>_cct_rx from the list of available node models. 105) Click OK. 106) Click on the Link Models button and add <initials>_cct_link from the list of available link models.
80
107) Click OK. 108) Click on the Save button in the Configure Palette dialog and save the palette as <initials>_cct. 109) Click OK to close the Configure Palette dialog box. The next step is to create bus network. Instead of creating the entire bus network by hand, you can use rapid configuration to build it quickly. 110) Select Topology
Rapid Configuration.
111) Choose Bus and click OK. In the Model area. 112) Select <initials>_cct_tx in the Node model pull-down list. 113) Select <initials>_cct_link in the Link model pull-down list. 114) Enter the value 20 in the Number field. 115) Select <initials>_cct_link in the Tap model pull-down list. In the Placement area. 116) Select Horizontal radio button. 117) Check the Top of bus and Bottom of bus check boxes. 118) Enter X: 100 and Y: 200 for Head of bus. 119) Enter the value 500 for the Bus Size. 120) Enter the value 100 for Tap Size.
81
All the transmitter nodes have been created. The network needs a receiver node. 121) Click and drag the receiver node <initials>_cct_rx from the palette into the left side of the tool area.
in the palette and draw a tap 122) Click on the <initials>_cct_link tap link from the bus to the receiver node. Drawing a tap from the node to the bus may produce different results.
82
124) Right-click and choose Edit attributes 125) Change the values in the common tab: Duration to 20000 sec and seed to an arbitrary integer. 126) Click on the Global Attributes tab and set max packet count value to 1000. 127) Click on the Object Attributes tab and click on the Add button. 128) Add Office Network. *.gen.Packet Interarrival Time and click OK. 129) Click the on the Values button. 130) Click in the value column and choose exponential (mean) in the pop-up list.
83
131) Set the value 1000 by replacing mean with the value. (see figure 79)
132) Repeate the last 2 steps to enter the following values: 200, 150, 100, 80, 50, 35, 30, 25, 20, 18,15
133) Click OK. 134) Click on the Advanced tab. 135) Set Network to <initials>_cct_network-aloha. 136) Set Probe file to NONE. 137) Set Scalar file to <initials>_cct_a. 138) Click OK.
84
If the output scalar file <initials>_cct_a does not exist when the simulation sequence begins, it will be created so that scalar results may be recorded. If the file already exists, the simulation executables will append their scalar results to this file. To avoid viewing obsolete results which may already exist in a similarly named file, the output scalar file <initials>_cct_a must be deleted if it exists. 139) Select File
Model Files Delete Model Files....
A list of delete able file types appears. 140) Select the Output Scalars item. A list of available scalar files appears. 141) If the list contains the output scalar file <initials>_cct_a, select the entry to delete the file. 142) Close the open dialog boxes. The simulation is now ready for execution. 143) Click on the Execute Simulation Sequence action button. 144) Click OK to confirm execution. 145) When the simulations are complete, close the Simulation Sequence dialog box and the Simulation Sequence editor. Aloha channel performance can be measured according to the number of successfully received packets as a function of the number of packets submitted. In this network, channel throughput is a typical measurement of network performance. The results of each simulation are stored as two scalar values in the output scalar file. That allows us to view the networks performance as a function of an input parameter rather than a function of time. The channel throughput as a function of the channel traffic across all simulations can be viewed in the Analysis Configuration Editor. 146) Select File 147) Select File
New and then choose Analysis Configuration. Click OK. Load Output Scalar File.
149) Click on the Create graph of two scalars file action button.
Tommy Svensson Alex Popescu 85
150) Select Channel Traffic G from the Horizontal pull-down menu. 151) Select Channel Throughput S from the Vertical pull-down menu. 152) Click OK.
86
154) Select the <initials>_aloha_tx model then click OK. Modifications have to be made for adjusting the process model to CSMA. 155) Click on the Header Block button. 156) Add the following lines to the end of the existing code.
/* Input statistic indices */ #define CH_BUSY_STAT 0 /* Conditional macros */ #define FREE (op_stat_local_read (CH_BUSY_STAT) == 0.0) #define PKTS_QUEUED (!op_strm_empty (IN_STRM)) #define CH_GOES_FREE (op_intrpt_type () == OPC_INTRPT_STAT)
The Macro FREE makes the process verify that the channel is free before transmitting. The Macro PKTS_QUEUED checks if the queue is empty. The Macro CH_GOES_FREE keeps track of when the channel becomes empty and ready for a new transmission. 157) Select File
Save to save and exit the Header Block.
158) Now create a new state in the Process Model and name it wt_free. 159) Create a transition from wt_free to tx_pkt, and change the condition to CH_GOES_FREE. 160) Create a transition from the wt_free state back to itself and set the condition to default. 161) Create a transition from the idle state to wt_free and change the condition to PKT_ARVL && !FREE.
Tommy Svensson Alex Popescu 87
162) Add a transition from the idle state back to itself with a condition of default. 163) Change the condition on the transition from idle state to the tx_pkt state to PKT_ARVL && FREE. 164) Change the unconditional transition from tx_pkt to idle to conditional by setting the condition attribute to default. 165) Create a transition from tx_pkt back to itself, and set the condition to PKTS_QUEUED && FREE. 166) Finally, create a transition from tx_pkt to wt_free and set the condition to PKTS_QUEUED && !FREE. The finished configuration should look like in the picture below.
170) Select the <initials>_cct_tx model in the list and click OK. 171) Click on the create processor action button. 172) Place a processor on the workspace above the existing model.
173) Click on the create bus receiver action button. 174) Place a bus receiver next to the new processor. 175) Change the name of the new processor module to sink and the name of the bus receiver to bus_rx. 176) Click on the create packet stream button 177) Make a connection form the bus_rx receiver to the sink processor.
89
179) Connect bus_rx module with tx_proc module. 180) Right click on the static wire and choose Edit Attributes 181) Set the falling edge trigger attribute to enabled and rising edge trigger attribute to disabled. Click OK.
182) Right click on the tx_proc module and choose Edit attributes... 183) Change the process model attribute to <initials>_csma_tx. Click OK. The processor now uses the CSMA process model created previously. 184) Select File
Save As... and rename the model <initials>_cct_csma_tx.
90
187) Name the new scenario CSMA. The only change to the network model is to use the new CSMA transmitter node model. It needs to be added to the object palette. 188) Open the Object palette if its not already opened and click on the configure palette action button. 189) Click on the Node models action button. 190) Include <initials>_cct_csma_tx node model and click OK. 191) Click on the save button and save the palette with the default name. All transmitter nodes in the network model need to be changed to use the new transmitter model. 192) Right-click on one of the transmitter nodes and choose Select Similar Nodes from the Object pop-up menu. All 20 transmitter nodes are selected. 193) Right-click on any of the selected nodes and choose Edit Attributes from the pop-up menu. 194) Change the model attribute to <initials>_cct_csma_tx. 195) Check Apply Changes to Selected Objects check box in the bottom left, then click OK. The nodes are now modified to use the new node model.
91
198) Right-click on the simulation set and select Edit Attributes from the pop-up menu. 199) Change the seed to any arbitrary integer. 200) Click on the Advanced tab. 201) Change the Scalar file to <initials>_cct_c. 202) Set Probe file to NONE. 203) Click OK. 204) Save the simulation sequence, File
Save.
205) Delete any existing output scalar files with the name <initials>_cct_c. 206) Execute the simulation. 207) Close the simulation sequence editor when the simulation is finished.
92
210) Select <initials>_cct_c from the list of available files. 211) Click on the Create a graph of two scalars action button. 212) Select Channel Traffic G from the Horizontal pull-down menu. 213) Select Channel Throughput S from the Vertical pull-down menu. Your graph should resemble the one below:
The goal is to compare the Aloha and CSMA protocols. The easiest way to do so is to display both traces on the same graph.
93
215) Select <initials>_cct_a from the menu. 216) Click on the Create a graph of two scalars action button. 217) Select Channel Traffic G from the Horizontal pull-down menu. 218) Select Channel Throughput S from the Vertical pull-down menu. 219) Click OK. Create a vector graph that displays both results. 220) Select Panels
Create Vector Panel.
221) Open the Displayed Statistics menu, and select both displayed statistics. 222) Change the display mode to Statistics Overlaid.
94
224) Right-click on the multiple vector graph and select Edit Graph Properties. Notice the pop-up menu of active traces in the top section of the dialog box. Click and hold this menu to see the list of active traces. Both are named Channel Throughput S. Which is the CSMA trace and which the Aloha trace?
In this pop-up menu, traces are listed in the order in which they were added to the multitrace graph. The first trace listed in the pop-up menu is the CSMA trace. Change the labels for the CSMA trace. 225) Change the Custom Title to CSMA Channel Throughput.
Tommy Svensson Alex Popescu 95
226) Click on the Apply button. Change the labels for the Aloha trace. 227) Select the second active trace in the pop-up menu. 228) Change the Custom Title to Aloha Channel Throughput. 229) Click OK.
The CSMA protocol is shown to be superior to the Aloha protocol at all channel traffic loads. 230) Close the graphs and the Analysis Configuration Editor.
96
The bus_tx and bus_rx modules serve as the bus link interface. These modules are set to transmit and receive at a data rate of 10 Mbits/second by default.
97
The sink processor represents higher layers and simply accepts incoming packets that have been processed through the mac (medium access control) process. The defer processor independently monitors the links condition and maintains a deference flag that the mac process reads over a statistic wire to decide whether transmission is allowed. The bursty_gen module represents higher layer users who submit data for transmission. It uses an ON-OFF pattern for traffic generation. The mac process handles both incoming and outgoing packets. Incoming packets are decapsulated from their Ethernet frames and delivered to a higher level process. Outgoing packets are encapsulated within Ethernet frames and when the deference flag goes low, a frame is sent to the transmitter. This process also monitors for collisions, and if one occurs, the transmission is appropriately terminated and rescheduled for a later attempt. 231) Open a new project. File
New and choose project.
232) Name the project <initials>_ethernet and the scenario bus. 233) Create an empty scenario. Click next. 234) Choose Office. Click next. 235) Choose X span 100 and Y span 100. Click next. 236) Include ethcoax. Click next. 237) Review the settings then click OK. Proceed by constructing the network. 238) Use the rapid configuration tool. Topology 239) Choose bus. Click OK.
Rapid configuration.
98
240) Make the following configuration: Node model: ethcoax_station Link model: eth_coax Tap model: eth_tap Number: 8 Placement: Horizontal, Top of bus and Bottom of bus. Head of bus: X=10 and Y=50 Bus: 80 Tap: 20
241) Click OK. 242) Right click on one node and choose select similar nodes from the pop-up menu. 243) Right click on a node and select edit attributes.
99
244) Make the following configuration: Traffic Generation Parameters Start Time: constant (5.0) ON State Time: Exponential (100) OFF State Time: Exponential (0) Packet Generation Arguments Interarrival time: Exponential (0.01333) Packet Size: Constant (1250) Segmentation size: No segmentation Stop time: Never
245) Check the Apply Changes to Selected Objects check box. (figure 95)
Save.
The network model is completed. To gather the statistics of interest a probe model is needed. 247) Select File
New and choose probe model from the menu. Click OK.
The statistic of interest is the bus utilization. 248) Add a link statistic probe. Click on the add link statistic probe action button. 249) Choose network model to probe. Select Object 250) Click on <initials>_ethernet-bus in the list.
Set Network Model.
100
251) Right click on the link probe and select choose probed link. 252) Expand the tree and then select top.Office Network.bus 0. Click OK.
253) Right click on the link probe and choose edit attributes. 254) Set the name attribute to Bus Utilization. 255) Set the statistic attribute to bus.utilization. 256) Save the probe as <initials>_ethernet-probe. The probe model is now completed. Proceed by executing the simulation.
Configure Discrete Event 257) In the project window, select Simulation Simulation (Advanced). 258) Right click on the scenario and select edit attributes.
259) In the common tab set: Duration: 60 seconds Seed: Any arbitrary integer. 260) In the advanced tab set: Network: <initials>_ethernet-bus Probe file: <initials>_ethernet-probe Vector file: <initials>_ethernet-vector 261) Click on the Run action button to execute the simulation. 262) Close the simulation sequence window when the simulation is completed. 263) Open the Analysis Configuration tool. File Configuration.
New and then Analysis
264) Click on the create graph of a statistic action button. 265) Expand File statistic.<initials>_ethernet-vector.object statistics.Office Network.bus_0 [0].bus. 266) Check the utilization statistic.
101
102
As you can see, the throughput after 30 seconds of simulation stabilizes near 5.5 Mbps/sec. This demonstrates the superiority of the carrier-sensing, collisiondetection, and backoff strategies used by Ethernet over the less sophisticated methods used by the pure Aloha and CSMA protocols. The lab is now completed.
103
Objective
The purpose of this lab is to demonstrate the functioning of TCP, and particularly the four algorithms used for congestion control: slow start, congestion avoidance, fast retransmit and fast recovery. The lab provides a number of scenarios to simulate and compare these algorithms.
Overview
In this lab we will study TCPs four intertwined congestion control algorithms, namely: slow start, congestion avoidance, fast retransmit and fast recovery. The objectives are: To study the behavior and implementation of slow start and congestion avoidance algorithms. To study modifications to the congestion avoidance algorithm, namely fast retransmit and fast recovery.
Procedure
Slow start and congestion avoidance
Previous versions of TCP start a connection with the sender injecting multiple segments into the network, up to the windows size advertised by the receiver. This is ok when the hosts are placed on the same LAN. But if there are routers and slower links between the sender and the receiver different problems can arise. Some intermediate router must queue the packets and it is possible for the router to run out of space in the queue. The algorithm to avoid this is called slow start. Beginning transmission into a network with unknown conditions requires TCP to slowly probe the network to determine the available capacity, in order to avoid congesting the network with an inappropriate large burst of data. Slow start adds another window to the senders TCP: the congestion window, called cwnd. When a new connection is established with a host on another network, the congestion window is initialized to one segment (typically 536 bytes or 512 bytes). The sender starts by transmitting one segment and waiting for its ACK. When that ACK is received, the congestion window is increased from one to two, and two segments can be sent. When each of those two segments is acknowledged, the congestion window is increased to four. This provides an exponential growth, although it is not exactly exponential because the receiver may delay its ACKs, typically sending one ACK every two segments that it receives. The sender can transmit up to the minimum of the congestion window and the advertised window. The congestion window is flow control
Tommy Svensson Alex Popescu 104
imposed by the sender, while the advertised window is flow control imposed by the receiver. At some point the capacity of the internet can be reached and an intermediate router will start discarding packets. This tells the sender that its congestion window has gotten too large. Congestion avoidance is a way to deal with lost packets. Congestion can occur when data arrives on a big pipe (a fast LAN) and outputs on a smaller pipe (a slower WAN). Congestion can also occur when multiple input streams arrive at a router whose output capacity is less than the sum of the inputs. There are two indications of packet loss at a sender: a timeout occurring and the receipt of duplicate ACKs. However, the overall assumption of the algorithm is that packet loss caused by damage is very small (much less than 1%), therefore the loss of a packet signals congestion somewhere in the network between the source and destination. Although congestion avoidance and slow start are independent algorithms with different objectives, in practice they are implemented together. When congestion occurs TCP must slow down its transmission rate of packets into the network, and then invokes slow start to get things going again. [3] The combined congestion avoidance and slow start algorithms require that two variables are maintained for each connection:
The combined algorithm operates as follows: a) Initialization for a given connection sets cwnd to one segment and sstresh to 65535 bytes. The initial value of cwnd must be less than or equal to 2*SMSS bytes and must not be more than 2 segments. SMSS, Sender Maximum Segment Size, is the size of the largest segment that the sender can transmit. The initial value of cwnd may be arbitrarily high (some implementations use the size of the advertised window), but it may be reduced in response to congestion. b) The TCP output routine never sends more than the minimum of cwnd and receivers advertised window. c) When congestion occurs one-half of the current window size is saved in ssthresh. Additionally, if the congestion is indicated by a timeout, cwnd is set to one segment. Congestion is indicated by a timeout or the reception of duplicate ACKs. d) When new data is acknowledged by the other end, increase cwnd. The way in which cwnd is increased depends on whether TCP is performing slow start or congestion avoidance. If cwnd is less than or equal to ssthresh, TCP is in slow start, otherwise TCP is performing congestion avoidance. Slow start continues until TCP is halfway to where it
105
was when congestion occurred, and then congestion avoidance takes over. This is done due to the recorded half of the window size that caused the problem. As mentioned earlier slow start increases congestion window (cwnd) exponentially. Congestion avoidance on the other hand dictates that congestion window (cwnd) be incremented by segsize * segsize / cwnd each time an ACK is received, where segsize is the segment size and cwnd is maintained in bytes. This results in a linear growth of cwnd, compared to slow starts exponential growth. The increase in cwnd should be at most one segment each round-trip time (regardless how many ACKs are received in that RTT) whereas slow start increments cwnd by the number of ACKs received in a round-trip time. [2]
106
9) Add an Application Config object to the workspace and rename it to Applications. 10) Right click on the Applications node and choose Edit Attributes. 11) Click in the value column on the Application Definitions row. Choose Edit
12) Set the Rows attribute value to 1. 13) Set the Application name to FTP_Application. Click OK. 14) Go to Application definitions choose Edit 15) Set the following values:
Tommy Svensson Alex Popescu
Row 0
Description
FTP and
107
Attribute Command Mix (Get/Total) Inter-Request Time (seconds) File Size (bytes) Symbolic Server Name Type of service RSVP Parameters Back-End Custom Application
Value 100% constant (3600) constant (9000000) FTP Server Best Effort (0) None Not Used
16) Click OK. 17) Click OK to close Application Attributes. 18) Add a Profile Config object to the workspace and rename it to Profiles. 19) Right click on the Profile node and choose Edit attributes 20) Click in the value column on the Profile Configuration row. Choose Edit
21) Set the Rows attribute to 1. 22) Set Profile Name to FTP_Profile. 23) Set Operation Mode to Serial (Ordered). 24) Set Start Time to constant (100) and Duration to End of Simulation. 25) Set Repeatability to Once at Start Time. 26) Click in the Applications column and choose Edit 27) Set the Rows attribute to 1. 28) Set Name to FTP_Application. 29) Set Start Time Offset to constant (5) and Duration to End of Profile. 30) Set Repeatability to Once at Start Time. 31) Click OK to close the Applications Table.
Tommy Svensson Alex Popescu 108
32) Click OK to close the Profile Configuration Table. The Profiles Attributes should look like the picture below:
109
43) Set the Rows attribute to 1. 44) Choose the name FTP_Application and click OK. 45) Edit the Server Address attribute and set value to Server_Paris. 46) Expand TCP Parameters. 47) Disable both Fast Retransmit and Fast Recovery. 48) Click OK. 49) Save the project. File
Save.
110
50) Click the Go to next higher level action button. The Paris subnet is now configured.
111
60) Set the Rows attribute to 1. 61) Change the Profile Name attribute to FTP_Profile. 62) Click OK. 63) Set the Client Address attribute value to Client_Sthlm. 64) Go to the Application: Destination Preferences and choose Edit 65) Set the Rows attribute to 1. 66) Set the Symbolic Name attribute to FTP Server. 67) Click in the Actual name column. 68) Set the Name attribute to Server_Paris. Click OK to close Actual name table dialog. 69) Click OK to close Application: Destination Preferences dialog.
Tommy Svensson Alex Popescu 112
70) Click OK to close Client_Sthlm Attributes dialog. 71) Save the project. File
Save.
113
114
Choose Statistics
79) Enter the Paris Subnet. 80) Right click on Server_Paris and select Choose Indivitual Statistics from the pop-up menu. TCP Connection and select Congestion 81) Expand Node Statistics Windows Size (bytes)
82) Right click on the Congestion Window Size (bytes) and select Change Collection mode. 83) Check the Advanced checkbox in the pop-up dialog. 84) Change Capture mode to all values. 85) Click OK to close the dialog.
Tommy Svensson Alex Popescu 115
86) Click OK to close the Choose results dialog. 87) Save the project. File
Save.
116
89) Set Duration to 10 minutes. 90) Click Run. 91) Click Close when the simulation has finished.
117
Fast retransmit
Fast retransmit is a modification to the congestion avoidance algorithm. The TCP sender should use fast retransmit algorithm to detect and repair loss, based on incoming duplicate ACKs. The fast retransmit algorithm uses the arrival of 3 duplicate ACKs (4 identical ACKs without the arrival of any other intervening packets) as an indication that a segment has been lost. After receiving 3 duplicate ACKs, TCP performs a retransmission of what appears to be the missing segment, without waiting for the retransmission timer to expire. The fast retransmit algorithm first appeared in the 4.3BSD Tahoe release.
Fast recovery
Congestion avoidance without slow start is performed after fast retransmit sends what appears to be the missing segment. It is an improvement that allows high throughput under moderate congestion, especially for large windows. In this case the reason for not performing slow start is that the receipt of duplicate ACKs tells TCP that more than just one packet has been lost. Since the receiver can only generate the duplicate ACK when another segment is received, that segment has left the network and is in the receivers buffer. In other words there is still data flowing between the two ends, and TCP does not want to reduce the flow abruptly by going into slow start. The fast recovery algorithm appeared in the 4.3BSD Reno release. The fast retransmit and fast recovery algorithms are usually implemented together as follows:
a) When the third duplicate ACK is received, set ssthresh to no more than one-half the current congestion window, cwnd, but no less than two segments. Retransmit the missing segment, and then set cwnd to ssthresh plus 3 times the segment size. This increases the congestion window by the number of segments that have left the network and which the other end has cached. b) Each time another duplicate ACK arrives, increment cwnd by the segment size. This inflates the congestion window for the additional segment that has left the network. c) Transmit a segment (packet) if allowed by the new value of cwnd and the receivers advertised window. d) When the next ACK arrives that acknowledges new data, set cwnd to ssthresh. This ACK should be the acknowledgment of the retransmission from step a, one round-trip time after the retransmission. Additionally, this ACK should acknowledge all the intermediate segments sent between the lost packet and the receipt of the first duplicate ACK. This step is congestion avoidance, since TCP is down to one-half the rate it was at when the packet was lost.
118
96) Name the scenario Tahoe. 97) Right click on the IP Cloud, Europa Internet, and choose Edit Attributes. 98) Set the Packet Discard Ratio attribute to 0.5%.
99) Click OK. 100) Enter the Paris subnet. 101) Right click on Server_Paris and choose Edit Attributes 102) Expand TCP Parameters. 103) Change the Fast Retransmit attribute to Enabled.
107) Name the scenario Reno. 108) Right click on the Server_Paris and choose Edit Attributes
Tommy Svensson Alex Popescu 119
109) Expand TCP Parameters. 110) Change the Fast Recovery attribute to Reno.
115) Click OK. 116) Click Close when the simulations has finished.
View results
117) Right click on the workspace and choose Compare Results.
Choose From Maps Network 118) Expand Object statistics Server Paris TCP Connection. 119) Check Congestion Window size (bytes). Paris
120
121) Click Show. The graph should resemble the one below.
The first graph illustrates the NoDrop scenario which has no packet loss.
121
The second graph illustrates the Tahoe scenario which has 0.5% packet loss. When congestion is indicated by a timeout, cwnd is set to one segment. In other words, slow start is performed. The third graph illustrates the Reno scenario which also has 0.5% packet loss. The congestion window size does not drop to zero as in the Tahoe graph. Fast recovery is performed instead of slow start. The lab is completed.
122
Overview
In this lab we will study the OSPF routing protocol. The objective is to construct a network and configure it with all the necessary parameters for OSPF routing. Using this network we will analyze the behavior of the OSPF routing protocol.
Procedure
The Open Shortest Path First (OSPF) protocol is an interior gateway protocol (IGP) used for routing in Internet Protocol (IP) networks. As a link state routing protocol, OSPF is more robust against network topology changes than distance vector protocols such as RIP, IGRP, and EIGRP. OSPF can be used to build large scale networks consisting of hundreds or thousands of routers. Open Shortest Path First (OSPF) uses the Dijkstras algorithm to compute the shortest path to a destination. The algorithm calculates the shortest path to each destination based on the cumulative cost required to reach that destination. The cumulative cost is a function of the cost of the various interfaces needed to be traversed in order to reach that destination. The cost (or the metric) of an interface in OSPF is an indication of the overhead required to send packets across that interface. The cost of an interface is calculated based on the bandwidth -- it is inversely proportional to the bandwidth of that specific interface (i.e., a higher bandwidth indicates a lower cost). For example, the cost of a T1 interface is much higher than the cost of a 100Mbit Ethernet interface because there is more overhead (e.g., time delays) involved in crossing a T1 interface.[5]
Characteristic features of OSPF Link State Based Runs directly over IP Interior or border gateway protocol Multiple paths to each destination. Load balancing. Link-attribute based costing. Costing is statically assigned. [6]
123
9. Click OK. 10. Place ten slip8_gtwys in the workspace as in figure 117. 11. Change the object palette to internet_toolbox.
12. Connect all the routers using PPP_DS3 link as in figure 117.
124
13. Rename all the routers as in figure 117. Right click on each router and select Set Name from the pop up menu.
125
Method
Protocols IP Routing Configure Routing Protocols menu operation
Characteristics
Any number of interfaces can be configured at the same time Overwrites the IP Routing Parameters Interface Information Routing Parameters attribute Multiple routing protocols can be specified. Only one interface can be configured at a time.
When to Use
In most cases.
IP Routing Parameters Interface Information Routing Protocols IP Dynamic Routing Protocol simulation attribute
When one wants to add a protocol to those already designated on a particular interface. You have configured the routing protocols in your network but want to see the effects of running a single protocol throughout the network.
Does not modify router attributes Overrides the routing protocols configured on the router interfaces for the duration of the simulation One routing protocol used on all interfaces When this attribute is set to Default, the protocols specified on the router interfaces are used.
The easiest way to designate routing protocols is the Configure Routing Protocols IP Routing menu. This operation has the same effect operation from the Protocols as manually setting the interface routing protocol attributes, but with the added advantage of being able to configure multiple interfaces at the same time. The previous setting on the interface is overwritten each time this operation is used. 1. Open the Protocols menu.
Tommy Svensson Alex Popescu
IP
Routing
126
2. Check the OSPF check box. Figure 118. 3. Select the All interfaces radio button. Figure 118.
127
A Routing Domain Legend appears in the bottom left corner on the workspace. All links should have a green O attached to it. This indicates that OSPF routing protocol is used over that link. Figure 119.
128
129
B. Globally for all interfaces: If wanted to change the interface cost across all interfaces, then, rather than individually setting them on each interface, one can use the model-wide cost configuration option using the following menu option: Protocols OSPF Configure Interface Cost. This operation will allow for choosing one of the following two cost configuration options: B1) The Reference Bandwidth will be set for all routers. All interfaces will be set with a cost value of Auto Calculate. B2) All interfaces will be set with the specified cost value. The interface/bandwidth settings will be ignored.
In this lab we use different bandwidths on the links to set different costs. 1. Select the links between: Router A Router B Router B Router D Router D Router C Router C Router A Router B Router C by shift clicking on them. 2. Open the Configure Interface Metric Information dialog. Protocols Routing Configure Interface Metric Information. 3. Set the Bandwidth value to 5000 kbps. 4. Select Interfaces across selected links radio button. Click OK. 5. Select the links between: Router B Router E Router E Router G Router I Router F Router F Router D Router E Router F by shift clicking on them.
Tommy Svensson Alex Popescu
IP
130
6. Open the Configure Interface Metric Information dialog. Protocols Routing Configure Interface Metric Information. 7. Set the Bandwidth value to 20000 kbps. 8. Select Interfaces across selected links radio button. Click OK. 9. Select the links between: Router G Router H Router H Router J Router J Router I Router I Router G Router G Router J by shift clicking on them. 10. Open the Configure Interface Metric Information dialog. Protocols Routing Configure Interface Metric Information. 11. Set the Bandwidth value to 10000 kbps. 12. Select Interfaces across selected links radio button. Click OK. 13. Save the project. The cost configuration looks as in figure 123:
IP
IP
131
Configure Simulation
1. 2. 3. 4. Open the Configure Discrete Event Simulation dialog. Set duration to 10 minutes. Click OK. Save the project.
Areas scenario
The major addition in OSPF configuration, relative to other protocols, is that the OSPF routing domain can be divided into smaller segments called areas. This reduces memory and computational load on the routers. Each area is numbered and there must always be an area zero, which is the backbone. All other areas attach to the backbone either directly or via virtual links. An area should contain no more than about 50-100 routers for optimum performance. A router that connects to more than one area is called an Area Border Router (ABR). 1. Duplicate the scenario. Scenarios 2. Name the scenario Areas.
Duplicate scenario
Partition the network into areas. This is a physical partitioning in the sense that an interface can belong to only one area. The distinct interfaces of the same router may still belong to separate areas.
Tommy Svensson Alex Popescu 132
3. Select the links between: Router A Router B Router B Router D Router D Router C Router C Router A Router B Router C by shift clicking on them. OSPF 4. Open the OSPF Area Configuration dialog. Protocols Areas. 5. Set the value 1 to Area Identifier. 6. Click OK. 7. Select the links between: Router B Router E Router E Router G Router I Router F Router F Router D Router E Router F by shift clicking on them. OSPF 8. Open the OSPF Area Configuration dialog. Protocols Areas. 9. Set the value 0 to Area Identifier. 10. Click OK. 11. Select the links between: Router G Router H Router H Router J Router J Router I Router I Router G Router G Router J by shift clicking on them. OSPF 12. Open the OSPF Area Configuration dialog. Protocols Areas. 13. Set the value 2 to Area Identifier. 14. Click OK. OSPF Visualize Areas 15. Visualize the areas. Protocols 16. Click OK in the pop-up dialog. 17. Save the project. The areas are visualized in different colors.
Configure
Configure
Configure
Balanced Scenario
Load balancing is a concept that allows a router to take advantage of multiple best paths (routes) to a given destination. If two routes to the same destination have the same cost, the traffic will be distributed half to each.
133
1. Go back to the NoAreas scenario. Scenarios Switch To Scenario NoAreas. 2. Duplicate the scenario. Scenarios Duplicate scenario 3. Name the scenario Balanced. 4. Select both Router C and Router J by shit clicking on them. IP 5. Open the Configure Load Balancing Option dialog. Protocols Routing Configure Load Balancing Option. 6. Select Packet based in the roll-down menu. 7. Select the Selected Routers radio button. 8. Click OK. 9. Save the project.
4. Click OK to run the simulation. 5. Click Close when the simulation has finished.
134
135
6. 7. 8. 9.
Change the Display attribute for Router B Router D to No. Expand Sources Router C Router J. Select Router C Router J. Change the Display attribute to Yes. Figure 128.
136
Areas scenario
1. Switch to the Areas scenario. Scenarios Switch to Scenario 2. Open the Route Report for IP Traffic Flows dialog. Protocols Demands Display Routes for Configured Demands Router B Router D. 3. Expand Sources 4. Select Router B Router D. 5. Change the Display attribute to Yes. The traffic flow should look like figure 130.
Areas. IP
137
Balanced scenario
1. Switch to the Balanced scenario. Scenarios Switch to Scenario Balanced. IP Demands 2. Open the Route Report for IP Traffic Flows dialog. Protocols Display Routes for Configured Demands Router C Router J. 3. Expand Sources 4. Select Router C Router J. 5. Change the Display attribute to Yes.
138
Overview
In this lab we will look at one aspect of the DS (Differentiated Services) architecture which is queue management and traffic shaping. The simulation package OPNET has been used in this study. Based on the DS value, packets may be put in separate queues, and various forwarding policies can be used to favor high priority packets in different ways. The policies that are studied here are: FIFO (First In First Out), PQ (Priority Queuing), WFQ (Weighted Fair Queuing).
Procedure
Originally, the Internet was designed for data processing applications where delays were relatively unimportant. In most cases a best effort delivery service was adequate, and in case of loss or corruption of data, the TCP protocol would take care of the necessary retransmission and recovery. Nowadays these requirements have been changed due to the growth of multimedia application which are bandwidth hungry and require megabits per second rather than the kilobits per second required for traditional data processing applications. Todays application are more or less sensitive for the delays experienced when transmitting over Internet. It is therefore important to keep track of the delay and delay variation or jitter and insure that they dont grow to big. There is thus a need to support a variety of traffic with different quality of service (QoS). The central issue is how to share available resources in times of congestion. For doing this, diverse mechanisms are needed to differentiate between different types of traffic (priority).
139
Copy files
1. Copy the model files from the CD-ROM and place them on the hard drive. 2. Edit the Opnet environment file, env_db9.0. On Windows XP it is located in C:\Documents and Settings\<profile>\op_admin 3. Add the path where the files are placed to mod_dirs.
140
FIFO queuing
First-in-first-out (FIFO) is the simplest type of queuing. The incoming packets are placed in a single queue and are served in the order as they where received. This queuing policy requires very little computation and its behavior is very predicable, i.e. packet delay is a direct function of the queue size. There are many undesirable properties related to this queuing policy, due to the simplistic nature.
It is impossible to offer different services for different packet classes since all packets are inserted into the same queue. If an incoming flow suddenly becomes bursty, then it is possible for the entire buffer space to be filled by this single flow and other flows will not be serviced until the buffer is emptied.
141
4. 5. 6. 7. 8.
Open the Object palette. Click the Configure palette button. Clear the palette. Click the Clear button. Choose which node models to include. Click the Node models button. Include ta_fifo node model. Click OK.
9. Click SAVE in the Configure Palette dialog. Use the default filename. 10. Click OK to close the Configure Palette dialog. 11. Click and drag ta_fifo node model from the Object palette to the workspace. 12. Right click on node model in the workspace and choose set name. Set the name to fifo_infinite_buffer. 13. Double click on the fifo node model. The node model that appears should resemble the one in figure 135. The model has three packet sources which generates packets to the fifo_queue. The packets in the queue are served by fifo (First In First Out) queue discipline and sent to the sink, where they are destroyed.
142
14. Right click on source_1 and choose Edit attributes 15. Verify the values with figure 136. 16. Click OK to close the attribute dialog.
143
18. Right click on fifo_queue and choose Edit attributes 19. Right click on subqueue attribute and choose Promote to higher level. 20. Click OK to close the attribute dialog.
21. Close the node model window. Save the changes. 22. Right click on the fifo node and choose Edit attributes row 0. 23. Expand fifo_queue.subqueue 24. Set both bit capacity and pk capacity to infinity.
144
Duplicate scenario
26. Duplicate the scenario. Choose scenarios or use shortcut key Ctrl + Shift + D.
duplicate Scenario (Figure 139)
27. Enter the name fifo_finite_buffer. 28. Right click on the fifo node and choose Edit attributes row 0. 29. Expand fifo_queue.subqueue 30. Set bit capacity to infinity and pk capacity to 20.
145
Collect statistics
32. Right click on the fifo node. 33. Select Choose individual statistics. fifo_queue queue. 34. Expand Module statistics 35. Check overflow, queue size and queue delay statistics.
36. Right click on the overflow statistic and choose Change collection mode.
37. Check the Advanced checkbox. 38. Change Collection mode to all values.
Figure 143 - Statistics capture mode Tommy Svensson Alex Popescu 146
39. Click OK. 40. Repeat the same procedure for Queue size (packet) and Queue delay statistics. 41. Click OK to close the dialog. Switch to scenario 42. Switch to scenario fifo_infinite_buffer. Scenarios fifo_infinite_buffer. 43. Choose the same statistics and capture mode as in fifo_finite_buffer scenario.
47. Click OK and wait for the simulation to finish. 48. Close the simulation sequence dialog.
147
54. Repeat the same procedure for queue delay statistics. 55. Check overflow statistic. 56. Choose differentiator in the middle pull down menu. Figure 146. 57. Choose select scenarios in the right pull down menu. Figure 146. 58. Click Show. 59. Uncheck fifo_infinite_buffer and check fifo_finite_buffer and click OK.
148
Figure 147 - Fifo Queue size (packet) for infinite and finite buffers
149
Figure 148 - Fifo queue delay for infinite and finite buffers
150
151
Priority queuing
A simple way of offering different services to different classes of packets is Priority Queuing. Its operation involves classifying each incoming packet into different priorities and placing them into separate queues accordingly. The packets that have the highest priority are transmitted on the output port before the packets with lower priority. Even though this queuing policy is a good way of providing differentiated service, it also has some shortcomings, like large continuous flow of high priority traffic into the queue, equals excessive delay, and perhaps even service starvation for lower priority packets. Further, in our case we make use of both a non-preemptive priority network and a preemptive priority network. The difference between a so-called non-preemptive priority queuing discipline and a preemptive priority queuing discipline is that the transmission of a packet in a non-preemptive queuing discipline is not interrupted once it has begun.
152
10. Click Save and use the default filename. 11. Click OK to close the dialog. 12. Click and drag jsd_prio node model from the Object palette to the workspace. set name. 13. Change the name on the node to nonpreemptive. Right click 14. Double click on the node. 15. Right click on source_1 and choose Edit attributes 16. Set: ia_time to 1 instruction_range to 9600 priority_range to 0 17. Click OK. 18. Right click on source_2 and choose Edit attributes 19. Set: ia_time to 1 instruction_range to 9600 priority_range to 1 20. Click OK. 21. Right click on source_3 and choose Edit attributes 22. Set: ia_time to 1 instruction_range to 9600 priority_range to 2 23. Click OK. 24. Right click on nonpreemptive_priority_queue and choose Edit attributes
153
26. Click OK. 27. Close the node model and save the changes.
154
28. Right click on the node and select Choose Individual Statistics. 29. Check the statistics as in figure 152. 30. Change Statistic collection mode to All values. Right click on the statistic and choose Change collection mode. 31. Click OK to close the Choose Result dialog.
Figure 152 - Choose individual statistics for nonpreemtive priority queue model
155
48. Click OK. 49. Close the node model and save the changes. 50. Right click and select Choose individual statistics. 51. Choose the same statistics as in nonpreemptive scenario. Dont forget to change statistic collection mode to all values.
156
157
58. Click Create a graph of a statistic button. <initials>_priority_queue-non_preemptive 59. Expand File statistics Object Statistics nonpreemptive nonpreemptive_priority_queue. Figure 154.
158
61. Choose Statistics Overlaid and time_average in the pull down menus at the bottom.
159
160
63. Expand File statistics <initials>_priority_queue-preemptive Object Statistics preemptive preemptive_priority_queue. Figure 158.
65. Choose Statistics Overlaid and time_average in the pull down menus at the bottom.
161
162
70. Click OK. 71. Close the node model and save the changes. 72. Right click on the preemptive node and select Choose Individual Statistics. preemptive_priority_queue.subqueue[0] 73. Expand Module Statistics queue. 74. Check overflows statistic. 75. Right click on the overflows statistics and choose Change Collection Mode. 76. Set Capture mode to All values. 77. Repeat the same procedure on subqueue[1] and subqueue[2].
96. Click Create a graph of a statistic button. <initials>_priority_queue-non_preemptive 97. Expand File statistics Object Statistics nonpreemptive nonpreemptive_priority_queue. Figure 64.
164
99. Choose Statistics Overlaid and differentiator in the pull down menus at the bottom.
165
166
101. Expand File statistics <initials>_priority_queue-preemptive Object Statistics preemptive preemptive_priority_queue. Figure 168.
103. Choose Statistics Overlaid and differentiator in the pull down menus at the bottom.
168
4. 5. 6. 7. 8.
Open the Object palette. Click the Configure palette button. Clear the palette. Click the Clear button. Choose which node models to include. Click the Node models button. Include ta_wfq_node_model. Figure 173.
169
9. Click OK. 10. Click Save and use the default filename. 11. Click OK. 12. Click on ta_wfq_node_model in the object palette and drag it into the workspace. 13. Right click on the node and choose Set name. 14. Set the name wfq and click OK. 15. Enter the wfq node. Double click on it. 16. Right click on source_1 and choose Edit Attributes ia_time to 1 17. Set instruction_range to 1 priority_range to 0 18. Click OK. 19. Right click on source_2 and choose Edit Attributes ia_time to 1 20. Set instruction_range to 1 priority_range to 1 21. Click OK. 22. Right click on source_3 and choose Edit Attributes ia_time to 1 23. Set instruction_range to 9600 priority_range to 2 24. Click OK. 25. Right click on wfq_queue and choose Edit Attributes processing_rate to 30000 26. Set queue_weight0 to 50 queue_weight1 to 30 queue_weight2 to 20 27. Set the rows attribute value to 3 28. Set Row 0 Bit capacity to infinity.
Tommy Svensson Alex Popescu 170
Pk capacity to infinity. Bit capacity to infinity. Pk capacity to infinity. Bit capacity to infinity. Pk capacity to infinity.
171
30. Right click the wfq node and select Choose Individual Statistics. 31. Choose the statistics as in Figure 175. queue 32. Right click subqueue[0] queue size (packets) and choose Change collection mode. 33. Change Capture mode to all values. 34. Click OK to close capture mode dialog. 35. Click OK to close Choose Results dialog.
172
173
174
48. Click OK. 49. Close the node model and save the changes. 50. Right click the wfq node and select Choose Individual Statistics. wfq_queue wfq_queue.subqueue[0] 51. Include Module statistics overflows and change the colletion mode to all values. wfq_queue wfq_queue.subqueue[1] 52. Include Module statistics overflows and change the colletion mode to all values. wfq_queue wfq_queue.subqueue[2] 53. Include Module statistics overflows and change the colletion mode to all values. 54. Click OK.
175
176
177
Laboratory 7 Self-Similar
Objective
The purpose of this lab is to understand self-similarity on physical grounds in a realistic network environment. This understanding is important when developing efficient and integrated network frameworks within which end-to-end QoS guarantees are fully supported.
Overview
Self-similar traffic has been shown to exist in networks and it seems to be a ubiquitous phenomenon that is independent of technology, protocol and environment. In this laboratory moment we will study and compare the performance of an Ethernet segment run with heavy-tail traffic and with exponential traffic. The performance parameters considered here are link utilization and e2e delay. The laboratory moments are as follows: Creation of the network model Running the simulation with different ON-OFF models Plotting and comparing the results
178
Procedure
A self-similar phenomenon represents a process displaying structural similarities across a wide range of scales of a specific dimension. In other words, the reference structure is repeating itself over a wide range of scales and the (main) statistics of the process do not change. However, these properties do not hold indefinitely for real phenomena and at some point, this structure breaks down. Self-similarity can therefore be associated with fractals which are objects with unchanged appearances over different scales. A stochastic process is called fractal when a number of relevant statistics exhibit scaling with related scaling exponents. Since scaling leads mathematically to power-law relationships in the scaled quantities the conclusion is therefore that the traffic shows fractal properties when several estimated statistics exhibit power-law behaviour over a wide range of time scales [8]. A continuous-time stochastic process X(t) is considered to be statistical self-similar with parameter H(0.5 H 1.0) if, for any real positive a, the process a-Hx(at) has the same statistical properties as x(t). This relationship may be expressed by the following three conditions: E[x(t)] = E[x(at)] / aH Var[x(t)] = Var[x(at)] / a2H Rx(t,s) = Rx(at,as) /a2H mean variance autocorrelation
The parameter H is known as the Hurst parameter, or the self-similarity meter, and it is a key measure of self-similarity. More precisely H is a measure of the persistence of a statistical phenomenon and it is the measure of the length of the long-range dependence of a stochastic process. A value of H=0.5 indicates the absence of long-range dependence. The closer H is to 1 the greater the degree of persistence or long-range dependence.
179
7. Review the chosen values. Click OK. 8. Open the Object palette if its not already open. 9. Place two Ethernet_rpg_station nodes in the workspace. Figure 182.
10. Name the first node model PowOn-PowOff source and the second one PowOnPowOff receiver. Right click and choose Set Name. 11. Change the Object palette to ethernet_advanced. Figure 183.
180
13. Name the first node model Exponential source and the second one Exponential_receiver. Right click and choose Set Name. 14. Place two ethernet16_hub_adv in the workspace.
15. Name the first hub PowON-PowOFF Hub and the second hub Exponential Hub. Right click and choose Set Name. 16. Use 10BaseT_int link model to the following connections. PowOn-PowOff_source PowON-PowOFF Hub PowON-PowOFF Hub PowOn-PowOff receiver
Exponential source Exponential Hub Exponential Hub Exponential_receiver
181
17. Right click on PowOn-PowOff source and choose Edit Attributes... 18. Set the attributes as in Figure 188.
182
19. Click OK to close the attributes dialog. 20. Select the PowOn-PowOff network and press <CTRL>+C 21. Paste two copies on the workspace. Press <CTRL>+V to place a copy next to the original. 22. Rename the nodes. PowOn-PowOff source_0 to ExpOn-PowOff source PowOn-PowOff Hub_0 to ExpOn-PowOff Hub PowOn-PowOff Receiver_1 to ExpOn-PowOff Receiver
PowOn-PowOff source_1 to PowOn-ExpOff source PowOn-PowOff Hub_1 to PowOn-ExpOff Hub PowOn-PowOff Receiver_1 to PowOn-ExpOff Receiver
Tommy Svensson Alex Popescu 183
23. Right click on ExpOn-PowOff source and choose Edit Attributes... 24. Set the attributes as in Figure 189.
184
26. Right click on PowOn-ExpOff source and choose Edit Attributes... 27. Set the attributes as in Figure 190.
185
29. Right click on PowOn-ExpOff source and choose Edit Attributes... 30. Set the attributes as in Figure 191.
31. Click OK to close the dialog. 32. Right click on PowOn-ExpOff source and choose Edit Attributes... 33. Set the attributes as in Figure 192.
186
35. Right click on PowOn-PowOff source and choose Edit Attributes... 36. Set the attributes as in Figure 193.
37. Click OK to close the dialog. 38. Right click on Exponential source and choose Edit attributes 39. Set the attributes as in Figure 194.
187
41. Right click on Exponential receiver and choose Edit attributes 42. Set the attributes as in Figure 195.
43. Click OK to close the dialog. The final network should resemble figure 196.
188
44. Right click on the workspace and choose Select Individual Statistics. Ethernet. 45. Expand Node statistics 46. Choose Delay (sec) and Utilization statistics.
189
190
191
192
193
194
Conclusions throughput
ExpON-PowOff
Fluctuations are much higher at traffic with heavytail than at traffic with exponential only.
Exponential
Average throughput is more variable at ExpOn-PowOff. It is seen that OFF is heavytail.
Conclusions delay
ExpON-PowOff
It is clear that we have PowOff, long periods with very small delays
Exponential
It is clear that it is exponential only, small variations.
195
Concluding Remarks
This thesis consists of five laboratory exercises that cover a range of important topics in networking and telecommunications. The students are provided an opportunity to experience the behavior of different networks and protocols but also a chance to learn the basic procedures of network simulation by using the OPNET Modeler simulation environment. This is today the most cost effective solution for universities to demonstrate the behavior of different networks and protocols.
Acknowledgments
We would like to take this opportunity and thank the Department of Telecommunications and Signal Processing at the Blekinge Institute of Technology. We would also especially like to thank Prof: Arne Nilsson and Docent: Adrian Popescu for giving us the opportunity to work with such interesting and challenging topics. Finally we would like to give special thanks to the Ph.D. students: Doro Constantinescu, Dragos Ilie, David Erman and Lennart Isaksson for their help and support.
196
Glossary
ACK - Acknowledge ATM Asynchronous Transfer Mode CSMA - Carrier Sensing Multiple Access CSMA-CD - Carrier Sensing Multiple Access with Collision Detection cwnd - congestion window EIGRP Enhanced Interior Gateway Routing Protocol E-mail Electronic mail FIFO First in First Out FSM - Finite State Machines FTP File Transfer Protocol IGP Interior Gateway Protocol IGRP Interior Gateway Routing Protocol IP Internet Protocol LAN Local Area Network M/M/1 Markov/Markov/1 queue MAC - Medium Access Control MPLS Multiprotocol Label Switching OPNET - Optimized Network Engineering Tools OSPF Open Shortest Path First RIP Routing Internet Protocol RTT Round Trip Time Segsize Segment Size SMSS - Sender Maximum Segment Size ssthresh - slow start threshold TCP Transmission control protocol WAN Wide Area Network
197
References
[1] [2] [3] [4]
URL: http://www.opnet.com/products/modeler/home.html (2003-05-31) URL: http://www.ietf.org/rfc/rfc2001.txt?number=2001 (2003-05-31) URL: http://www.ietf.org/rfc/rfc2581.txt?number=2581 (2003-05-31)
Modeling and Simulating Communication Networks Irene Katzela Published: Prentice Hall, Inc. 1999 ISBN: 0-13-915737-9 Advanced IP Routing In Cisco Networks Terry Slattery and Bill Burton Published: The McGraw-Hill Companies, Inc. 2000 ISBN: 0-07-212591-8 OPNET Online Documentation IP Model Description Kteori och tillfrlitlighetsteori Ulf Krner Published: Ulf Krner and Studentlitteratur 1992, 1997 ISBN: 91-44-00480-X Traffic Self-Similarity technical report Adrian Popescu BTH 2000
[5]
[6] [7]
[8]
198
Appendix 1
/* Process model C form file: jsd_prio.pr.c */ /* This variable carries the header into the object file */ static const char jsd_prio_pr_c [] = "MIL_3_Tfile_Hdr_ 90A 30A modeler 7 3F55FAD2 3F55FAD2 1 its-2503-5 exjobb 0 0 none none 0 0 none 0 0 0 0 0 0 "; #include <string.h>
/* OPNET system definitions */ #include <opnet.h> #if defined (__cplusplus) extern "C" { #endif FSM_EXT_DECS #if defined (__cplusplus) } /* end of 'extern "C"' */ #endif /* Header Block */ #include <stdlib.h> typedef struct { int job_type; double job_size; } JsdT_Job_Desc; #define QUEUE_EMPTY #define ARRIVAL #define SVC_COMPLETION op_q_empty () op_intrpt_type () == OPC_INTRPT_STRM op_intrpt_type () == OPC_INTRPT_SELF 0 /* Success codes for /* atoi(), atof() */
#define GET_INST_SUCCESS get_instructions () function */ #define GET_INST_NO_JOB_TYPE -1 #define GET_INST_NO_JOB_TABLE -2 #define GET_INST_NO_ENTRY #include "jsd_win_avg.ex.h" int void
-3
/* End of Header Block */ #if !defined (VOSD_NO_FIN) #undef BIN Tommy Svensson Alex Popescu 199
Master thesis MEE 03:24 #undef BOUT #define BIN FIN_LOCAL_FIELD(last_line_passed) = __LINE__ _block_origin; #define BOUT BIN #define BINIT FIN_LOCAL_FIELD(last_line_passed) = 0; _block_origin = __LINE__; #else #define BINIT #endif /* #if !defined (VOSD_NO_FIN) */
/* State variable definitions */ typedef struct { /* Internal state tracking for FSM */ FSM_SYS_STATE /* State Variables */ int server_busy; int table_exists; int num_lines; double processing_rate; double last_update_time; double total_busy_time; double work_left_last; double total_work; double total_delay; double num_pks_serviced; double win_size; JsdT_Win_Stat_Hndl* Util_Stat_Hndl; JsdT_Win_Stat_Hndl* Work_Left_Stat_Hndl; Objid own_id; Evhandle svc_complete; JsdT_Job_Desc* Job_Desc_Table; Stathandle busy_signal_shandle; Stathandle inst_delay_shandle; Stathandle inst_wk_left_shandle; Stathandle normalized_delay_shandle; Stathandle mean_util_shandle; Stathandle avg_thruput_shandle; Stathandle mean_delay_shandle; } jsd_prio_state; #define pr_state_ptr SimI_Mod_State_Ptr) #define server_busy #define table_exists #define num_lines #define processing_rate #define last_update_time #define total_busy_time #define work_left_last #define total_work #define total_delay #define num_pks_serviced #define win_size #define Util_Stat_Hndl Tommy Svensson Alex Popescu ((jsd_prio_state*) pr_state_ptr->server_busy pr_state_ptr->table_exists pr_state_ptr->num_lines pr_state_ptr->processing_rate pr_state_ptr->last_update_time pr_state_ptr->total_busy_time pr_state_ptr->work_left_last pr_state_ptr->total_work pr_state_ptr->total_delay pr_state_ptr->num_pks_serviced pr_state_ptr->win_size pr_state_ptr->Util_Stat_Hndl 200
Master thesis MEE 03:24 #define Work_Left_Stat_Hndl >Work_Left_Stat_Hndl #define own_id #define svc_complete #define Job_Desc_Table #define busy_signal_shandle >busy_signal_shandle #define inst_delay_shandle >inst_delay_shandle #define inst_wk_left_shandle >inst_wk_left_shandle #define normalized_delay_shandle >normalized_delay_shandle #define mean_util_shandle >mean_util_shandle #define avg_thruput_shandle >avg_thruput_shandle #define mean_delay_shandle >mean_delay_shandle pr_state_ptrpr_state_ptr->own_id pr_state_ptr->svc_complete pr_state_ptr->Job_Desc_Table pr_state_ptrpr_state_ptrpr_state_ptrpr_state_ptrpr_state_ptrpr_state_ptrpr_state_ptr-
/* This macro definition will define a local variable called */ /* "op_sv_ptr" in each function containing a FIN statement. */ /* This variable points to the state variable data structure, */ /* and can be used from a C debugger to display their values. */ #undef FIN_PREAMBLE #define FIN_PREAMBLE jsd_prio_state *op_sv_ptr = pr_state_ptr; /* Function Block */ enum { _block_origin = __LINE__ }; int jsd_prio_get_instructions (pkptr, pk_inst_ptr) Packet* pkptr; double* pk_inst_ptr; { int job_type, i; /** This function takes as input a pointer to a packet, and returns **/ /** a double corresponding to the number of instructions in the **/ /** packet. If the instructions field in the packet is not set, the **/ /** function determines the number of instructions by getting the **/ /** type of the job from the job_type field of the packet, and **/ /** looking up the number of instructions for that type of job in **/ /** the Job_Desc_Table, which has been read in from an external file **/ /** in the init state. **/ FIN (jsd_prio_get_instructions (pkptr, pk_inst_ptr));
201
Master thesis MEE 03:24 /* Get the number of instructions directly */ /* from the named field in the packet. */ if (op_pk_nfd_get (pkptr, "instructions", pk_inst_ptr) == OPC_COMPCODE_FAILURE) jsd_prio_error ("Unable to get instructions field from packet."); FRET (GET_INST_SUCCESS);
} void jsd_prio_error (msg) char* msg; { /** Print an error message and exit the simulation. **/ FIN (jsd_prio_error (msg)); op_sim_end ("Error in JSD priority process (jsd_prio):", msg, OPC_NIL, OPC_NIL); FOUT; } /* End of Function Block */ /* Undefine optional tracing in FIN/FOUT/FRET */ /* The FSM has its own tracing code and the other */ /* functions should not have any tracing. */ #undef FIN_TRACING #define FIN_TRACING #undef FOUTRET_TRACING #define FOUTRET_TRACING #if defined (__cplusplus) extern "C" { #endif void jsd_prio (void); Compcode jsd_prio_init (void **); void jsd_prio_diag (void); void jsd_prio_terminate (void); void jsd_prio_svar (void *, const char *, char **); #if defined (__cplusplus) } /* end of 'extern "C"' */ #endif
/* Process model interrupt handling procedure */ void jsd_prio (void) Tommy Svensson Alex Popescu 202
Master thesis MEE 03:24 { int _block_origin = 0; FIN (jsd_prio ()); if (1) { Packet* Packet* Objid int int int int int int int int int double double double double double double double double double double Objid Objid char char* int int double double pkptr; low_pkptr; orig_id; orig_port; insert_ok; svc_time_determined; success_code; i; pkid; num_pkts; position; sub_q_no; pk_instructions; pk_svc_time; low_pk_svc_time; time_in_processor; svc_start; original_svc_time; processing_delay; mean_util; avg_throughput; mean_proc_delay; job_type_table_id; line_id; err_str [256]; line; dval; job_type; instructions; pk_prio;
-----*/
/** state (init) enter executives **/ FSM_STATE_ENTER_FORCED_NOLABEL (0, "init", "jsd_prio [init enter execs]") FSM_PROFILE_SECTION_IN ("jsd_prio [init enter execs]", state0_enter_exec) { /** These executives are encountered only once, at the beginning of the simulation. **/ /** Their purpose is to initialize the process model. The attributes of this particular **/ /** module are determined and state variables are initialized. If a job_type_filename **/ Tommy Svensson Alex Popescu 203
Master thesis MEE 03:24 job description table. /** was set, the file is read and parsed into a **/ /* Initially the server is idle. */ server_busy = 0; /* Get queue module's own object id. */ own_id = op_id_self (); */ /* Get assigned value of server processing rate.
if (op_ima_obj_attr_get (own_id, "processing_rate", &processing_rate) == OPC_COMPCODE_FAILURE) jsd_prio_error ("Unable to get processing rate from attribute."); windowed stats. */ /* Get assigned value of the window size for
if (op_ima_obj_attr_get (own_id, "win_size", &win_size) == OPC_COMPCODE_FAILURE) jsd_prio_error ("Unable to get window size from attribute."); statistics. */ /* Initialize some state variables dealing with last_update_time = op_sim_time (); total_busy_time = 0.0; work_left_last = op_sim_time (); total_work = 0.0; /* Initialize the structures for the windowed
stats. */
Util_Stat_Hndl = jsd_win_avg_create ("Jsd Windowed Utilization", win_size, OPC_STAT_LOCAL); Work_Left_Stat_Hndl = jsd_win_avg_create ("Jsd Windowed Work Left (sec)", win_size, OPC_STAT_LOCAL); /* Set the table exists flag. */ table_exists = 1; /* Register Statistics. */ busy_signal_shandle = op_stat_reg ("Jsd Busy Signal", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); inst_delay_shandle = op_stat_reg ("Jsd Instantaneous Delay (sec)", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); inst_wk_left_shandle = op_stat_reg ("Jsd Instantaneous Work Left (sec)", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); normalized_delay_shandle = op_stat_reg ("Jsd Normalized Delay", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); mean_util_shandle = op_stat_reg ("Jsd Total Busy Time", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); avg_thruput_shandle = op_stat_reg ("Jsd Total Work", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); mean_delay_shandle = op_stat_reg ("Jsd Mean Delay (sec)", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); } Tommy Svensson Alex Popescu 204
Master thesis MEE 03:24 FSM_PROFILE_SECTION_OUT ("jsd_prio [init enter execs]", state0_enter_exec) /** state (init) exit executives **/ FSM_STATE_EXIT_FORCED (0, "init", "jsd_prio [init exit
execs]")
FSM_PROFILE_SECTION_IN ("jsd_prio [init exit execs]", state0_exit_exec) { } FSM_PROFILE_SECTION_OUT ("jsd_prio [init exit execs]", state0_exit_exec) /** state (init) transition processing **/ FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "init", "idle") /*--------------------------------------------------------*/
/** state (idle) enter executives **/ FSM_STATE_ENTER_UNFORCED (1, state1_enter_exec, "idle", "jsd_prio [idle enter execs]") FSM_PROFILE_SECTION_IN ("jsd_prio [idle enter execs]", state1_enter_exec) { } FSM_PROFILE_SECTION_OUT ("jsd_prio [idle enter execs]", state1_enter_exec) **/ /** blocking after enter executives of unforced state. FSM_EXIT (3,jsd_prio) /** state (idle) exit executives **/ FSM_STATE_EXIT_UNFORCED (1, "idle", "jsd_prio [idle
exit execs]")
FSM_PROFILE_SECTION_IN ("jsd_prio [idle exit execs]", state1_exit_exec) { /** These executives are encountered whenever there is a stream interrupt (arrival), or a **/ /** self interrupt (service completion). In either case, we want to record some statistics. **/ /** If the server is busy at this point, we will want to record a 1.0 for each statistic from **/ /** the last update time until the current update time. If the server is free, we will want **/ /** to record a 0.0. Thus we will use the value of server_busy as the value to record. **/ Tommy Svensson Alex Popescu 205
/* Update the busy signal. */ op_stat_write_t (busy_signal_shandle, server_busy, last_update_time); /* Update the windowed utilization statistic. */ jsd_win_avg_update (Util_Stat_Hndl, (double) /* Prevent rounding off errors, if any. */ if (work_left_last < 0) work_left_last = 0; /* Update the statistic for the instantaneous total amount of unfinished work in the queue. */ op_stat_write_t (inst_wk_left_shandle, work_left_last, last_update_time); /* Update the statistic for the windowed unfinished work in the queue. */ jsd_win_avg_update (Work_Left_Stat_Hndl, work_left_last); work_left_last -= (server_busy * (op_sim_time () - last_update_time)); /* Add to the total_busy_time for use by the mean_utilization stat. */ total_busy_time += (server_busy * (op_sim_time () - last_update_time)); /* Update the statistic. */ op_stat_write (mean_util_shandle, total_busy_time/ op_sim_time ()); event. */ /* Set the last_update_time for use by the next
server_busy);
last_update_time = op_sim_time (); } FSM_PROFILE_SECTION_OUT ("jsd_prio [idle exit execs]", state1_exit_exec) /** state (idle) transition processing **/ FSM_PROFILE_SECTION_IN ("jsd_prio [idle trans conditions]", state1_trans_conds) FSM_INIT_COND (SVC_COMPLETION) FSM_TEST_COND (ARRIVAL) FSM_TEST_LOGIC ("idle") FSM_PROFILE_SECTION_OUT ("jsd_prio [idle trans conditions]", state1_trans_conds) FSM_TRANSIT_SWITCH { FSM_CASE_TRANSIT (0, 4, state4_enter_exec, ;, "SVC_COMPLETION", "", "idle", "svc_comp")
206
Master thesis MEE 03:24 FSM_CASE_TRANSIT (1, 2, state2_enter_exec, ;, "ARRIVAL", "", "idle", "arrival") } /*--------------------------------------------------------*/
/** state (arrival) enter executives **/ FSM_STATE_ENTER_FORCED (2, state2_enter_exec, "arrival", "jsd_prio [arrival enter execs]") FSM_PROFILE_SECTION_IN ("jsd_prio [arrival enter execs]", state2_enter_exec) { /** These executives are encountered when a packet arrives on an input **/ /** stream. The incoming packet is enqueued in priority order in a subqueue. **/ /** If there is a packet already in service, it will not be preempted. **/ /* Acquire the arriving packet. /* Multiple arriving streams are supported. pkptr = op_pk_get (op_intrpt_strm()); if (pkptr == OPC_NIL) jsd_prio_error ("Unable to get packet from /** Determine the remaining service time of the /* If the svc_time field of the packet is set, /* read the remaining service time directly from
*/ */
if (op_pk_nfd_is_set (pkptr, "svc_time")) { if (op_pk_nfd_get (pkptr, "svc_time", &pk_svc_time) == OPC_COMPCODE_FAILURE) jsd_prio_error ("Unable to get remaining service time from packet."); /* Set a success flag to be used later. */ svc_time_determined = 1; } instructions */ /* Otherwise we need to determine the number of /* in the packet. */ else { /* Determine the number of instructions in
the packet. */
207
Master thesis MEE 03:24 (pkptr, &pk_instructions); successfully determined, success_code = jsd_prio_get_instructions /* If the number of instructions was */ /* compute the service time of the packet. */ if (success_code == GET_INST_SUCCESS) { pk_svc_time = pk_instructions / /* Since the svc_time field was not /* set it now for later statistical
if (op_pk_nfd_set (pkptr, "svc_time", pk_svc_time) == OPC_COMPCODE_FAILURE) jsd_prio_error ("Unable to set service time in packet."); later. */ else /* Set a success flag to be used svc_time_determined = 1; }
{ /* It was not possible to get the number of instructions from the packet. */ svc_time_determined = 0; determine mumber of instructions."); deallocate the packet. */ the packet and continuing."); sprintf (err_str, "Error: Unable to /* Print error messages and op_sim_message (err_str, "Dropping op_pk_destroy (pkptr);
/* Set flag to ensure that transition to svc_start does not occur. */ insert_ok = 0; } } successfully. */ /* Check whether the svc_time was determined if (svc_time_determined == 1) { /* Write the remaining service time into
the packet. */
if (op_pk_nfd_set (pkptr, "svc_time_remain", pk_svc_time) == OPC_COMPCODE_FAILURE) jsd_prio_error ("Unable to set remaining service time in packet."); Tommy Svensson Alex Popescu 208
Master thesis MEE 03:24 /* Set the svc_start field to the current
/* when the packet first entered the */ if (op_pk_nfd_set (pkptr, "svc_start", op_sim_time ()) == OPC_COMPCODE_FAILURE) jsd_prio_error ("Unable to set service start time in packet."); type is double! */ /* Get the packets priority, return
*/
pk_prio=op_pk_priority_get (pkptr);
/* Attempt to enqueue the packet in priority order in subqueue pk_prio. Typecasting pk_prio to int!! */ if (op_subq_pk_insert ((int)pk_prio, pkptr, OPC_QPOS_TAIL) != OPC_QINS_OK) { /* The insertion failed (due to a full queue). Determine the */ /* packet with the lowest priority and remove it from the queue. */ low_pkptr = op_subq_pk_remove ((int)pk_prio, OPC_QPOS_TAIL); if (low_pkptr == OPC_NIL) jsd_prio_error ("Unable to get lowest priority packet from subqueue."); /* Determine the remaining service */ if (op_pk_nfd_get (low_pkptr, "svc_time_remain", &low_pk_svc_time) == OPC_COMPCODE_FAILURE) jsd_prio_error ("Unable to get remaining service time from packet."); time of the low priority packet. the work left in the queue. */ /* Subtract this amount of time from work_left_last -= low_pk_svc_time; /* Deallocate the packet with the op_pk_destroy (low_pkptr);
lowest priority. */
/* Attempt to re-enqueue the new packet in priority order in subqueue pk_prio. */ if (op_subq_pk_insert ((int)pk_prio, pkptr, OPC_QPOS_TAIL) != OPC_QINS_OK) { /* The insertion failed again. Deallocate the new packet. */ op_pk_destroy (pkptr); insertion fail. This flag is used to this state. Tommy Svensson Alex Popescu /* Set flag indicating */ /* determine transition out of */ 209
Master thesis MEE 03:24 insert_ok = 0; } { /* Insertion was successful */ insert_ok = 1; /* Add the service time of the /* the work left in the queue, work_left_last += pk_svc_time; }
else
*/ */ }
else
{ /* Insertion was successful */ insert_ok = 1; /* Add the service time of the /* the work left in the queue, for work_left_last += pk_svc_time; }
*/
FSM_PROFILE_SECTION_OUT ("jsd_prio [arrival enter execs]", state2_enter_exec) /** state (arrival) exit executives **/ FSM_STATE_EXIT_FORCED (2, "arrival", "jsd_prio [arrival exit execs]") FSM_PROFILE_SECTION_IN ("jsd_prio [arrival exit execs]", state2_exit_exec) { } FSM_PROFILE_SECTION_OUT ("jsd_prio [arrival exit execs]", state2_exit_exec) /** state (arrival) transition processing **/ FSM_PROFILE_SECTION_IN ("jsd_prio [arrival trans conditions]", state2_trans_conds) FSM_INIT_COND (!server_busy && insert_ok) FSM_DFLT_COND FSM_TEST_LOGIC ("arrival") FSM_PROFILE_SECTION_OUT ("jsd_prio [arrival trans conditions]", state2_trans_conds) FSM_TRANSIT_SWITCH { FSM_CASE_TRANSIT (0, 3, state3_enter_exec, ;, "!server_busy && insert_ok", "", "arrival", "svc_start") FSM_CASE_TRANSIT (1, 1, state1_enter_exec, ;, "default", "", "arrival", "idle") Tommy Svensson Alex Popescu 210
-----------*/
/** state (svc_start) enter executives **/ FSM_STATE_ENTER_FORCED (3, state3_enter_exec, "svc_start", "jsd_prio [svc_start enter execs]") FSM_PROFILE_SECTION_IN ("jsd_prio [svc_start enter execs]", state3_enter_exec) { /** When entering these executives, there will be a packet at the **/ /** head of subqueue 0 that requires service. This state begins **/ /** service for the packet and schedules an interrupt for the **/ /** time of completion of service. **/ sub_q_no=0; for (i=2; i>=0; i--) { if (!op_subq_empty(i)) { sub_q_no=i; } } subqueue sub_q_no. /* Get a handle on the packet at the head of */ /* This does not remove the packet. */ pkptr = op_subq_pk_access (sub_q_no, if (pkptr == OPC_NIL) jsd_prio_error ("Unable to access packet /* Extract the remaining service time of the
if (op_pk_nfd_get (pkptr, "svc_time_remain", &pk_svc_time) == OPC_COMPCODE_FAILURE) jsd_prio_error ("Unable to get remaining service time from packet."); /* Schedule an interrupt for this process at the */ /* The packet id is used as the interrupt code, so that the packet can be */ /* identified in the queue at the time of its service completion interrupt. */ svc_complete = op_intrpt_schedule_self (op_sim_time () + pk_svc_time, op_pk_id (pkptr)); if (op_ev_valid (svc_complete) == OPC_FALSE) time where service ends.
211
Master thesis MEE 03:24 jsd_prio_error ("Unable to schedule self interrupt for service completion."); /* Make the server busy. */ server_busy = 1; } FSM_PROFILE_SECTION_OUT ("jsd_prio [svc_start enter execs]", state3_enter_exec) /** state (svc_start) exit executives **/ FSM_STATE_EXIT_FORCED (3, "svc_start", "jsd_prio [svc_start exit execs]") FSM_PROFILE_SECTION_IN ("jsd_prio [svc_start exit execs]", state3_exit_exec) { } FSM_PROFILE_SECTION_OUT ("jsd_prio [svc_start exit execs]", state3_exit_exec) /** state (svc_start) transition processing **/ FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "svc_start", "idle") /*--------------------------------------------------------*/
/** state (svc_comp) enter executives **/ FSM_STATE_ENTER_FORCED (4, state4_enter_exec, "svc_comp", "jsd_prio [svc_comp enter execs]") FSM_PROFILE_SECTION_IN ("jsd_prio [svc_comp enter execs]", state4_enter_exec) { /** These executives are encountered when a packet completes **/ /** service. They record some statistics, convert the packet **/ /** into an acknowledgement packet, and send it back to the **/ /** address specified by the the orig_id and orig_port fields **/ /** of the packet. **/ /* Determine the id of the packet just */ /* This is passed as the code associated with /* completion interrupt. */ pkid = op_intrpt_code ();
212
Master thesis MEE 03:24 /* Locate the packet and determine which subqueue it is located in and queue position. */ success_code=0; sub_q_no=0; position=0; for (sub_q_no=0;sub_q_no<3;sub_q_no++) { /* Determine the number of packets currently in the queue. */ dval = op_subq_stat (sub_q_no, OPC_QSTAT_PKSIZE); if (dval == OPC_DBL_INVALID) jsd_prio_error ("Unable to get number of packets in subqueue."); num_pkts = (int) dval; /* Determine if this packet is located in this subqueue. And if so,the queue position of this packet */ /* and obtain a pointer to it. */ position++) position); (pkptr) == pkid) for (position = 0; position < num_pkts; { pkptr = op_subq_pk_access (sub_q_no, if (pkptr != OPC_NIL && op_pk_id { success_code=1; break;
} } if (success_code==1) break; }
in fact obtained. */
if (position == num_pkts) op_sim_message ("Error: could not find packet in queue at svc_comp state.", ""); else { /* Extract the packet just finishing service. */ pkptr = op_subq_pk_remove (sub_q_no, position); if (pkptr == OPC_NIL) jsd_prio_error ("Unable to get packet from subqueue.");
213
Master thesis MEE 03:24 entered the processor processor. */ /* Determine when this packet first
/* and how long it has been in the */ if (op_pk_nfd_get (pkptr, "svc_start", &svc_start) == OPC_COMPCODE_FAILURE) jsd_prio_error ("Unable to get service start time from packet."); time_in_processor = op_sim_time () svc_start; this packet and how */ /* Determine the original service time of
/* much processing delay it has */ if (op_pk_nfd_get (pkptr, "svc_time", &original_svc_time) == OPC_COMPCODE_FAILURE) jsd_prio_error ("Unable to get original service time from packet."); experienced in the queue. original_svc_time; processing_delay = time_in_processor /* Prevent any rounding off errors. */ if (processing_delay < 0) processing_delay = 0.0; */ processing_delay); */ /* Write the processing delay statistic. op_stat_write (inst_delay_shandle, /* Write the normalized delay statistic.
if (original_svc_time > 0.0) op_stat_write (normalized_delay_shandle, time_in_processor / original_svc_time); processing delay and the the average delay statistic. /* Add to the counters for the total */ /* number of packets serviced for use by */ total_delay += processing_delay; num_pks_serviced++;
/* Write the mean delay statistic.*/ op_stat_write (mean_delay_shandle, total_delay / num_pks_serviced); completed by the queue statistic. */ */ /* Add to the counter of total work /* for use by the average throughput total_work += original_svc_time; /* Update the statistic. */
214
Master thesis MEE 03:24 total_work / op_sim_time ()); completion ack. */ OPC_COMPCODE_FAILURE) op_stat_write (avg_thruput_shandle, /* Convert the job packet to a job if (op_pk_nfd_set (pkptr, "ack", 1) == jsd_prio_error ("Unable to set
/* Extract the originator's object id and /* and deliver the ack packet to the
originator. */
if (op_pk_nfd_get (pkptr, "orig_id", &orig_id) == OPC_COMPCODE_FAILURE || op_pk_nfd_get (pkptr, "orig_port", &orig_port) == OPC_COMPCODE_FAILURE) { jsd_prio_error ("Unable to get originator's ID or port from packet."); } op_pk_deliver (pkptr, orig_id, orig_port); /* Make the server idle again. */ server_busy = 0;
} }
FSM_PROFILE_SECTION_OUT ("jsd_prio [svc_comp enter execs]", state4_enter_exec) /** state (svc_comp) exit executives **/ FSM_STATE_EXIT_FORCED (4, "svc_comp", "jsd_prio [svc_comp exit execs]") FSM_PROFILE_SECTION_IN ("jsd_prio [svc_comp exit execs]", state4_exit_exec) { } FSM_PROFILE_SECTION_OUT ("jsd_prio [svc_comp exit execs]", state4_exit_exec) /** state (svc_comp) transition processing **/ FSM_PROFILE_SECTION_IN ("jsd_prio [svc_comp trans conditions]", state4_trans_conds) FSM_INIT_COND (!QUEUE_EMPTY) FSM_DFLT_COND FSM_TEST_LOGIC ("svc_comp") FSM_PROFILE_SECTION_OUT ("jsd_prio [svc_comp trans conditions]", state4_trans_conds) FSM_TRANSIT_SWITCH {
215
Master thesis MEE 03:24 FSM_CASE_TRANSIT (0, 3, state3_enter_exec, ;, "!QUEUE_EMPTY", "", "svc_comp", "svc_start") FSM_CASE_TRANSIT (1, 1, state1_enter_exec, ;, "default", "", "svc_comp", "idle") } /*--------------------------------------------------------*/
} FSM_EXIT (0,jsd_prio) }
#if defined (__cplusplus) extern "C" { #endif extern VosT_Fun_Status Vos_Catmem_Register (const char * , int , VosT_Void_Null_Proc, VosT_Address *); extern VosT_Address Vos_Catmem_Alloc (VosT_Address, size_t); extern VosT_Fun_Status Vos_Catmem_Dealloc (VosT_Address); #if defined (__cplusplus) } #endif Compcode jsd_prio_init (void ** gen_state_pptr) { int _block_origin = 0; static VosT_Address obtype = OPC_NIL; FIN (jsd_prio_init (gen_state_pptr)) if (obtype == OPC_NIL) { /* Initialize memory management */ if (Vos_Catmem_Register ("proc state vars (jsd_prio)", sizeof (jsd_prio_state), Vos_Vnop, &obtype) == VOSC_FAILURE) { FRET (OPC_COMPCODE_FAILURE) } } *gen_state_pptr = Vos_Catmem_Alloc (obtype, 1); if (*gen_state_pptr == OPC_NIL) { FRET (OPC_COMPCODE_FAILURE) } else { /* Initialize FSM handling */ ((jsd_prio_state *)(*gen_state_pptr))->current_block = 0; Tommy Svensson Alex Popescu 216
void jsd_prio_terminate (void) { int _block_origin = __LINE__; FIN (jsd_prio_terminate (void)) Vos_Catmem_Dealloc (pr_state_ptr); FOUT } /* Undefine shortcuts to state variables to avoid */ /* syntax error in direct access to fields of */ /* local variable prs_ptr in jsd_prio_svar function. */ #undef server_busy #undef table_exists #undef num_lines #undef processing_rate #undef last_update_time #undef total_busy_time #undef work_left_last #undef total_work #undef total_delay #undef num_pks_serviced #undef win_size #undef Util_Stat_Hndl #undef Work_Left_Stat_Hndl #undef own_id #undef svc_complete #undef Job_Desc_Table #undef busy_signal_shandle #undef inst_delay_shandle #undef inst_wk_left_shandle #undef normalized_delay_shandle #undef mean_util_shandle #undef avg_thruput_shandle #undef mean_delay_shandle
217
Master thesis MEE 03:24 void jsd_prio_svar (void * gen_ptr, const char * var_name, char ** var_p_ptr) { jsd_prio_state *prs_ptr; FIN (jsd_prio_svar (gen_ptr, var_name, var_p_ptr)) if (var_name == OPC_NIL) { *var_p_ptr = (char *)OPC_NIL; FOUT } prs_ptr = (jsd_prio_state *)gen_ptr; if (strcmp ("server_busy" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->server_busy); FOUT } if (strcmp ("table_exists" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->table_exists); FOUT } if (strcmp ("num_lines" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->num_lines); FOUT } if (strcmp ("processing_rate" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->processing_rate); FOUT } if (strcmp ("last_update_time" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->last_update_time); FOUT } if (strcmp ("total_busy_time" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->total_busy_time); FOUT } if (strcmp ("work_left_last" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->work_left_last); FOUT } if (strcmp ("total_work" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->total_work); FOUT } if (strcmp ("total_delay" , var_name) == 0) { Tommy Svensson Alex Popescu 218
Master thesis MEE 03:24 *var_p_ptr = (char *) (&prs_ptr->total_delay); FOUT } (strcmp ("num_pks_serviced" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->num_pks_serviced); FOUT } (strcmp ("win_size" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->win_size); FOUT } (strcmp ("Util_Stat_Hndl" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->Util_Stat_Hndl); FOUT } (strcmp ("Work_Left_Stat_Hndl" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->Work_Left_Stat_Hndl); FOUT } (strcmp ("own_id" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->own_id); FOUT } (strcmp ("svc_complete" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->svc_complete); FOUT } (strcmp ("Job_Desc_Table" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->Job_Desc_Table); FOUT } (strcmp ("busy_signal_shandle" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->busy_signal_shandle); FOUT } (strcmp ("inst_delay_shandle" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->inst_delay_shandle); FOUT } (strcmp ("inst_wk_left_shandle" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->inst_wk_left_shandle); FOUT } (strcmp ("normalized_delay_shandle" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->normalized_delay_shandle); FOUT 219
if
if
if
if
if
if
if
if
if
if
if
Master thesis MEE 03:24 } if (strcmp ("mean_util_shandle" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->mean_util_shandle); FOUT } if (strcmp ("avg_thruput_shandle" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->avg_thruput_shandle); FOUT } if (strcmp ("mean_delay_shandle" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->mean_delay_shandle); FOUT } *var_p_ptr = (char *)OPC_NIL; FOUT }
220
Appendix 2
/* Process model C form file: jsd_prmpt_res.pr.c */ /* This variable carries the header into the object file */ static const char jsd_prmpt_res_pr_c [] = "MIL_3_Tfile_Hdr_ 90A 30A modeler 7 3EF9869E 3EF9869E 1 its-2503-5 exjobb 0 0 none none 0 0 none 0 0 0 0 0 0 "; #include <string.h>
/* OPNET system definitions */ #include <opnet.h> #if defined (__cplusplus) extern "C" { #endif FSM_EXT_DECS #if defined (__cplusplus) } /* end of 'extern "C"' */ #endif /* Header Block */ #include <stdlib.h> typedef struct { int job_type; double job_size; } JsdT_Job_Desc; #define QUEUE_EMPTY #define ARRIVAL #define SVC_COMPLETION op_q_empty () op_intrpt_type () == OPC_INTRPT_STRM op_intrpt_type () == OPC_INTRPT_SELF 0 /* Success codes for /* atof(), atoi() */
#define GET_INST_SUCCESS get_instructions () function */ #define GET_INST_NO_JOB_TYPE -1 #define GET_INST_NO_JOB_TABLE -2 #define GET_INST_NO_ENTRY #include "jsd_win_avg.ex.h"
-3
static int jsd_prmpt_res_get_instructions (Packet * pkptr, double * pk_inst_ptr); static void jsd_prmpt_res_error (const char * msg); /* End of Header Block */
221
Master thesis MEE 03:24 #if !defined (VOSD_NO_FIN) #undef BIN #undef BOUT #define BIN FIN_LOCAL_FIELD(last_line_passed) = __LINE__ _block_origin; #define BOUT BIN #define BINIT FIN_LOCAL_FIELD(last_line_passed) = 0; _block_origin = __LINE__; #else #define BINIT #endif /* #if !defined (VOSD_NO_FIN) */
/* State variable definitions */ typedef struct { /* Internal state tracking for FSM */ FSM_SYS_STATE /* State Variables */ int server_busy; int table_exists; int num_lines; double processing_rate; double current_priority; double last_update_time; double total_busy_time; double work_left_last; double total_work; double total_delay; double num_pks_serviced; double win_size; JsdT_Win_Stat_Hndl* Util_Stat_Hndl; JsdT_Win_Stat_Hndl* Objid Evhandle JsdT_Job_Desc* Objid Stathandle Stathandle Stathandle Stathandle Stathandle Stathandle Stathandle int } jsd_prmpt_res_state; #define pr_state_ptr SimI_Mod_State_Ptr) #define server_busy #define table_exists #define num_lines #define processing_rate Work_Left_Stat_Hndl; own_id; svc_complete; Job_Desc_Table; job_type_table_id; busy_signal_shandle; inst_delay_shandle; inst_wk_left_shandle; normalized_delay_shandle; mean_util_shandle; avg_thruput_shandle; mean_delay_shandle; current_subq; ((jsd_prmpt_res_state*) pr_state_ptr->server_busy pr_state_ptr->table_exists pr_state_ptr->num_lines pr_state_ptr->processing_rate
222
Master thesis MEE 03:24 #define current_priority #define last_update_time #define total_busy_time #define work_left_last #define total_work #define total_delay #define num_pks_serviced #define win_size #define Util_Stat_Hndl #define Work_Left_Stat_Hndl >Work_Left_Stat_Hndl #define own_id #define svc_complete #define Job_Desc_Table #define job_type_table_id >job_type_table_id #define busy_signal_shandle >busy_signal_shandle #define inst_delay_shandle >inst_delay_shandle #define inst_wk_left_shandle >inst_wk_left_shandle #define normalized_delay_shandle >normalized_delay_shandle #define mean_util_shandle >mean_util_shandle #define avg_thruput_shandle >avg_thruput_shandle #define mean_delay_shandle >mean_delay_shandle #define current_subq pr_state_ptr->current_priority pr_state_ptr->last_update_time pr_state_ptr->total_busy_time pr_state_ptr->work_left_last pr_state_ptr->total_work pr_state_ptr->total_delay pr_state_ptr->num_pks_serviced pr_state_ptr->win_size pr_state_ptr->Util_Stat_Hndl pr_state_ptrpr_state_ptr->own_id pr_state_ptr->svc_complete pr_state_ptr->Job_Desc_Table pr_state_ptrpr_state_ptrpr_state_ptrpr_state_ptrpr_state_ptrpr_state_ptrpr_state_ptrpr_state_ptrpr_state_ptr->current_subq
/* This macro definition will define a local variable called */ /* "op_sv_ptr" in each function containing a FIN statement. */ /* This variable points to the state variable data structure, */ /* and can be used from a C debugger to display their values. */ #undef FIN_PREAMBLE #define FIN_PREAMBLE jsd_prmpt_res_state *op_sv_ptr = pr_state_ptr; /* Function Block */ enum { _block_origin = __LINE__ }; static int jsd_prmpt_res_get_instructions (Packet * pkptr, double * pk_inst_ptr) { int job_type, i; /** This function takes as input a pointer to a packet, and returns **/ /** a double corresponding to the number of instructions in the **/ /** packet. If the instructions field in the packet is not set, the **/ /** function determines the number of instructions by getting the **/ Tommy Svensson Alex Popescu 223
Master thesis MEE 03:24 /** type of the job from the job_type field of the packet, and **/ /** looking up the number of instructions for that type of job in **/ /** the Job_Desc_Table, which has been read in from an external **/ /** in the init state. **/ FIN (jsd_prmpt_res_get_instructions (pkptr, pk_inst_ptr))
file
/* Get the number of instructions directly */ /* from the named field in the packet. */ if (op_pk_nfd_get (pkptr, "instructions", pk_inst_ptr) == OPC_COMPCODE_FAILURE) jsd_prmpt_res_error ("Unable to get instructions field from packet."); FRET (GET_INST_SUCCESS); } static void jsd_prmpt_res_error (const char * msg) { /** Print an error message and exit the simulation. **/ FIN (jsd_prmpt_res_error (msg)); op_sim_end ("Error in JSD preempt and resume process (jsd_prmpt_res):", msg, OPC_NIL, OPC_NIL); FOUT; } /* End of Function Block */ /* Undefine optional tracing in FIN/FOUT/FRET */ /* The FSM has its own tracing code and the other */ /* functions should not have any tracing. */ #undef FIN_TRACING #define FIN_TRACING #undef FOUTRET_TRACING #define FOUTRET_TRACING #if defined (__cplusplus) extern "C" { #endif void jsd_prmpt_res (void); Compcode jsd_prmpt_res_init (void **); void jsd_prmpt_res_diag (void); void jsd_prmpt_res_terminate (void); void jsd_prmpt_res_svar (void *, const char *, char **); #if defined (__cplusplus) } /* end of 'extern "C"' */ #endif
224
/* Process model interrupt handling procedure */ void jsd_prmpt_res (void) { int _block_origin = 0; FIN (jsd_prmpt_res ()); if (1) { Packet* pkptr; Packet* Packet* Objid int int int int int int double double double double double double double double double double double double double char char char* int int double head_pkptr; low_pkptr; orig_id; orig_port; insert_ok; svc_time_determined; success_code; i; sub_q_no; pk_instructions; pk_svc_time; low_pk_svc_time; old_svc_time; time_processed; time_in_processor; svc_start; original_svc_time; processing_delay; mean_util; avg_throughput; mean_proc_delay; pk_prio; job_type_filename [64]; err_str [256]; line; line_id; job_type; instructions;
-----*/
/** state (init) enter executives **/ FSM_STATE_ENTER_FORCED_NOLABEL (0, "init", "jsd_prmpt_res [init enter execs]") FSM_PROFILE_SECTION_IN ("jsd_prmpt_res [init enter execs]", state0_enter_exec) { Tommy Svensson Alex Popescu 225
Master thesis MEE 03:24 /** These executives are encountered only once, at the beginning of the simulation. **/ /** Their purpose is to initialize the process model. The attributes of this particular **/ /** module are determined and state variables are initialized. If a job_type_filename **/ /** was set, the file is read and parsed into a job description table. **/ /* Initially the server is idle. */ server_busy = 0; /* Initially the current priority is 0. */ current_priority = 0.0; /* Initially the current subqueue is 0. */ current_subq = 0; /* Get queue module's own object id. */ own_id = op_id_self (); */ /* Get assigned value of server processing rate.
if (op_ima_obj_attr_get (own_id, "processing_rate", &processing_rate) == OPC_COMPCODE_FAILURE) jsd_prmpt_res_error ("Unable to get processing rate from attribute."); windowed stats. */ /* Get assigned value of the window size for
if (op_ima_obj_attr_get (own_id, "win_size", &win_size) == OPC_COMPCODE_FAILURE) jsd_prmpt_res_error ("Unable to get window size from attribute."); statistics. */ /* Initialize some state variables dealing with last_update_time = op_sim_time (); total_busy_time = 0.0; work_left_last = 0.0; total_work = 0.0; /* Initialize the structures for the windowed
stats. */
Util_Stat_Hndl = jsd_win_avg_create ("Jsd.Windowed Utilization", win_size, OPC_STAT_LOCAL); Work_Left_Stat_Hndl = jsd_win_avg_create ("Jsd.Windowed Work Left (sec)", win_size, OPC_STAT_LOCAL); /* Register Statistics. */ busy_signal_shandle = op_stat_reg ("Jsd.Busy Signal", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); inst_delay_shandle = op_stat_reg ("Jsd.Instantaneous Delay (sec)", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL);
226
Master thesis MEE 03:24 inst_wk_left_shandle = op_stat_reg ("Jsd.Instantaneous Work Left (sec)", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); normalized_delay_shandle = op_stat_reg ("Jsd.Normalized Delay", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); mean_util_shandle = op_stat_reg ("Jsd.Total Busy Time", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); avg_thruput_shandle = op_stat_reg ("Jsd.Total Work", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); mean_delay_shandle = op_stat_reg ("Jsd.Mean Delay (sec)", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL); } FSM_PROFILE_SECTION_OUT ("jsd_prmpt_res [init enter execs]", state0_enter_exec) /** state (init) exit executives **/ FSM_STATE_EXIT_FORCED (0, "init", "jsd_prmpt_res [init
exit execs]")
FSM_PROFILE_SECTION_IN ("jsd_prmpt_res [init exit execs]", state0_exit_exec) { } FSM_PROFILE_SECTION_OUT ("jsd_prmpt_res [init exit execs]", state0_exit_exec) /** state (init) transition processing **/ FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "init", "idle") /*--------------------------------------------------------*/
/** state (idle) enter executives **/ FSM_STATE_ENTER_UNFORCED (1, state1_enter_exec, "idle", "jsd_prmpt_res [idle enter execs]") FSM_PROFILE_SECTION_IN ("jsd_prmpt_res [idle enter execs]", state1_enter_exec) { } FSM_PROFILE_SECTION_OUT ("jsd_prmpt_res [idle enter execs]", state1_enter_exec) **/ /** blocking after enter executives of unforced state. FSM_EXIT (3,jsd_prmpt_res)
/** state (idle) exit executives **/ FSM_STATE_EXIT_UNFORCED (1, "idle", "jsd_prmpt_res [idle exit execs]") FSM_PROFILE_SECTION_IN ("jsd_prmpt_res [idle exit execs]", state1_exit_exec) { Tommy Svensson Alex Popescu 227
Master thesis MEE 03:24 /** These executives are encountered whenever there is a stream interrupt (arrival), or a **/ /** self interrupt (service completion). In either case, we want to record some statistics. **/ /** If the server is busy at this point, we will want to record a 1.0 for each statistic from **/ /** the last update time until the current update time. If the server is free, we will want **/ /** to record a 0.0. Thus we will use the value of server_busy as the value to record. **/ /* Update the busy signal. */ op_stat_write_t (busy_signal_shandle, server_busy, last_update_time); /* Update the windowed utilization statistic. */ jsd_win_avg_update (Util_Stat_Hndl, (double)
server_busy);
/* Update the statistic for the instantaneous total amount of unfinished work in the queue. */ op_stat_write_t (inst_wk_left_shandle, work_left_last, last_update_time); /* Update the statistic for the windowed unfinished work in the queue. */ jsd_win_avg_update (Work_Left_Stat_Hndl, work_left_last); work_left_last -= (server_busy * (op_sim_time () - last_update_time)); /* Prevent rounding off errors. */ if (work_left_last < 0.0) work_left_last = 0.0; /* Add to the total_busy_time for use by the mean_utilization stat. */ total_busy_time += (server_busy * (op_sim_time () - last_update_time)); /* Update the statistic. */ op_stat_write (mean_util_shandle, total_busy_time/ op_sim_time ()); event. */ /* Set the last_update_time for use by the next
last_update_time = op_sim_time (); } FSM_PROFILE_SECTION_OUT ("jsd_prmpt_res [idle exit execs]", state1_exit_exec) /** state (idle) transition processing **/ FSM_PROFILE_SECTION_IN ("jsd_prmpt_res [idle trans conditions]", state1_trans_conds) Tommy Svensson Alex Popescu 228
Master thesis MEE 03:24 FSM_INIT_COND (SVC_COMPLETION) FSM_TEST_COND (ARRIVAL) FSM_TEST_LOGIC ("idle") FSM_PROFILE_SECTION_OUT ("jsd_prmpt_res [idle trans conditions]", state1_trans_conds) FSM_TRANSIT_SWITCH { FSM_CASE_TRANSIT (0, 4, state4_enter_exec, ;, "SVC_COMPLETION", "", "idle", "svc_comp") FSM_CASE_TRANSIT (1, 2, state2_enter_exec, ;, "ARRIVAL", "", "idle", "arrival") } /*--------------------------------------------------------*/
/** state (arrival) enter executives **/ FSM_STATE_ENTER_FORCED (2, state2_enter_exec, "arrival", "jsd_prmpt_res [arrival enter execs]") FSM_PROFILE_SECTION_IN ("jsd_prmpt_res [arrival enter execs]", state2_enter_exec) { /** These executives are encountered when a packet arrives on an input stream. **/ /** The incoming packet is enqueued in priority order in subqueue 0. If the **/ /** priority of the incoming packet is higher than that of a packet being served, **/ /** the packet being served is preempted by the incoming packet. **/ */ */ /* Acquire the arriving packet. /* Multiple arriving streams are supported. pkptr = op_pk_get (op_intrpt_strm()); if (pkptr == OPC_NIL) jsd_prmpt_res_error ("Unable to get packet /** Determine the remaining service time of the /* If the svc_time field of the packet is set, /* read the remaining service time directly from
if (op_pk_nfd_is_set (pkptr, "svc_time")) { if (op_pk_nfd_get (pkptr, "svc_time", &pk_svc_time) == OPC_COMPCODE_FAILURE) jsd_prmpt_res_error ("Unable to get remaining service time from packet."); /* Set a success flag to be used later. */ Tommy Svensson Alex Popescu 229
Master thesis MEE 03:24 svc_time_determined = 1; } instructions */ /* Otherwise we need to determine the number of /* in the packet. */ else { /* Determine the number of instructions in
the packet. */
success_code = jsd_prmpt_res_get_instructions (pkptr, &pk_instructions); successfully determined, /* If the number of instructions was */ /* compute the service time of the packet. */ if (success_code == GET_INST_SUCCESS) { pk_svc_time = pk_instructions / /* Since the svc_time field was not /* set it now for later statistical
if (op_pk_nfd_set (pkptr, "svc_time", pk_svc_time) == OPC_COMPCODE_FAILURE) jsd_prmpt_res_error ("Unable to get service time from packet."); later. */ else /* Set a success flag to be used svc_time_determined = 1; }
{ /* It was not possible to get the number of instructions from the packet. */ svc_time_determined = 0; job_type field was not set."); deallocate the packet. */ the packet and continuing."); sprintf (err_str, "Error: the /* Print error messages and op_sim_message (err_str, "Dropping op_pk_destroy (pkptr);
/* Set flag to ensure that transition to svc_start does not occur. */ insert_ok = 0; } }
230
Master thesis MEE 03:24 successfully. */ /* Check whether the svc_time was determined if (svc_time_determined == 1) { /* Write the remaining service time into
the packet. */
if (op_pk_nfd_set (pkptr, "svc_time_remain", pk_svc_time) == OPC_COMPCODE_FAILURE) jsd_prmpt_res_error ("Unable to set remaining service time in packet."); time, to keep track of processor. */ /* Set the svc_start field to the current
/* when the packet first entered the */ if (op_pk_nfd_set (pkptr, "svc_start", op_sim_time ()) == OPC_COMPCODE_FAILURE) jsd_prmpt_res_error ("Unable to set service start time in packet."); /* Check if the server is busy. If not, the packet will be enqueued. */ if (server_busy) { /* If the server is busy, preemption may be necessary. */ incoming packet is higher than currently being served. current_priority) packet in service is necessary. currently in service. */ /* Check if the priority of the */ /* the priority of the packet */ if (op_pk_priority_get (pkptr) > { /* If so, preemption of the /* Get a pointer to the packet head_pkptr = op_subq_pk_access
*/
(current_subq , OPC_QPOS_HEAD);
if (head_pkptr == OPC_NIL) jsd_prmpt_res_error ("Unable to get packet from head of subqueue."); processing time the packet required */ server. /* Determine how much
/* before it entered the */ if (op_pk_nfd_get (head_pkptr, "svc_time_remain", &old_svc_time) == OPC_COMPCODE_FAILURE) jsd_prmpt_res_error ("Unable to get remaining service time from packet."); /* Determine how much time has been spent processing this packet so far. */ time_processed = op_sim_time () - op_pk_stamp_time_get (head_pkptr); Tommy Svensson Alex Popescu 231
Master thesis MEE 03:24 /* Change the service time remaining in the packet being removed from the server. */ if (op_pk_nfd_set (head_pkptr, "svc_time_remain", old_svc_time - time_processed) == OPC_COMPCODE_FAILURE) { jsd_prmpt_res_error ("Unable to set remaining service time in packet."); } indicates the end of this job. */ (svc_complete) == OPC_COMPCODE_FAILURE) /* Cancel the interrupt which if (op_intrpt_cancel jsd_prmpt_res_error
pk_prio=op_pk_priority_get (pkptr);
/* Attempt to enqueue the packet in priority order in subqueue pk_prio. */ /* This code will be executed whether or not preemption was necessary. */ if (op_subq_pk_insert ((int)pk_prio, pkptr, OPC_QPOS_TAIL) != OPC_QINS_OK) { /* The insertion failed (due to a full queue). Determine the */ /* packet with the lowest priority and remove it from the queue. */ low_pkptr = op_subq_pk_remove ((int)pk_prio, OPC_QPOS_TAIL); if (low_pkptr == OPC_NIL) jsd_prmpt_res_error ("Unable to get lowest priority packet from subqueue."); /* Determine the remaining service */ if (op_pk_nfd_get (low_pkptr, "svc_time_remain", &low_pk_svc_time) == OPC_COMPCODE_FAILURE) jsd_prmpt_res_error ("Unable to get remaining service time from packet."); time of the low priority packet. the work left in the queue. */ /* Subtract this amount of time from work_left_last -= low_pk_svc_time;
232
Master thesis MEE 03:24 lowest priority. */ /* Deallocate the packet with the op_pk_destroy (low_pkptr);
/* Attempt to re-enqueue the new packet in priority order in subqueue 0. */ if (op_subq_pk_insert ((int)pk_prio, pkptr, OPC_QPOS_PRIO) != OPC_QINS_OK) { /* The insertion failed again. Deallocate the new packet. */ op_pk_destroy (pkptr); insertion fail. this state. else This flag is used to /* Set flag indicating */ /* determine transition out of */ insert_ok = 0; } { /* Insertion was successful */ insert_ok = 1; /* Add the service time of the /* the work left in the queue, work_left_last += pk_svc_time; }
*/ */ }
else
{ /* Insertion was successful */ insert_ok = 1; /* Add the service time of the /* the work left in the queue, for work_left_last += pk_svc_time; }
*/
FSM_PROFILE_SECTION_OUT ("jsd_prmpt_res [arrival enter execs]", state2_enter_exec) /** state (arrival) exit executives **/ FSM_STATE_EXIT_FORCED (2, "arrival", "jsd_prmpt_res [arrival exit execs]") FSM_PROFILE_SECTION_IN ("jsd_prmpt_res [arrival exit execs]", state2_exit_exec) { } FSM_PROFILE_SECTION_OUT ("jsd_prmpt_res [arrival exit execs]", state2_exit_exec) Tommy Svensson Alex Popescu 233
/** state (arrival) transition processing **/ FSM_PROFILE_SECTION_IN ("jsd_prmpt_res [arrival trans conditions]", state2_trans_conds) FSM_INIT_COND (!server_busy && insert_ok) FSM_DFLT_COND FSM_TEST_LOGIC ("arrival") FSM_PROFILE_SECTION_OUT ("jsd_prmpt_res [arrival trans conditions]", state2_trans_conds) FSM_TRANSIT_SWITCH { FSM_CASE_TRANSIT (0, 3, state3_enter_exec, ;, "!server_busy && insert_ok", "", "arrival", "svc_start") FSM_CASE_TRANSIT (1, 1, state1_enter_exec, ;, "default", "", "arrival", "idle") } /*--------------------------------------------------------*/
/** state (svc_start) enter executives **/ FSM_STATE_ENTER_FORCED (3, state3_enter_exec, "svc_start", "jsd_prmpt_res [svc_start enter execs]") FSM_PROFILE_SECTION_IN ("jsd_prmpt_res [svc_start enter execs]", state3_enter_exec) { /** When entering these executives, there will be a packet at the **/ /** head of subqueue 0 that requires service. This state begins **/ /** service for the packet and schedules an interrupt for the **/ /** time of completion of service. **/ sub_q_no=0; for (i=2; i>=0; i--) { if (!op_subq_empty(i)) { sub_q_no=i; } } subqueue 0. */ /* Get a handle on the packet at the head of /* This does not remove the packet. */ pkptr = op_subq_pk_access (sub_q_no,
OPC_QPOS_HEAD);
234
Master thesis MEE 03:24 /* Set the current priority to the priority of the packet beginning service. */ current_priority = op_pk_priority_get (pkptr); /* Set the current subqueue to the subqueue of the packet beginning service. */ current_subq = sub_q_no; packet. */ /* Extract the remaining service time of the
if (op_pk_nfd_get (pkptr, "svc_time_remain", &pk_svc_time) == OPC_COMPCODE_FAILURE) jsd_prmpt_res_error ("Unable to get remaining service time from packet."); /* Schedule an interrupt for this process at the time where service ends. */ svc_complete = op_intrpt_schedule_self (op_sim_time () + pk_svc_time, 0); if (op_ev_valid (svc_complete) == OPC_FALSE) jsd_prmpt_res_error ("Unable to schedule self interrupt for service completion."); started. */ /* Stamp packet so that we know when processing op_pk_stamp (pkptr); /* Make the server busy. */ server_busy = 1; } FSM_PROFILE_SECTION_OUT ("jsd_prmpt_res [svc_start enter execs]", state3_enter_exec) /** state (svc_start) exit executives **/ FSM_STATE_EXIT_FORCED (3, "svc_start", "jsd_prmpt_res [svc_start exit execs]") FSM_PROFILE_SECTION_IN ("jsd_prmpt_res [svc_start exit execs]", state3_exit_exec) { } FSM_PROFILE_SECTION_OUT ("jsd_prmpt_res [svc_start exit execs]", state3_exit_exec) /** state (svc_start) transition processing **/ FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "svc_start", "idle") /*--------------------------------------------------------*/
/** state (svc_comp) enter executives **/ FSM_STATE_ENTER_FORCED (4, state4_enter_exec, "svc_comp", "jsd_prmpt_res [svc_comp enter execs]") Tommy Svensson Alex Popescu 235
Master thesis MEE 03:24 FSM_PROFILE_SECTION_IN ("jsd_prmpt_res [svc_comp enter execs]", state4_enter_exec) { /** These executives are encountered when a packet completes **/ /** service. They record some statistics, convert the packet **/ /** into an acknowledgement packet, and send it back to the **/ /** address specified by the the orig_id and orig_port fields **/ /** of the packet. **/ /* Extract the packet at the head of the queue. /* This is the packet just finishing service. pkptr = op_subq_pk_remove (current_subq,
*/ */ OPC_QPOS_HEAD);
if (pkptr == OPC_NIL) jsd_prmpt_res_error ("Unable to get packet from head of subqueue."); processor */ */ /* Determine when this packet first entered the /* and how long it has been in the processor.
if (op_pk_nfd_get (pkptr, "svc_start", &svc_start) == OPC_COMPCODE_FAILURE) jsd_prmpt_res_error ("Unable to get service start time from packet."); time_in_processor = op_sim_time () - svc_start; packet and how the queue. */ */ /* Determine the original service time of this /* much processing delay it has experienced in
if (op_pk_nfd_get (pkptr, "svc_time", &original_svc_time) == OPC_COMPCODE_FAILURE) jsd_prmpt_res_error ("Unable to get original service time from packet."); processing_delay = time_in_processor original_svc_time; /* Prevent rounding off error. */ if (processing_delay < 0.0) processing_delay = 0.0; /* Write the processing delay statistic. */ op_stat_write (inst_delay_shandle,
processing_delay);
/* Write the normalized delay statistic. */ op_stat_write (normalized_delay_shandle, (time_in_processor / original_svc_time)); Tommy Svensson Alex Popescu 236
Master thesis MEE 03:24 /* Add to the counters for the total processing */ /* number of packets serviced for use by the average delay statistic. */ total_delay += processing_delay; num_pks_serviced++; delay and the /* Update the statistic.*/ op_stat_write (mean_delay_shandle, total_delay / /* Add to the counter of total work completed by /* for use by the average throughput statistic. total_work += original_svc_time; /* Update the statistic. */ op_stat_write (avg_thruput_shandle, total_work /
op_sim_time ());
ack. */ OPC_COMPCODE_FAILURE)
jsd_prmpt_res_error ("Unable to set acknowledgement flag in packet."); */ */ /* Extract the originator's object id and port, /* and deliver the ack packet to the originator.
if (op_pk_nfd_get (pkptr, "orig_id", &orig_id) == OPC_COMPCODE_FAILURE || op_pk_nfd_get (pkptr, "orig_port", &orig_port) == OPC_COMPCODE_FAILURE) { jsd_prmpt_res_error ("Unable to get originator's object ID or port from packet."); } op_pk_deliver (pkptr, orig_id, orig_port); */ */ /* Set the current priority to 0, since nothing /* is being serviced at this moment. current_priority = 0.0; /* Make the server idle again. */ server_busy = 0; } FSM_PROFILE_SECTION_OUT ("jsd_prmpt_res [svc_comp enter execs]", state4_enter_exec)
237
Master thesis MEE 03:24 /** state (svc_comp) exit executives **/ FSM_STATE_EXIT_FORCED (4, "svc_comp", "jsd_prmpt_res [svc_comp exit execs]") FSM_PROFILE_SECTION_IN ("jsd_prmpt_res [svc_comp exit execs]", state4_exit_exec) { } FSM_PROFILE_SECTION_OUT ("jsd_prmpt_res [svc_comp exit execs]", state4_exit_exec)
/** state (svc_comp) transition processing **/ FSM_PROFILE_SECTION_IN ("jsd_prmpt_res [svc_comp trans conditions]", state4_trans_conds) FSM_INIT_COND (!QUEUE_EMPTY) FSM_DFLT_COND FSM_TEST_LOGIC ("svc_comp") FSM_PROFILE_SECTION_OUT ("jsd_prmpt_res [svc_comp trans conditions]", state4_trans_conds) FSM_TRANSIT_SWITCH { FSM_CASE_TRANSIT (0, 3, state3_enter_exec, ;, "!QUEUE_EMPTY", "", "svc_comp", "svc_start") FSM_CASE_TRANSIT (1, 1, state1_enter_exec, ;, "default", "", "svc_comp", "idle") } /*--------------------------------------------------------*/
} FSM_EXIT (0,jsd_prmpt_res) }
#if defined (__cplusplus) extern "C" { #endif extern VosT_Fun_Status Vos_Catmem_Register (const char * , int , VosT_Void_Null_Proc, VosT_Address *); extern VosT_Address Vos_Catmem_Alloc (VosT_Address, size_t); extern VosT_Fun_Status Vos_Catmem_Dealloc (VosT_Address); #if defined (__cplusplus) } #endif Compcode jsd_prmpt_res_init (void ** gen_state_pptr) { int _block_origin = 0; static VosT_Address obtype = OPC_NIL; Tommy Svensson Alex Popescu 238
Master thesis MEE 03:24 FIN (jsd_prmpt_res_init (gen_state_pptr)) if (obtype == OPC_NIL) { /* Initialize memory management */ if (Vos_Catmem_Register ("proc state vars (jsd_prmpt_res)", sizeof (jsd_prmpt_res_state), Vos_Vnop, &obtype) == VOSC_FAILURE) { FRET (OPC_COMPCODE_FAILURE) } } *gen_state_pptr = Vos_Catmem_Alloc (obtype, 1); if (*gen_state_pptr == OPC_NIL) { FRET (OPC_COMPCODE_FAILURE) else } { /* Initialize FSM handling */ ((jsd_prmpt_res_state *)(*gen_state_pptr))->current_block = FRET (OPC_COMPCODE_SUCCESS) }
0;
void jsd_prmpt_res_terminate (void) { int _block_origin = __LINE__; FIN (jsd_prmpt_res_terminate (void)) Vos_Catmem_Dealloc (pr_state_ptr); FOUT } /* Undefine shortcuts to state variables to avoid */ /* syntax error in direct access to fields of */ /* local variable prs_ptr in jsd_prmpt_res_svar function. */ Tommy Svensson Alex Popescu 239
Master thesis MEE 03:24 #undef #undef #undef #undef #undef #undef #undef #undef #undef #undef #undef #undef #undef #undef #undef #undef #undef #undef #undef #undef #undef #undef #undef #undef #undef #undef server_busy table_exists num_lines processing_rate current_priority last_update_time total_busy_time work_left_last total_work total_delay num_pks_serviced win_size Util_Stat_Hndl Work_Left_Stat_Hndl own_id svc_complete Job_Desc_Table job_type_table_id busy_signal_shandle inst_delay_shandle inst_wk_left_shandle normalized_delay_shandle mean_util_shandle avg_thruput_shandle mean_delay_shandle current_subq
void jsd_prmpt_res_svar (void * gen_ptr, const char * var_name, char ** var_p_ptr) { jsd_prmpt_res_state *prs_ptr; FIN (jsd_prmpt_res_svar (gen_ptr, var_name, var_p_ptr)) if (var_name == OPC_NIL) { *var_p_ptr = (char *)OPC_NIL; FOUT } prs_ptr = (jsd_prmpt_res_state *)gen_ptr; if (strcmp ("server_busy" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->server_busy); FOUT } if (strcmp ("table_exists" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->table_exists); FOUT } if (strcmp ("num_lines" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->num_lines); Tommy Svensson Alex Popescu 240
Master thesis MEE 03:24 FOUT } (strcmp ("processing_rate" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->processing_rate); FOUT } (strcmp ("current_priority" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->current_priority); FOUT } (strcmp ("last_update_time" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->last_update_time); FOUT } (strcmp ("total_busy_time" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->total_busy_time); FOUT } (strcmp ("work_left_last" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->work_left_last); FOUT } (strcmp ("total_work" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->total_work); FOUT } (strcmp ("total_delay" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->total_delay); FOUT } (strcmp ("num_pks_serviced" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->num_pks_serviced); FOUT } (strcmp ("win_size" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->win_size); FOUT } (strcmp ("Util_Stat_Hndl" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->Util_Stat_Hndl); FOUT } (strcmp ("Work_Left_Stat_Hndl" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->Work_Left_Stat_Hndl); FOUT } 241
if
if
if
if
if
if
if
if
if
if
if
Master thesis MEE 03:24 if (strcmp ("own_id" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->own_id); FOUT } if (strcmp ("svc_complete" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->svc_complete); FOUT } if (strcmp ("Job_Desc_Table" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->Job_Desc_Table); FOUT } if (strcmp ("job_type_table_id" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->job_type_table_id); FOUT } if (strcmp ("busy_signal_shandle" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->busy_signal_shandle); FOUT } if (strcmp ("inst_delay_shandle" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->inst_delay_shandle); FOUT } if (strcmp ("inst_wk_left_shandle" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->inst_wk_left_shandle); FOUT } if (strcmp ("normalized_delay_shandle" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->normalized_delay_shandle); FOUT } if (strcmp ("mean_util_shandle" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->mean_util_shandle); FOUT } if (strcmp ("avg_thruput_shandle" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->avg_thruput_shandle); FOUT } if (strcmp ("mean_delay_shandle" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->mean_delay_shandle); FOUT } if (strcmp ("current_subq" , var_name) == 0) { Tommy Svensson Alex Popescu 242
Master thesis MEE 03:24 *var_p_ptr = (char *) (&prs_ptr->current_subq); FOUT } *var_p_ptr = (char *)OPC_NIL; FOUT }
243
Appendix 3
/* Process model C form file: ta_gen.pr.c */ /* This variable carries the header into the object file */ static const char ta_gen_pr_c [] = "MIL_3_Tfile_Hdr_ 90A 30A modeler 7 3EF84C02 3EF84C02 1 its-2503-5 exjobb 0 0 none none 0 0 none 0 0 0 0 0 0 "; #include <string.h>
/* OPNET system definitions */ #include <opnet.h> #if defined (__cplusplus) extern "C" { #endif FSM_EXT_DECS #if defined (__cplusplus) } /* end of 'extern "C"' */ #endif /* Header Block */ #define JSDC_SVC_TIME */ #define JSDC_INSTRUCTIONS #define JSDC_RCV_IN_STRM #define JSDC_XMT_OUT_STRM #define JSDC_CREATE_INTRPT creation */ 1 2 0 0 0 /* The intrpt code for packet /* Symbolic constants to determine /* which type of packets this */ /* Packet stream definitions */
/* Transition macros */ #define CREATE (op_intrpt_type () == OPC_INTRPT_SELF && \ op_intrpt_code () == JSDC_CREATE_INTRPT) #define ARRIVAL (op_intrpt_type () == OPC_INTRPT_STRM && \ op_intrpt_strm () == JSDC_RCV_IN_STRM)
void void
/* End of Header Block */ #if !defined (VOSD_NO_FIN) #undef BIN #undef BOUT Tommy Svensson Alex Popescu 244
Master thesis MEE 03:24 #define BIN FIN_LOCAL_FIELD(last_line_passed) = __LINE__ _block_origin; #define BOUT BIN #define BINIT FIN_LOCAL_FIELD(last_line_passed) = 0; _block_origin = __LINE__; #else #define BINIT #endif /* #if !defined (VOSD_NO_FIN) */
/* State variable definitions */ typedef struct { /* Internal state tracking for FSM */ FSM_SYS_STATE /* State Variables */ Objid own_id; int active; double instruction_range; double priority_range; Distribution * next_dist; double ia_time; } ta_gen_state; #define pr_state_ptr SimI_Mod_State_Ptr) #define own_id #define active #define instruction_range >instruction_range #define priority_range #define next_dist #define ia_time ((ta_gen_state*) pr_state_ptr->own_id pr_state_ptr->active pr_state_ptrpr_state_ptr->priority_range pr_state_ptr->next_dist pr_state_ptr->ia_time */ */ */
/* This macro definition will define a local variable called /* "op_sv_ptr" in each function containing a FIN statement. */ /* This variable points to the state variable data structure, /* and can be used from a C debugger to display their values. #undef FIN_PREAMBLE #define FIN_PREAMBLE ta_gen_state *op_sv_ptr = pr_state_ptr; /* Function Block */ enum { _block_origin = __LINE__ }; void jsd_gen_request_creation () { double next_creation_time; Evhandle evh;
/** This function computes the time until the next packet creation **/ /** from an exponential distribution based on the value of **/
245
Master thesis MEE 03:24 /** the ia_time attribute. The function schedules an interrupt **/ /** at the time of the next creation. **/ FIN (jsd_gen_request_creation ()); */ /* Only schedule interrupts if this generator is currently active.
if (active) { /* Determine the next packet creation time. */ next_creation_time = op_dist_outcome (next_dist); if (next_creation_time == OPC_DBL_INVALID) jsd_gen_error ("Unable to get next packet creation time from distribution."); /* Schedule an interrupt for that time. */ evh = op_intrpt_schedule_self (op_sim_time () + next_creation_time, JSDC_CREATE_INTRPT); if (op_ev_valid (evh) == OPC_FALSE) jsd_gen_error ("Unable to schedule self interrupt for next packet creation."); } FOUT; } void jsd_gen_error (msg) char* msg; { /** Print an error message and exit the simulation. **/ FIN (jsd_gen_error (msg)); op_sim_end ("Error in JSD traffic generation process (jsd_gen):", msg, OPC_NIL, OPC_NIL); FOUT; } /* End of Function Block */ /* Undefine optional tracing in FIN/FOUT/FRET */ /* The FSM has its own tracing code and the other */ /* functions should not have any tracing. */ #undef FIN_TRACING #define FIN_TRACING #undef FOUTRET_TRACING #define FOUTRET_TRACING #if defined (__cplusplus) extern "C" { #endif void ta_gen (void); Compcode ta_gen_init (void **); Tommy Svensson Alex Popescu 246
Master thesis MEE 03:24 void ta_gen_diag (void); void ta_gen_terminate (void); void ta_gen_svar (void *, const char *, char **); #if defined (__cplusplus) } /* end of 'extern "C"' */ #endif
/* Process model interrupt handling procedure */ void ta_gen (void) { int _block_origin FIN (ta_gen ()); if (1) { Packet* double double double double
= 0;
-----*/
/** state (init) enter executives **/ FSM_STATE_ENTER_FORCED_NOLABEL (0, "init", "ta_gen [init enter execs]") FSM_PROFILE_SECTION_IN ("ta_gen [init enter execs]", state0_enter_exec) { /** These executives are encountered only once, at the beginning of the simulation. **/ /** simulation. Their purpose is to initialize the process model. The attributes **/ /** of this particular generator are determined and distributions are loaded. **/ /* Get generator module's own object id. */ own_id = op_id_self (); /* Get the assigned value for the average packet
interarrival times. */
if (op_ima_obj_attr_get (own_id, "ia_time", &ia_time) == OPC_COMPCODE_FAILURE) jsd_gen_error ("Unable to get mean packet interarrival time from attribute.");
247
Master thesis MEE 03:24 /* Determine whether this particular generator This attribute is useful */ /* for being able to "delete" generators without having to modify the node model. */ if (op_ima_obj_attr_get (own_id, "active", &active) == OPC_COMPCODE_FAILURE) jsd_gen_error ("Unable to get activity flag from attribute."); is active. /* Determine the upper bound of the number of instructions of packets generated. */ if (op_ima_obj_attr_get (own_id, "instruction_range", &instruction_range) == OPC_COMPCODE_FAILURE) jsd_gen_error ("Unable to get number of instructions range from attribute."); /* Determine the upper bound of the range of priorities of packets generated. */ if (op_ima_obj_attr_get (own_id, "priority_range", &priority_range) == OPC_COMPCODE_FAILURE) jsd_gen_error ("Unable to get priority range from attribute."); interarrival times. ia_time, 0.0); arrival distribution."); /* Load the distribution function for the packet */ next_dist = op_dist_load ("exponential", if (next_dist == OPC_NIL) jsd_gen_error ("Unable to load packet }
FSM_PROFILE_SECTION_OUT ("ta_gen [init enter execs]", state0_enter_exec) /** state (init) exit executives **/ FSM_STATE_EXIT_FORCED (0, "init", "ta_gen [init exit
execs]")
FSM_PROFILE_SECTION_IN ("ta_gen [init exit execs]", state0_exit_exec) { /* When exiting this state, schedule the next interrupt for */ /* a packet creation by calling jsd_gen_request_creation(). */ jsd_gen_request_creation (); } FSM_PROFILE_SECTION_OUT ("ta_gen [init exit execs]", state0_exit_exec) /** state (init) transition processing **/ FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "init", "idle") /*--------------------------------------------------------*/
248
/** state (idle) enter executives **/ FSM_STATE_ENTER_UNFORCED (1, state1_enter_exec, "idle", "ta_gen [idle enter execs]") FSM_PROFILE_SECTION_IN ("ta_gen [idle enter execs]", state1_enter_exec) { } FSM_PROFILE_SECTION_OUT ("ta_gen [idle enter execs]", state1_enter_exec) **/ /** blocking after enter executives of unforced state. FSM_EXIT (3,ta_gen) /** state (idle) exit executives **/ FSM_STATE_EXIT_UNFORCED (1, "idle", "ta_gen [idle exit
execs]")
FSM_PROFILE_SECTION_IN ("ta_gen [idle exit execs]", state1_exit_exec) { } FSM_PROFILE_SECTION_OUT ("ta_gen [idle exit execs]", state1_exit_exec) /** state (idle) transition processing **/ FSM_PROFILE_SECTION_IN ("ta_gen [idle trans conditions]", state1_trans_conds) FSM_INIT_COND (CREATE) FSM_TEST_COND (ARRIVAL) FSM_DFLT_COND FSM_TEST_LOGIC ("idle") FSM_PROFILE_SECTION_OUT ("ta_gen [idle trans conditions]", state1_trans_conds) FSM_TRANSIT_SWITCH { FSM_CASE_TRANSIT (0, 2, state2_enter_exec, ;, "CREATE", "", "idle", "xmt") FSM_CASE_TRANSIT (1, 3, state3_enter_exec, ;, "ARRIVAL", "", "idle", "rcv") FSM_CASE_TRANSIT (2, 1, state1_enter_exec, ;, "default", "", "idle", "idle") } /*--------------------------------------------------------*/
/** state (xmt) enter executives **/ FSM_STATE_ENTER_FORCED (2, state2_enter_exec, "xmt", "ta_gen [xmt enter execs]")
249
Master thesis MEE 03:24 FSM_PROFILE_SECTION_IN ("ta_gen [xmt enter execs]", state2_enter_exec) { /** These executives are encountered when a self-interrupt ocurrs, **/ /** indicating that it is time to create and send a new packet. **/ /* Create a packet with the jsd format, and retain the packet pointer. */ pkptr = op_pk_create_fmt ("jsd_pk"); if (pkptr == OPC_NIL) jsd_gen_error ("Unable to create packet."); packet will be delivered serviced. OPC_COMPCODE_FAILURE || /* Set the orig_id and orig_port so that the */ /* back to this generator when it has been */ if (op_pk_nfd_set (pkptr, "orig_id", own_id) ==
op_pk_nfd_set (pkptr, "orig_port", JSDC_RCV_IN_STRM) == OPC_COMPCODE_FAILURE) { jsd_gen_error ("Unable to set ID or port in newly created packet."); } field, but just will */ */ */ /* The jsd packet format also contains an ack /* it will be left unset, since the packet was /* created and the field default is unset. This
/* indicate that this packet is a request and /** Set the appropriate field of the packet
(instruction_range);
from distribution.");
/* instructions = op_dist_uniform */ instructions = instruction_range; if (instructions == OPC_DBL_INVALID) jsd_gen_error ("Unable to get instructions
if (op_pk_nfd_set (pkptr, "instructions", instructions) == OPC_COMPCODE_FAILURE) jsd_gen_error ("Unable to set instructions in packet.");
250
Master thesis MEE 03:24 */ /* priority = op_dist_uniform (priority_range); priority = priority_range; if (priority == OPC_DBL_INVALID) jsd_gen_error ("Unable to get priority op_pk_priority_set (pkptr, priority); /* Send the packet over the XMT_OUT stream. */ op_pk_send (pkptr, JSDC_XMT_OUT_STRM); } FSM_PROFILE_SECTION_OUT ("ta_gen [xmt enter execs]", state2_enter_exec) /** state (xmt) exit executives **/ FSM_STATE_EXIT_FORCED (2, "xmt", "ta_gen [xmt exit
from distribution.");
execs]")
FSM_PROFILE_SECTION_IN ("ta_gen [xmt exit execs]", state2_exit_exec) { /* When exiting this state, schedule the next interrupt for */ /* a packet creation by calling jsd_gen_request_creation(). */ jsd_gen_request_creation (); } FSM_PROFILE_SECTION_OUT ("ta_gen [xmt exit execs]", state2_exit_exec) /** state (xmt) transition processing **/ FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", /*----------------------------------------------
/** state (rcv) enter executives **/ FSM_STATE_ENTER_FORCED (3, state3_enter_exec, "rcv", "ta_gen [rcv enter execs]") FSM_PROFILE_SECTION_IN ("ta_gen [rcv enter execs]", state3_enter_exec) { /** These executives are encountered when a packet is received on the **/ /** RCV_IN_STRM. The packet is destroyed to free its memory requirements. **/ /* Acquire the incoming packet. */ pkptr = op_pk_get (JSDC_RCV_IN_STRM); /* Deallocate the packet. */ if (pkptr != OPC_NIL) op_pk_destroy (pkptr); } Tommy Svensson Alex Popescu 251
Master thesis MEE 03:24 FSM_PROFILE_SECTION_OUT ("ta_gen [rcv enter execs]", state3_enter_exec) /** state (rcv) exit executives **/ FSM_STATE_EXIT_FORCED (3, "rcv", "ta_gen [rcv exit
execs]")
FSM_PROFILE_SECTION_IN ("ta_gen [rcv exit execs]", state3_exit_exec) { } FSM_PROFILE_SECTION_OUT ("ta_gen [rcv exit execs]", state3_exit_exec) /** state (rcv) transition processing **/ FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", /*----------------------------------------------
} FSM_EXIT (0,ta_gen) }
#if defined (__cplusplus) extern "C" { #endif extern VosT_Fun_Status Vos_Catmem_Register (const char * , int , VosT_Void_Null_Proc, VosT_Address *); extern VosT_Address Vos_Catmem_Alloc (VosT_Address, size_t); extern VosT_Fun_Status Vos_Catmem_Dealloc (VosT_Address); #if defined (__cplusplus) } #endif Compcode ta_gen_init (void ** gen_state_pptr) { int _block_origin = 0; static VosT_Address obtype = OPC_NIL; FIN (ta_gen_init (gen_state_pptr)) if (obtype == OPC_NIL) { /* Initialize memory management */ if (Vos_Catmem_Register ("proc state vars (ta_gen)", sizeof (ta_gen_state), Vos_Vnop, &obtype) == VOSC_FAILURE) { Tommy Svensson Alex Popescu 252
*gen_state_pptr = Vos_Catmem_Alloc (obtype, 1); if (*gen_state_pptr == OPC_NIL) { FRET (OPC_COMPCODE_FAILURE) } else { /* Initialize FSM handling */ ((ta_gen_state *)(*gen_state_pptr))->current_block = 0; FRET (OPC_COMPCODE_SUCCESS) }
void ta_gen_terminate (void) { int _block_origin = __LINE__; FIN (ta_gen_terminate (void)) Vos_Catmem_Dealloc (pr_state_ptr); FOUT } /* Undefine shortcuts to state variables to avoid */ /* syntax error in direct access to fields of */ /* local variable prs_ptr in ta_gen_svar function. */ #undef own_id #undef active #undef instruction_range #undef priority_range #undef next_dist #undef ia_time
void ta_gen_svar (void * gen_ptr, const char * var_name, char ** var_p_ptr) { Tommy Svensson Alex Popescu 253
FIN (ta_gen_svar (gen_ptr, var_name, var_p_ptr)) if (var_name == OPC_NIL) { *var_p_ptr = (char *)OPC_NIL; FOUT } prs_ptr = (ta_gen_state *)gen_ptr; if (strcmp ("own_id" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->own_id); FOUT } if (strcmp ("active" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->active); FOUT } if (strcmp ("instruction_range" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->instruction_range); FOUT } if (strcmp ("priority_range" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->priority_range); FOUT } if (strcmp ("next_dist" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->next_dist); FOUT } if (strcmp ("ia_time" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->ia_time); FOUT } *var_p_ptr = (char *)OPC_NIL; FOUT }
254
Appendix 4
/* Process model C form file: ta_wfq.pr.c */
/* This variable carries the header into the object file */ static const char ta_wfq_pr_c [] = "MIL_3_Tfile_Hdr_ 90A 30A modeler 7 3EFDA029 3EFDA029 1 its-2503-5 exjobb 0 0 none none 0 0 none 0 0 0 0 0 0 "; #include <string.h>
/* OPNET system definitions */ #include <opnet.h> #if defined (__cplusplus) extern "C" { #endif FSM_EXT_DECS #if defined (__cplusplus) } /* end of 'extern "C"' */ #endif /* Header Block */ #include <stdlib.h> #define QUEUE_EMPTY /* atof(), atoi() */ op_q_empty ()
/* Packet arrival macro */ #define PK_ARRIVAL op_intrpt_type () == OPC_INTRPT_STRM /* Service completion macro */ #define SVC_COMPLETION op_intrpt_type () == OPC_INTRPT_SELF #define SUBQ_INACTIVE #define SUBQ_ACTIVE #define SUBQ_EMPTY #define SERVER_FREE #define SERVER_BUSY 0 1 0 0 1
double VT (void); void ta_wfq_error (char * msg); double retmaximum (double val1,double val2); double SoQ_calc(int sq); double get_VFT (int sq); /* End of Header Block */ #if !defined (VOSD_NO_FIN) #undef BIN Tommy Svensson Alex Popescu 255
Master thesis MEE 03:24 #undef BOUT #define BIN FIN_LOCAL_FIELD(last_line_passed) = __LINE__ _block_origin; #define BOUT BIN #define BINIT FIN_LOCAL_FIELD(last_line_passed) = 0; _block_origin = __LINE__; #else #define BINIT #endif /* #if !defined (VOSD_NO_FIN) */
/* State variable definitions */ typedef struct { /* Internal state tracking for FSM */ FSM_SYS_STATE /* State Variables */ double processing_rate; Objid own_id; double weight[3]; int active_queues[3]; int server_busy; } ta_wfq_state; #define pr_state_ptr SimI_Mod_State_Ptr) #define processing_rate #define own_id #define weight #define active_queues #define server_busy ((ta_wfq_state*) pr_state_ptr->processing_rate pr_state_ptr->own_id pr_state_ptr->weight pr_state_ptr->active_queues pr_state_ptr->server_busy */ */ */
/* This macro definition will define a local variable called /* "op_sv_ptr" in each function containing a FIN statement. */ /* This variable points to the state variable data structure, /* and can be used from a C debugger to display their values. #undef FIN_PREAMBLE #define FIN_PREAMBLE ta_wfq_state *op_sv_ptr = pr_state_ptr; /* Function Block */ enum { _block_origin = __LINE__ }; double VT (void) { int no_active_q; int i; double virtual_time; /** This function returns the virtual time **/ /* Determine number of active queues */ for (i=0;i<3;i++) { no_active_q += active_queues[i]; } Tommy Svensson Alex Popescu
256
Master thesis MEE 03:24 /* Calculate virtual time*/ virtual_time = 1/retmaximum(1.0 , no_active_q); return virtual_time; } double retmaximum (double val1,double val2) { /** This function takes two values as arguments and returns the **/ /** biggest value **/ if (val1 < val2) return val2; else return val1; } double SoQ_calc(int sq) { double tot_weight; double SoQ_value; int i; /** This function returns share of queue **/ tot_weight=0; for (i=0;i<3;i++) { if (active_queues[i]== SUBQ_ACTIVE ) tot_weight+=weight[i]; } if (tot_weight==0.0) ta_wfq_error ("Unable to determine SoQ"); SoQ_value = weight[sq]/tot_weight; return SoQ_value; } double get_VFT (int sq) { double dval; double prev_pk_vft; Packet* pkptr; /* Determine how many jobs there are in the queue. */ dval = op_subq_stat (sq, OPC_QSTAT_PKSIZE); if (dval == OPC_DBL_INVALID) ta_wfq_error ("Unable to get number of packets in subqueue."); if ( (int)dval == SUBQ_EMPTY) { return 0.0; Tommy Svensson Alex Popescu 257
{ /* Get a handle to the tail packet */ pkptr = op_subq_pk_access (sq,OPC_QPOS_TAIL); if (pkptr == OPC_NIL) ta_wfq_error ("Unable to access packet in subqueue."); /* Determine VFT */ if (op_pk_nfd_get (pkptr, "svc_time_remain", &prev_pk_vft) == OPC_COMPCODE_FAILURE) ta_wfq_error ("Unable to get remaining service time from packet."); return prev_pk_vft; } } void ta_wfq_error (msg) char* msg; { /** Print an error message and exit the simulation. **/ FIN (ta_wfq_error (msg)); op_sim_end ("Error in WFQ process (ta_wfq):", msg, OPC_NIL, OPC_NIL); FOUT } /* End of Function Block */ /* Undefine optional tracing in FIN/FOUT/FRET */ /* The FSM has its own tracing code and the other */ /* functions should not have any tracing. */ #undef FIN_TRACING #define FIN_TRACING #undef FOUTRET_TRACING #define FOUTRET_TRACING #if defined (__cplusplus) extern "C" { #endif void ta_wfq (void); Compcode ta_wfq_init (void **); void ta_wfq_diag (void); void ta_wfq_terminate (void); void ta_wfq_svar (void *, const char *, char **); #if defined (__cplusplus) } /* end of 'extern "C"' */ #endif
258
Master thesis MEE 03:24 /* Process model interrupt handling procedure */ void ta_wfq (void) { int _block_origin = 0; FIN (ta_wfq ()); if (1) { Packet* pkptr; Objid orig_id; int i; int subq_no; double pk_prio; double VST; double VFT; double min_VFT; double SoQ; double dval; double instructions; double SVC_TIME; FSM_ENTER (ta_wfq) FSM_BLOCK_SWITCH { /*----------------------------------------------------
-----*/
/** state (init) enter executives **/ FSM_STATE_ENTER_FORCED_NOLABEL (0, "init", "ta_wfq [init enter execs]") FSM_PROFILE_SECTION_IN ("ta_wfq [init enter execs]", state0_enter_exec) { /** These executives are encountered only once, at the beginning of the simulation. **/ /** Their purpose is to initialize the process model. The attributes of this particular **/ /** module are determined and state variables are initialized. **/ /* Get queue module's own object id. */ own_id = op_id_self (); */ /* Get assigned value of server processing rate.
if (op_ima_obj_attr_get (own_id, "processing_rate", &processing_rate) == OPC_COMPCODE_FAILURE) ta_wfq_error ("Unable to get processing rate from attribute."); for(i=0;i<3;i++) { /* Get assigned value of the queue0-queue2
259
Master thesis MEE 03:24 if (op_ima_obj_attr_get (own_id, "queue_weight0", &weight[i] ) == OPC_COMPCODE_FAILURE) ta_wfq_error ("Unable to get queue weight from attribute."); } /* Set subqueues to inactive */ for(i=0;i<3;i++) { active_queues[i]=SUBQ_INACTIVE; } /* Set server as free */ server_busy= SERVER_FREE; } FSM_PROFILE_SECTION_OUT ("ta_wfq [init enter execs]", state0_enter_exec) /** state (init) exit executives **/ FSM_STATE_EXIT_FORCED (0, "init", "ta_wfq [init exit
execs]")
FSM_PROFILE_SECTION_IN ("ta_wfq [init exit execs]", state0_exit_exec) { } FSM_PROFILE_SECTION_OUT ("ta_wfq [init exit execs]", state0_exit_exec) /** state (init) transition processing **/ FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "init", "idle") /*--------------------------------------------------------*/
/** state (idle) enter executives **/ FSM_STATE_ENTER_UNFORCED (1, state1_enter_exec, "idle", "ta_wfq [idle enter execs]") FSM_PROFILE_SECTION_IN ("ta_wfq [idle enter execs]", state1_enter_exec) { } FSM_PROFILE_SECTION_OUT ("ta_wfq [idle enter execs]", state1_enter_exec) **/ /** blocking after enter executives of unforced state. FSM_EXIT (3,ta_wfq) /** state (idle) exit executives **/
260
Master thesis MEE 03:24 execs]") FSM_STATE_EXIT_UNFORCED (1, "idle", "ta_wfq [idle exit
FSM_PROFILE_SECTION_IN ("ta_wfq [idle exit execs]", state1_exit_exec) { } FSM_PROFILE_SECTION_OUT ("ta_wfq [idle exit execs]", state1_exit_exec) /** state (idle) transition processing **/ FSM_PROFILE_SECTION_IN ("ta_wfq [idle trans conditions]", state1_trans_conds) FSM_INIT_COND (SVC_COMPLETION) FSM_TEST_COND (PK_ARRIVAL) FSM_TEST_LOGIC ("idle") FSM_PROFILE_SECTION_OUT ("ta_wfq [idle trans conditions]", state1_trans_conds) FSM_TRANSIT_SWITCH { FSM_CASE_TRANSIT (0, 3, state3_enter_exec, ;, "SVC_COMPLETION", "", "idle", "svc_comp") FSM_CASE_TRANSIT (1, 2, state2_enter_exec, ;, "PK_ARRIVAL", "", "idle", "enqueue") } /*--------------------------------------------------------*/
/** state (enqueue) enter executives **/ FSM_STATE_ENTER_FORCED (2, state2_enter_exec, "enqueue", "ta_wfq [enqueue enter execs]") FSM_PROFILE_SECTION_IN ("ta_wfq [enqueue enter execs]", state2_enter_exec) { /** These executives are encountered when a packet arrives on an input stream. **/ /* Acquire the arriving packet. */ /* Multiple arriving streams are supported. */ pkptr = op_pk_get (op_intrpt_strm()); if (pkptr == OPC_NIL) ta_wfq_error ("Unable to get packet from /* Determine this packet's priority pk_prio=op_pk_priority_get (pkptr); */
input stream.");
/* Set subQueue as active */ active_queues[(int)pk_prio] = SUBQ_ACTIVE; /* Determine VFT for packet in queue tail */ VFT = get_VFT( (int)pk_prio );
261
Master thesis MEE 03:24 /* Calculate Vitrual Start Time */ VST = retmaximum ( VFT , VT() ); */ */ /* Get the number of instructions directly /* from the named field in the packet.
if (op_pk_nfd_get (pkptr, "instructions", &instructions) == OPC_COMPCODE_FAILURE) ta_wfq_error ("Unable to get instructions field from packet."); /* Calculate Service time fr this packet */ SVC_TIME = instructions/processing_rate; /* Calculate Share of Queue */ SoQ = SoQ_calc((int)pk_prio); /* Calculate Virtual Finish Time*/ VFT = VST + SVC_TIME/SoQ; /* Attach the VFT to the packet */ if (op_pk_nfd_set (pkptr, "svc_time_remain", VFT) == OPC_COMPCODE_FAILURE) ta_wfq_error ("Unable to set VFT field in packet."); /* Attach the service time to the packet */ if (op_pk_nfd_set (pkptr, "svc_time", SVC_TIME) ta_wfq_error ("Unable to set VFT field in
== OPC_COMPCODE_FAILURE) packet.");
subqueue pk_prio. */
if (op_subq_pk_insert ((int)pk_prio, pkptr, OPC_QPOS_TAIL) != OPC_QINS_OK) { /* The insertion failed (due to a full queue). Deallocate the packet. */ op_pk_destroy (pkptr); } } FSM_PROFILE_SECTION_OUT ("ta_wfq [enqueue enter execs]", state2_enter_exec) /** state (enqueue) exit executives **/ FSM_STATE_EXIT_FORCED (2, "enqueue", "ta_wfq [enqueue
exit execs]")
FSM_PROFILE_SECTION_IN ("ta_wfq [enqueue exit execs]", state2_exit_exec) { } FSM_PROFILE_SECTION_OUT ("ta_wfq [enqueue exit execs]", state2_exit_exec) Tommy Svensson Alex Popescu 262
/** state (enqueue) transition processing **/ FSM_PROFILE_SECTION_IN ("ta_wfq [enqueue trans conditions]", state2_trans_conds) FSM_INIT_COND (!server_busy) FSM_DFLT_COND FSM_TEST_LOGIC ("enqueue") FSM_PROFILE_SECTION_OUT ("ta_wfq [enqueue trans conditions]", state2_trans_conds) FSM_TRANSIT_SWITCH { FSM_CASE_TRANSIT (0, 4, state4_enter_exec, ;, "!server_busy", "", "enqueue", "scheduler") FSM_CASE_TRANSIT (1, 1, state1_enter_exec, ;, "default", "", "enqueue", "idle") } /*--------------------------------------------------------*/
/** state (svc_comp) enter executives **/ FSM_STATE_ENTER_FORCED (3, state3_enter_exec, "svc_comp", "ta_wfq [svc_comp enter execs]") FSM_PROFILE_SECTION_IN ("ta_wfq [svc_comp enter execs]", state3_enter_exec) { /** These executives are encountered when a packet completes **/ /** service. **/ completing service. */ the service */ /* Determine the subqueue of the packet just /* This is passed as the code associated with /* completion interrupt. */ subq_no = op_intrpt_code (); /* Extract the packet which is the current job. /* This is the packet just finishing service. pkptr = op_subq_pk_remove (subq_no,
*/ */ OPC_QPOS_HEAD);
if (pkptr == OPC_NIL) ta_wfq_error ("Unable to extract packet to service from subqueue."); packet. */ /* Packet has been serviced. Deallocate the op_pk_destroy (pkptr); /* Determine if subqueue is empty */ Tommy Svensson Alex Popescu 263
Master thesis MEE 03:24 dval = op_subq_stat (subq_no, OPC_QSTAT_PKSIZE); if (dval == OPC_DBL_INVALID) ta_wfq_error ("Unable to get number of if (dval==0.0) active_queues[subq_no]=SUBQ_INACTIVE; /* Determine if there still are packets i the if (QUEUE_EMPTY) server_busy=SERVER_FREE; } FSM_PROFILE_SECTION_OUT ("ta_wfq [svc_comp enter execs]", state3_enter_exec) /** state (svc_comp) exit executives **/ FSM_STATE_EXIT_FORCED (3, "svc_comp", "ta_wfq [svc_comp exit execs]") FSM_PROFILE_SECTION_IN ("ta_wfq [svc_comp exit execs]", state3_exit_exec) { } FSM_PROFILE_SECTION_OUT ("ta_wfq [svc_comp exit execs]", state3_exit_exec) /** state (svc_comp) transition processing **/ FSM_PROFILE_SECTION_IN ("ta_wfq [svc_comp trans conditions]", state3_trans_conds) FSM_INIT_COND (!QUEUE_EMPTY) FSM_DFLT_COND FSM_TEST_LOGIC ("svc_comp") FSM_PROFILE_SECTION_OUT ("ta_wfq [svc_comp trans conditions]", state3_trans_conds) FSM_TRANSIT_SWITCH { FSM_CASE_TRANSIT (0, 4, state4_enter_exec, ;, "!QUEUE_EMPTY", "", "svc_comp", "scheduler") FSM_CASE_TRANSIT (1, 1, state1_enter_exec, ;, "default", "", "svc_comp", "idle") } /*--------------------------------------------------------*/
packets in subqueue.");
system */
/** state (scheduler) enter executives **/ FSM_STATE_ENTER_FORCED (4, state4_enter_exec, "scheduler", "ta_wfq [scheduler enter execs]") FSM_PROFILE_SECTION_IN ("ta_wfq [scheduler enter execs]", state4_enter_exec) { /** These executives schedules the packet with smallest VFQ for transmisstion. **/ Tommy Svensson Alex Popescu 264
Master thesis MEE 03:24 /* Determine subq with smallest VFT */ subq_no=0; min_VFT=0.0; for (i=0;i<3;i++) { if (active_queues[i]==SUBQ_ACTIVE) { /* Get a handle to the HoL packet */ pkptr = op_subq_pk_access if (pkptr == OPC_NIL) ta_wfq_error ("Unable to
(i,OPC_QPOS_HEAD);
/* Determine VFT */ if (op_pk_nfd_get (pkptr, "svc_time_remain", &VFT) == OPC_COMPCODE_FAILURE) ta_wfq_error ("Unable to get VFT from packet."); if (min_VFT==0.0) { min_VFT=VFT; subq_no=i; } else if (min_VFT>VFT) { min_VFT=VFT; subq_no=i; } }
(subq_no,OPC_QPOS_HEAD); subqueue.");
/* Access packet with smallest VFT */ pkptr = op_subq_pk_access if (pkptr == OPC_NIL) ta_wfq_error ("Unable to access packet in /* Determine the packet's service time */ if (op_pk_nfd_get (pkptr, "svc_time", &SVC_TIME) ta_wfq_error ("Unable to get service time /* Schedule the packet for service */ op_intrpt_schedule_self (op_sim_time () + /* Set server as busy */ server_busy=SERVER_BUSY; }
SVC_TIME, subq_no);
265
Master thesis MEE 03:24 FSM_PROFILE_SECTION_OUT ("ta_wfq [scheduler enter execs]", state4_enter_exec) /** state (scheduler) exit executives **/ FSM_STATE_EXIT_FORCED (4, "scheduler", "ta_wfq [scheduler exit execs]") FSM_PROFILE_SECTION_IN ("ta_wfq [scheduler exit execs]", state4_exit_exec) { } FSM_PROFILE_SECTION_OUT ("ta_wfq [scheduler exit execs]", state4_exit_exec) /** state (scheduler) transition processing **/ FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "scheduler", "idle") /*--------------------------------------------------------*/
} FSM_EXIT (0,ta_wfq) }
#if defined (__cplusplus) extern "C" { #endif extern VosT_Fun_Status Vos_Catmem_Register (const char * , int , VosT_Void_Null_Proc, VosT_Address *); extern VosT_Address Vos_Catmem_Alloc (VosT_Address, size_t); extern VosT_Fun_Status Vos_Catmem_Dealloc (VosT_Address); #if defined (__cplusplus) } #endif Compcode ta_wfq_init (void ** gen_state_pptr) { int _block_origin = 0; static VosT_Address obtype = OPC_NIL; FIN (ta_wfq_init (gen_state_pptr)) if (obtype == OPC_NIL) { /* Initialize memory management */ if (Vos_Catmem_Register ("proc state vars (ta_wfq)", sizeof (ta_wfq_state), Vos_Vnop, &obtype) == VOSC_FAILURE) { Tommy Svensson Alex Popescu 266
*gen_state_pptr = Vos_Catmem_Alloc (obtype, 1); if (*gen_state_pptr == OPC_NIL) { FRET (OPC_COMPCODE_FAILURE) } else { /* Initialize FSM handling */ ((ta_wfq_state *)(*gen_state_pptr))->current_block = 0; FRET (OPC_COMPCODE_SUCCESS) }
void ta_wfq_terminate (void) { int _block_origin = __LINE__; FIN (ta_wfq_terminate (void)) Vos_Catmem_Dealloc (pr_state_ptr); FOUT } /* Undefine shortcuts to state variables to avoid */ /* syntax error in direct access to fields of */ /* local variable prs_ptr in ta_wfq_svar function. */ #undef processing_rate #undef own_id #undef weight #undef active_queues #undef server_busy
void ta_wfq_svar (void * gen_ptr, const char * var_name, char ** var_p_ptr) { ta_wfq_state *prs_ptr; Tommy Svensson Alex Popescu 267
Master thesis MEE 03:24 FIN (ta_wfq_svar (gen_ptr, var_name, var_p_ptr)) if (var_name == OPC_NIL) { *var_p_ptr = (char *)OPC_NIL; FOUT } prs_ptr = (ta_wfq_state *)gen_ptr; if (strcmp ("processing_rate" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->processing_rate); FOUT } if (strcmp ("own_id" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->own_id); FOUT } if (strcmp ("weight" , var_name) == 0) { *var_p_ptr = (char *) (prs_ptr->weight); FOUT } if (strcmp ("active_queues" , var_name) == 0) { *var_p_ptr = (char *) (prs_ptr->active_queues); FOUT } if (strcmp ("server_busy" , var_name) == 0) { *var_p_ptr = (char *) (&prs_ptr->server_busy); FOUT } *var_p_ptr = (char *)OPC_NIL; FOUT }
268