⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 otcl.tex

📁 对IEEE 802.11e里的分布式信道接入算法EDCA进行改进
💻 TEX
📖 第 1 页 / 共 4 页
字号:
\chapter{OTcl Linkage}\label{chap:otcl:intro}\ns\ is an object oriented simulator,written in C++, with an OTcl interpreter as a frontend.The simulator supports a class hierarchy in C++(also called the compiled hierarchy in this document),and a similar class hierarchy within the OTcl interpreter(also called the interpreted hierarchy in this document).The two hierarchies are closely related to each other;from the user's perspective,there is a one-to-one correspondencebetween a class in the interpreted hierarchyand one in the compiled hierarchy.The root of this hierarchy is the class TclObject.Users create new simulator objects through the interpreter;these objects are instantiated within the interpreter, and are closely mirrored by a corresponding objectin the compiled hierarchy.The interpreted class hierarchy is automatically established throughmethods defined in the class TclClass.user instantiated objects are mirrored through methodsdefined in the class TclObject.There are other hierarchies in the C++ code and OTcl scripts;these other hierarchies are not mirrored in the manner of TclObject.\section{Concept Overview}\emph{Why two languages?}\ns\ uses two languages because simulator has two different  kinds of things it needs to do.On one hand, detailed simulations of protocols  requires a systems programming language  which can efficiently manipulate bytes, packet headers,  and implement algorithms that run over large data sets.For these tasks run-time speed is important and  turn-around time (run simulation, find bug, fix bug, recompile, re-run)  is less important.On the other hand,  a large part of network research involves slightly varying  parameters or configurations,  or quickly exploring a number of scenarios.In these cases, iteration time (change the model and re-run)  is more important.Since configuration runs once (at the beginning of the simulation),  run-time of this part of the task is less important.\ns\ meets both of these needs with two languages,  C++ and OTcl.C++ is fast to run but slower to change, making it suitable  for detailed protocol implementation.OTcl runs much slower but can be changed very quickly (and interactively),  making it ideal for simulation configuration.\ns\ (via \code{tclcl})  provides glue to make objects and variables appear on both langauges.For more information about the idea of scripting languages  and split-language programming, see Ousterhout's article  in IEEE Computer~\cite{Ousterhout98a}.For more information about split level programming for network simulation,  see the ns paper~\cite{Bajaj99a}.\emph{Which language for what?}Having two languages raises the question of which language shouldbe used for what purpose.Our basic advice is to use OTcl:\begin{itemize}\item for configuration, setup, and ``one-time'' stuff\item if you can do what you want by manipulating existing C++ objects\end{itemize}and use C++:\begin{itemize}\item if you are doing \emph{anything} that requires processing	each packet of a flow\item if you have to change the behavior of an existing C++ class	in ways that weren't anticipated\end{itemize}For example, links are OTcl objects that assemble delay, queueing, andpossibly loss modules.  If your experiment can be done with thosepieces, great.  If instead you want do something fancier (a specialqueueing dicipline or model of loss), then you'll need a new C++object.There are certainly grey areas in this spectrum:most routing is done in OTcl(although the core Dijkstra algorithm is in C++).We've had HTTP simulations where each flow was started in OTcl  and per-packet processing was all in C++.This approache worked OK until we had 100s of flows  starting per second of simulated time.In general, if you're ever having to invoke Tcl many times per second,  you problably should move that code to C++.\section{Code Overview}In this document,we use the term ``interpreter''to be synonymous with the OTcl interpreter.The code to interface with the interpreter residesin a separate directory, \code{tclcl}.The rest of the simulator code resides in the directory, \code{ns-2}.We will use the notation \Tclf{\tup{file}}\to refer to a particular \tup{file}\ in the\code{Tcl}\ directory.Similarly, we will use the notation, \nsf{\tup{file}}to refer to a particular \tup{file}\ in the \code{ns-2} directory.There are a number of classes defined in \Tclf{}.We only focus on the six that are used in \ns:The \href{Class Tcl}{Section}{sec:Tcl} contains the methods thatC++ code will use to access the interpreter.The \href{class TclObject}{Section}{sec:TclObject}is the base class for all simulator objects that are also mirrored in the compiled hierarchy.The \href{class TclClass}{Section}{sec:TclClass} definesthe interpreted class hierarchy, and the methods to permit the user to instantiate TclObjects.The \href{class TclCommand}{Section}{sec:TclCommand}is used to define simple global interpreter commands.The \href{class EmbeddedTcl}{Section}{sec:EmbeddedTcl}contains the methods to load higher level builtin commandsthat make configuring simulations easier.Finally, the \href{class InstVar}{Section}{sec:InstVar}contains methods to access C++ member variablesas OTcl instance variables.The procedures and functions described in this chapter can be found in\Tclf{Tcl.\{cc, h\}}, \Tclf{Tcl2.cc}, \Tclf{tcl-object.tcl}, and,\Tclf{tracedvar.\{cc, h\}}.The file \Tclf{tcl2c++.c} is used in building \ns, and is mentionedbriefly in this chapter.\section{Class Tcl}\label{sec:Tcl}The \clsref{Tcl}{../Tcl/Tcl.h} encapsulates the actual instance ofthe OTcl interpreter, and provides the methodsto access and communicate with that interpreter.The methods described in this section are relevant to the\ns\ programmer who is writing C++ code.The class provides methods for the following operations:\begin{list}{\textbullet}{}\itemsep0pt\item obtain a reference to the Tcl instance;%  {\tt%    \begin{list}{}{}%    \item \fcn[]{Tc::instance}%    \end{list}%  }\item invoke OTcl procedures through the interpreter;%  {\tt%    \begin{list}{}{}%    \item \fcn[char* $s$]{Tcl::eval}%    \item \fcn[const char* $s$]{Tcl::evalc}%    \item \fcn[]{Tcl::eval}%    \item \fcn[const char* $\mathit{fmt}$, \ldots]{Tcl::evalf}%    \end{list}%  }\item retrieve, or pass back results to the interpreter;%  {\tt%    \begin{list}{}{}%    \item \fcn[const char* $s$]{Tcl::result}%    \item \fcn[const char* $\mathit{fmt}$, \ldots]{Tcl::resultf}%    \item \fcn[]{Tcl::result}%    \end{list}%  }\item report error situations and exit in an uniform manner; and%  {\tt%    \begin{list}{}{}%    \item \fcn[const char* $s$]{Tcl::error}%    \end{list}%  }\item store and lookup ``TclObjects''.%  {\tt%    \begin{list}{}{}%    \item \fcn[const char* $s$]{Tcl::lookup}%    \item \fcn[TclObject* $o$]{Tcl::enter}%    \item \fcn[TclObject* $o$]{Tcl::remove}%    \end{list}%  }\item acquire direct access to the interpreter.%  {\tt%    \begin{list}{}{}%    \item \fcn[]{Tcl::interp}%    \end{list}%  }\end{list}We describe each of the methods in the following subsections.\subsection{Obtain a Reference to the class Tcl instance}\label{sec:instance}A single instance of the class is declared in \Tclf{Tcl.cc}as a static member variable;the programmer must obtain a reference to this instanceto access other methods described in this section.The statement required to access this instance is:\begin{program}        Tcl& tcl = Tcl::instance();\end{program}\subsection{Invoking OTcl Procedures}\label{sec:Invoke}There are four different methods to invoke an OTcl commandthrough the instance, \code{tcl}.They differ essentially in their calling arguments.Each function passes a string to the interpreter,that then evaluates the string in a global context.These methods will return to the caller if the interpreter returns TCL\_OK.On the other hand, if the interpreter returns TCL\_ERROR,the methods will call \proc{tkerror}.The user can overload this procedure to selectively disregardcertain types of errors.Such intricacies of OTcl programming are outside thescope of this document.\href{The next section}{Section}{sec:Result}describes methods to access the result returned by the interpreter.\begin{itemize}\itemsep0pt\item \fcnref{\fcn[char* $s$]{tcl.eval}}{../Tcl/Tcl.cc}{Tcl::eval}  invokes \fcn[]{Tcl\_GlobalEval} to execute $s$ through the interpreter.\item \fcnref{\fcn[const char* $s$]{tcl.evalc}}{../Tcl/Tcl.cc}{Tcl::evalc}  preserves the argument string $s$.  It copies the string $s$ into its internal buffer;  it then invokes the previous \fcn[char* $s$]{eval} on the internal buffer.\item \fcnref{\fcn[]{tcl.eval}}{../Tcl/Tcl.cc}{Tcl::eval}  assumes that the command is already stored in the class' internal  \code{bp_}; it directly invokes \fcn[char* bp\_]{tcl.eval}.  A handle to the buffer itself is available through the method  \fcnref{\fcn{tcl.buffer}}{../Tcl/Tcl.h}{Tcl::buffer}.\item  \fcnref{\fcn[const char* $s$, \ldots]{tcl.evalf}}{../Tcl/Tcl2.cc}{Tcl::evalf}  is a \code{Printf}(3) like equivalent.  It uses \code{vsprintf}(3) internally to create the input string.\end{itemize}As an example, here are some of the ways of using the above methods:\begin{program}        Tcl& tcl = {\bfseries{}Tcl::instance}();        char wrk[128];        strcpy(wrk, "Simulator set NumberInterfaces_ 1");        {\bfseries{}tcl.eval}(wrk);        sprintf({\bfseries{}tcl.buffer}(), "Agent/SRM set requestFunction_ %s", "Fixed");        {\bfseries{}tcl.eval}();        {\bfseries{}tcl.evalc}("puts stdout {hello world}");        {\bfseries{}tcl.evalf}("%s request %d %d", name_, sender, msgid);\end{program}\subsection{Passing Results to/fro the Interpreter}\label{sec:Result}When the interpreter invokes a C++ method,it expects the result back in the private member variable,\code{tcl_->result}.Two methods are available to set this variable.\begin{list}{\textbullet}{}\item \fcnref{\fcn[const char* $s$]{tcl.result}}{../Tcl/Tcl.h}{Tcl::result}        Pass the result string $s$ back to the interpreter.\item  \fcnref{\fcn[const char* fmt, \ldots]{tcl.resultf}}{../Tcl/Tcl2.cc}{Tcl::resultf}        \code{varargs}(3) variant of above        to format the result using \code{vsprintf}(3),        pass the result string back to the interpreter.\end{list}\begin{program}        if (strcmp(argv[1], "now") == 0) \{                {\bfseries{}tcl.resultf}("%.17g", clock());                return TCL_OK;        \}        {\bfseries{}tcl.result}("Invalid operation specified");        return TCL_ERROR;\end{program}Likewise, when a C++ method invokes an OTcl command,the interpreter returns the result in \code{tcl_->result}.\begin{list}{\textbullet}{}\item \fcnref{\fcn{tcl.result}}{../Tcl/Tcl.h}{Tcl::result}      must be used to retrieve the result.      Note that the result is a string, that must be converted      into an internal format appropriate to the type of result.\end{list}\begin{program}        tcl.evalc("Simulator set NumberInterfaces_");        char* ni = {\bfseries{}tcl.result}();        if (atoi(ni) != 1)                tcl.evalc("Simulator set NumberInterfaces_ 1");\end{program}        \subsection{Error Reporting and Exit}\label{sec:ErrorReporting}This method provides a uniform way to report errors in the compiled code.\begin{list}{\textbullet}{}\item \fcnref{\fcn[const char* $s$]{tcl.error}}{../Tcl/Tcl.cc}{Tcl::error}performs the following functions:write $s$ to stdout; write \code{tcl_->result} to stdout;exit with error code 1.\end{list}\begin{program}        {\bfseries{}tcl.resultf}("cmd = %s", cmd);        {\bfseries{}tcl.error}("invalid command specified");        /*{\cf{}NOTREACHED}*/\end{program}Note thatthere are minor differences between returning TCL\_ERROR\href{as we did in the previous subsection}{Section}{sec:Result},and calling \fcn[]{Tcl::error}.The former generates an exception within the interpreter;the user can trap the exception and possibly recover from the error.If the user has not specified any traps, the interpreter will print a stack trace and exit.However, if the code invokes \fcn[]{error},then the simulation user cannot trap the error;in addition, \ns\ will not print any stack trace.\subsection{Hash Functions within the Interpreter}\label{sec:HashTables}\ns\ stores a reference to every TclObject in the compiled hierarchyin a hash table;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -