Documentation Page Format: 1-Introduction

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 14

1—Introduction

1 Introduction
This document serves as a reference for the services provided by the
Simulation Kernel and to the means of accessing these services. For the most
part, the simulation services are accessed through Kernel Procedures (KPs),
which are procedures that can be called from within process models,
Transceiver Pipeline stages, C/C++ functions that have been scheduled as
interrupts, or simply C/C++ functions that are directly or indirectly invoked from
one of these contexts.

KPs are categorized by primary function, based on the types of objects they
attempt to manipulate. The collection of KPs within a category is called a
package, and KPs within the same package share a common package keyword
in their procedure names. For instance, a large number of KPs are concerned
with manipulating packets; these are grouped together in the Packet package
and use the “pk” keyword. Each package has its own section. Sections are
arranged alphabetically, based on the package name.

You can view function descriptions from the documentation or by choosing


Help > Help on all KPs from the Modeler menu bar.

Documentation Page Format


Manual pages that describe KPs all have the same appearance and structure.
The pages for each KP are divided into the following sections:

Banner Displays the name of the KP in large type at the top of the page. The KP banner
includes an empty pair of parentheses (representing the argument list for the
KP).

Abstract Gives a brief synopsis of the KP usage. Most users will begin by browsing this
section when first learning about the KP.

Syntax Displays the calling syntax of the KP using a variation on the standard C/C++
function interface notation. The name of the KP is repeated, this time with a fully
specified argument list. Underneath this first line, the KP arguments are
detailed. Each argument’s name, data type, and description appears in a table.
Additional detailed information describes the techniques used to obtain certain
data types, or the appropriate symbolic constants to use as flag values.

Return Type Gives the data type of the return value of the KP and a short description of the
interpretation and use of the value.

Modeler/Release 14.0 DES-1-1


1—Introduction

Example Lists C/C++ or Transceiver Pipeline Model statements that show typical usage
of the KP. In some instances, the listing has been specially prepared for this
manual, while in other instances the listing is an excerpt from an example model
supplied with OPNET. Statement that invoke the current KP is in bold typeface.

Details Contains narrative text that explains portions of background modeling theory,
discusses limitations or special considerations of using the KP, and presents
detailed information about the KP internal operations, as needed.

Purpose Contains a less formal discussion of the need for the KP and explains the
primary application of the KP in simulations.

Errors Lists errors that can occur while the current KP is executing. Listed errors might
be controlled (i.e., the detection of special conditions by if statements,
resulting in a specific error message) or uncontrolled (i.e., an operating system
trap which detects a bad memory access).

Reference Lists KPs that are related to the current KP. Related KPs can be inverse in
nature to the current KP, variations on the current KP, or commonly used in
conjunction with the current KP. The goal of this section is to point users in
useful directions when they are looking for a KP to do a specific task.

Kernel Procedure Names


KP names have a standard structure. This policy has been adopted to make
KPs more visible in C/C++ code, to avoid naming conflicts with non-OPNET
procedures or variables, and to serve as an aid to recall procedure names and
purposes. The naming structure has a few simple rules:

• Names begin with the prefix op_, which serves to identify KPs as being
provided by the OPNET Simulation Kernel.

• The second word in a KP name is the package name (in lower case letters),
which is usually an abbreviated name of the object that the package
manipulates (e.g., pk, ici, or stat).

• The third word in a name may be a sub-package name (e.g., nfd in the KP
op_pk_nfd_set()), which provides a further categorization of the KP.

• Typically, KPs perform operations on objects. In KP names, the object


always appears before the action. For instance, the name fragments attr_set
and subq_flush place objects (attribute and subqueue) before actions (set
and flush).

DES-1-2 Modeler/Release 14.0


1—Introduction

Argument Data Types


The Syntax and Return Type sections of KP manual pages present the calling
syntax of a KP. Each argument of the procedure is separately listed, as well as
the procedure’s return type. Argument listings include the name, C/C++ data
type, and description text; the return type is similar, except it lacks a name. The
purpose of these two sections is to clearly define the calling interface of a KP,
and to avoid incorrect interpretation of the return value or argument data types.

Many arguments and return values of KPs are standard C/C++ data types, such
as int, double, and char*.

Besides the basic C/C++ data types, arguments and return values are often
declared to be special OPNET data types. These data types are derived from
simulation data structures via the typedef statement of the C/C++ language.
Although users are involved in manipulating OPNET data types via KPs, and
they become familiar with the basic contents of each data type, the exact
internal structure of the data type need not be of concern. In fact, the contents
of simulation data structures may change in new releases of the software, so it
is good practice to not depend on undocumented internal fields of the data
structures. Each of the special data types are introduced in the following
sections.

• Animation Entities

• Booleans

• Compcodes

• Distributions

• Event Handles

• Statistic Handles

• ICIs

• Lists

• Object IDs

• Packets

• Memory Object Types

• Log Handles

• Procedures

• Process Handles

• SAR Buffer Handles

Modeler/Release 14.0 DES-1-3


1—Introduction

Animation Entities
The Anim (Animation) package relies on numeric “serial numbers” (IDs) to refer
to specific animation entities involved in operations. Integer IDs are used
instead of C/C++ pointers because the IDs are communicated beyond the
scope of the simulation, to the animation viewer program, op_vuanim. Even
though the IDs are simply integer values, and may be stored in regular C/C++
integer variables, specific data types have been declared to precisely tag ID
arguments and variables. The three animation entities referenced by IDs are
viewers, macros, and drawings; their respective data types are listed below.

Base Data Type Anvid (viewer ID)

Example Declaration Anvid vid;

Base Data Type Anmid (macro ID)

Example Declaration Anmid mid;

Base Data Type Andid (drawing ID)

Example Declaration Andid did;

Booleans
Booleans are values returned by many Kernel Procedures to indicate a true or
false result. The value of a Boolean can be compared to the symbolic constants
OPC_TRUE and OPC_FALSE.

Base Data Type Boolean

Example Declaration Boolean bool;

Compcodes
Compcodes are values returned by many Kernel Procedures that indicate
whether an operation completed successfully. The value of a Compcode may
be compared to the symbolic constants OPC_COMPCODE_SUCCESS and
OPC_COMPCODE_FAILURE.

Base Data Type Compcode

Example Declaration Compcode comp_status;

DES-1-4 Modeler/Release 14.0


1—Introduction

Distributions
Distributions are data structures that describe the mapping of a random number
into a specific numeric outcome, consistent with a probability density function
(PDF). The distribution can include a numeric table which encodes the mapping,
or it can point to an algorithm which will perform the mapping. For table-based
distributions, the contents data is read in from a PDF model file which has been
prepared using the PDF Editor. These structures are manipulated by the Dist
package KPs.

Base Data Type Distribution

Example Declaration Distribution* dist_ptr;

Event Handles
Event handles are data structures which uniquely identify a pending simulation
event (interrupt). These structures are used by Intrpt Package KPs, so that
scheduled interrupts can be manipulated through their handle. Note that event
handles are actually data structures, and not integers or pointers. Therefore,
they should not be cast into or stored in integer or pointer variables.

Base Data Type Evhandle

Example Declaration Evhandle evh;

Statistic Handles
Statistic handles are data structures used to identify global and local statistics
that are created dynamically. The data type provided for these handles is
Stathandle and the only way to obtain such a handle is by “registering” a statistic
via a KP dedicated to this purpose in the Stat package. A statistic has a unique
name that is specified at registration, and also an output vector used to store its
values over time. Local statistics are used within a specific processor or queue.
Global statistics are typically shared by several different entities in a simulation
model, and each of these entities contributes to the output vector in a distributed
manner.

Base Data Type Stathandle

Example Declaration Stathandle stat_handle;

Modeler/Release 14.0 DES-1-5


1—Introduction

ICIs
ICIs (Interface Control Information) are collections of structured data associated
with simulation interrupts. They serve as an inter-process communication
mechanism, specialized for conveying information which controls layered
protocol interfaces. These structures are manipulated by Ici package KPs.

Base Data Type Ici

Example Declaration Ici* ici_ptr;

Lists
Lists are ordered collections of data elements, stored in a doubly-linked chain.
Elements in lists can range from simple C/C++ data types to complex data
structures. Lists can be heterogeneous, containing collections of varied
elements, but they typically are not. Lists can grow arbitrarily large; elements
can be inserted into or removed from any specified position. Lists are often used
to temporarily store groups of related data structures. These structures are
manipulated by the List sub-package of the Prg package.

Base Data Type List

Example Declaration List* list_ptr;

Object IDs
An object ID is a numeric “serial number” that uniquely identifies a single
simulation object. The Objid data type is used to declare these identifiers. Objids
are used by the Id, Ima, Topo and Pk packages.

Base Data Type Objid

Example Declaration Objid objid;

Packets
Packets are the fundamental simulation entity for modeling encapsulation and
transmission of data. These structures are manipulated by Pk package KPs.

Base Data Type Packet

Example Declaration Packet* pkptr;

DES-1-6 Modeler/Release 14.0


1—Introduction

Memory Object Types


Some modeling applications may require memory to be allocated on a dynamic
basis in order to provide storage for variable amounts of information. When new
data items are created and destroyed on a recurring basis and groups of items
of the same physical size (in terms of bytes) can be identified, it is often most
efficient to use the Pooled Memory facility provided by the Simulation Kernel.
Each group of equally sized data items is referred to as a pool, and the Kernel
is able to simultaneously allocate large numbers of items at once for each pool
in order to improve efficiency over the standard memory allocator. Each pooled
memory object type must be created by calling the KP op_prg_pmo_define(),
which returns a Pooled Memory Object Handle that identifies the pool. The data
type provided for these handles is Pmohandle. A pooled memory object type
has a unique name that is specified when it is created. Each pooled memory
object type is typically shared by multiple entities in a simulation model.

Base Data Type Pmohandle

Example Declaration Pmohandle pmh;

Log Handles
When creating simulation logs to aid in simulation debugging or results analysis,
a log handle is necessary for each category of log entry.

Base Data Type Log_Handle

Example Declaration Log_Handle config_log_hndl;

Procedures
Several KPs take C/C++ function pointers as arguments. Instead of declaring
these arguments as pointers to functions which return integers, a special data
type has been defined for use in the declarations, called Procedure.

Base Data Type Procedure

Example Declaration Procedure proc;

Modeler/Release 14.0 DES-1-7


1—Introduction

Process Handles
Process handles are data structures which uniquely identify an active process
within a simulation. These structures are used by Pro package KPs, so that
operations can be performed on processes. Process handles are actually data
structures, and not integers or pointers. Therefore, they should not be cast into
or stored in integer or pointer variables.

Base Data Type Prohandle

Example Declaration Prohandle proh;

SAR Buffer Handles


A Sar Buffer Handle is a data structure that uniquely identifies a Sar
(Segmentation & Reassembly) buffer, an object that buffers sequences of
packets, and can either split packets into segments, or reassemble the
segments into packets. Sar buffers are created by a KP in the Sar package,
which returns a Sar buffer handle for accessing the new buffer. Sar buffer
handles are passed to most Sar package KPs, so that the KPs can operate on
the identified Sar buffer. As with other handle data structures, Sar buffer
handles should not be cast into, or assigned to, integers or pointers.

Base Data Type Sbhandle

Example Declaration Sbhandle sbh;

Function Stack Tracing


One of the most useful techniques for diagnosing and debugging program
errors is the stack traceback: i.e., a listing of all the function calls which are
currently on the stack of the executing program. A traceback serves as a
roadmap to the location of the error, pinpointing the place in the “tree of
functions” at which the error occurred. Many times, the cause of an error may
be located in a part of the program far removed from the location of the error’s
occurrence, but the traceback still is an important starting point.

All OPNET programs, including simulations, have the capability of generating a


stack traceback for OPNET-supplied functions (operating system calls are not
included in the traceback, because the stack tracing technology requires that
special code be included in traced functions). Should an error occur, the
traceback of functions can be printed using the op_vuerr utility (documented in
op_vuerr on page EI-3-76). Figure 1-1 shows an example op_vuerr output
listing. Note that the stack listing consists of a series of function references,
each of which consists of the function name and a list of its argument names.

DES-1-8 Modeler/Release 14.0


1—Introduction

The function listing builds down, from the top-level function towards the function
in which the error occurred. Thus, in the example, function #10
(sim_err_pk_access()) is associated with the segmentation violation that
caused the program to abort.

Figure 1-1 Example Output of op_vuerr

extracted the following messages from 'err_log' file:

<<< Program Abort >>>


* Time: 13:32:07 Wed Aug 06 2003
* Product: modeler
* Program: op_runsim (Version 10.0.A PL1 Build 2282)
* System: Windows NT 5.0 Build 2195
* Package: process (acb_fifo) at module (top.m1.queue)
* Function: sim_err_pk_access
* Error: Packet pointer is NIL
T (0), EV (4), MOD (top.m1.queue), KP (op_pk_destroy)

* Function call stack: (builds down)


------------------------------------------------------------
Call Block
Count Line# Function
------------------------------------------------------------
0) 1 1073741928 0x09254d0e [name not available]
1) 1 1879048703 0x00004c00 [name not available]
2) 1 -805306207 0x0000c400 [name not available]
3) 1 284 m3_main
4) 1 935 sim_main
5) 1 2364 sim_ev_loop
6) 1 354 sim_strm_insert
7) 5 522 sim_obj_qps_intrpt
8) 2 1 acb_fifo [arrival enter execs]
9) 1 1341 op_pk_destroy (pkptr)
10) 1 1483 sim_err_pk_access
------------------------------------------------------------

In simulations, all OPNET-supplied functions, including Kernel Procedures


documented in this manual and the underlying Simulation Kernel functions,
incorporate stack tracing code. User-defined simulation functions, which appear
in process model function blocks or external C/C++ files, can also be traced. In
fact, most users find the best application of op_vuerr is assisting their
simulation function debugging.

For a user-defined simulation function to be traced, it must incorporate the


special stack tracing code. Stack tracing is accomplished by inserting
preprocessor macro statements at the entrance point and exit point(s) of a
function (a function has only one entrance point, but can have multiple exit
points due to the return statement of C). The macro statements are named
FIN, FOUT, and FRET (which stand for Function-In, Function-Out, and
Function-Returns, respectively). FIN is inserted at the function entrance point,
FOUT is inserted at function exit points which do not return any value, and FRET
is inserted at function exit points which do return a value.

Note—The FIN macro might be replaced by a FIN_MT macro in some functions


that support parallel simulation (as described in Simulation Context Pointer on
page MC-11-51). The syntax of FIN and FIN_MT is identical.

Modeler/Release 14.0 DES-1-9


1—Introduction

Syntax guides for these macros appear below, followed by example functions
that use them. Note that these macros do not need trailing semi-colons (they
include their own) and that the argument to FIN does not require double-quotes
(it also includes its own).

FIN (<function name & arguments>)


FOUT
FRET (<return type>)

Figure 1-2 Example Use of FIN / FRET

int
sum_three (int a, int b, int c)
{
int sum;

FIN (sum_three (a, b, c))


sum = a + b + c;
FRET (sum)
}

Figure 1-3 Example Use of FIN / FOUT

void
pr_banner (char* string)
{
FIN (pr_banner (string))
printf ("-----------\n");
printf ("%s\n", string);
printf ("-----------\n");
FOUT
}

All example models provided with OPNET incorporate these macros, and it is
recommended that user-defined functions incorporate them as well. If FIN,
FOUT, and FRET statements are properly inserted into user-defined functions,
op_vuerr can be used to determine the location of a program error even in a
nested group of model function calls.

WARNING—Do not use the FIN, FOUT, and FRET macros in the main()
function of an EMA or ET program. An abnormal function stack imbalance error
will occur if these macros occur before either prg_init(), Vos_Init(), or Ema_Init()
has been invoked.

DES-1-10 Modeler/Release 14.0


1—Introduction

Variable Name Limitations


In general, users are free to select any syntactically correct names for variables
used within process models. A minor limitation on this is presented by the C/C++
language and most workstation linkers, however. In the C/C++ language, if a
global or local variable has the same name as a function, then statements
invoking the function will actually resolve to the variable, instead of the intended
function’s code. Thus, when statements attempt to invoke such a function, the
program starts executing whatever bytes it finds starting at the variable’s
address as if it were a function, usually leading to a program abort via illegal
instruction.

The above problem does not manifest itself in process model state variables,
due to the way they are preprocessed into data structure references. However,
process model temporary (local) and header block (global) variables can
override function names, so care must be taken not to choose variable names
which have the same names as functions.

The most common way in which the name overriding problem occurs is not due
to user-defined variable names conflicting with user-defined function names.
Instead, user-defined variable names conflict with short system call function
names that the user is not even aware are being linked into the simulation. The
most likely “conflict list” of function names appears in Table 1-1; users should
avoid duplicating these names for use as variables.

Note—The function names in Table 1-1 represent only a subset of possible


conflicting function names. For a complete list, refer to the Solaris or Linux
manuals or to a Windows API reference.

Table 1-1 Possible Function Name Conflicts


accept() index() send()

access() kill() signal()

audit() link() socket()

bind() listen() stat()

clear() open() tell()

clock() pipe() truncate()

close() poll() unlink()

connect() read() wait()

exit() select()

End of Table 1-1

Modeler/Release 14.0 DES-1-11


1—Introduction

Multi-Threading Safety
Modeler has a parallel simulation kernel that allows simulations to use multiple
processors. To ensure that activities such as the parallel transmission of
packets are performed correctly and as quickly as possible, any code involved
must use multi-threading-safe APIs (Kernel Procedures and PRG functions).

OPNET APIs have one of two possible multi-threading safeness levels:

• MT-safe: These APIs support multi-threading. Multiple threads can execute


these APIs in parallel without danger.

• MT-unsafe: These APIs do not support multi-threading. It is the responsibility


of the user to perform appropriate serialization of code that uses MT-unsafe
APIs. (Enabling parallelism in these APIs would result in performance loss,
rather than the expected gain due to parallelism.)

Most KPs and PRG APIs are MT-safe. Those that are not, or that have some
restrictions to their safeness, are identified as such in the API description and
are listed in Table 1-2.

Note—Some packages are not supported by the parallel kernel. If used in a


parallel simulation, APIs from such packages will either fail or do nothing.

Table 1-2 MT-Unsafe KPs and PRG APIs


KP Comment

op_anim_ package Unsafe. Use of animation KPs (especially macro


definitions) must be serialized by the user.

op_esys_ package The External System package is not supported by


the parallel kernel.

op_ev_count(), op_ev_count_local(), Safe, but deterministic only for future events


op_ev_next(), op_ev_next_local(), (those outside the current execution time
op_ev_pending(), op_ev_seek_time() window). We recommend not using these KPs in
parallel simulations.

op_ima_obj_svar_get() Safe, but must be used with care if multiple clients


are accessing or modifying shared svar
information.

op_prg_list_ sub-package Unsafe. Access to shared lists must be serialized


by the user.

op_pro_svar_get() Safe, but must be used with care if multiple clients


are accessing or modifying shared svar
information.

prg_string_hash_table package Unsafe. Access to shared hash tables must be


serialized by the user.

DES-1-12 Modeler/Release 14.0


1—Introduction

Table 1-2 MT-Unsafe KPs and PRG APIs (Continued)


KP Comment

prg_list package Unsafe. Access to shared lists must be serialized


by the user.

prg_map package Unsafe. Access to mapped data elements that are


shared must be serialized by the user.

prg_vector package Unsafe. Access to shared vectors must be


serialized by the user.

End of Table 1-2

Manual Terminology
This manual incorporates special terminology for discussing the relationships of
KPs and the environment in which they operate. The terminology is not
completely unique to this manual, but it is a slight variation on the general set of
terminology used in the complete documentation set. Several terms are defined
below.

Contexts
There are four contexts in which users can define procedural logic which is
integrated into a simulation. These contexts are fundamentally different in terms
of the resources available to the C/C++ statements which form the procedural
logic. The interface between user-specified C/C++ statements and simulation
resources is provided by Simulation Kernel procedures (KPs), and the four
different contexts each present a different set of limitations on which KPs can
be invoked. Many KPs are usable in all four contexts; exceptions are noted in
the KP documentation within this manual. The four contexts are listed below:

• A process running on a processor module. In this context, a process has


access to input streams, output streams, input statistics, output statistics,
state variables, temporary variables, header block definitions, incoming
interrupts, ICIs, and packets. In addition to C/C++ statements which are
embedded within the associated process model, this context includes C/C++
functions which are directly or indirectly invoked by a statement in the
process model.

• A process running on a queue module. In this context, a process has access


to all of the resources listed above for the processor context, in addition to
the resources which are unique to a queue. These resources include an
internal bank of subqueues, and access to the Q and Subq Package KPs.

Modeler/Release 14.0 DES-1-13


1—Introduction

• A Transceiver Pipeline model (i.e., a C/C++ function which serves as a stage


in a link model pipeline). Many KPs cannot be used within this context, since
they rely on the resources available to a process. The majority of KPs used
by pipeline models are from the Td package, which provides access to
transmission data attributes stored within packets.

• A C/C++ function which was scheduled for execution via the KP


op_intrpt_schedule_call(). For the most part, this context provides the same
resources as the context from which it was scheduled. That is, if a process
schedules a call to a procedure, the procedure will essentially be able to
perform the same set of tasks as the process itself. Depending upon where
the code for this procedure is defined, it may not have access to the state
variables of the process, however.

Invoking Process
As mentioned above, a KP can be invoked from one of four different execution
contexts. However, the vast majority of invocations of KPs are from the first two
contexts (i.e., from processes running on processors or queues). In the
documentation pages for KPs, the process that invoked the KP under
discussion is called the invoking process. The invoking process is also
sometimes called the current process.

Surrounding Module / Node / Subnet


In the documentation pages for KPs, the module on which the invoking process
is running is called the surrounding module (i.e., the processor or queue
conceptually surrounds the process model and the local resources it
manipulates). Similarly, an object that is the parent of another object
conceptually surrounds the child it contains. Thus the surrounding node and
surrounding subnet are the parent (and “grandparent”) objects of the invoking
process’ surrounding module. The term current module is also sometimes used
to mean surrounding module.

DES-1-14 Modeler/Release 14.0

You might also like