opnet之simple source进程模型

来源:互联网 发布:牙周医生 知乎 编辑:程序博客网 时间:2024/05/29 10:11

用自己的话解释一遍

总结了一下simple source模型。
功能:根据我们设置的属性值发包。
简化的叙述一下流程:

  • 在init状态的入口处设置了一个自中断,出口处获取中断码
  • 准备转移到generate状态,执行转移函数,发包
  • 执行generate入口代码,产生了一个自中断,出口处获取中断码
  • 转移到自身,执行转移函数,发包
  • 下一个循环

1.状态转移图

2.Module Attribute

3.Local Statistics

4.SV

5.TV

/* Variables used in the "init" state.      */char        interarrival_str [128];char        size_str [128];Prg_List*   pk_format_names_lptr;char*       found_format_str;Boolean     format_found;int         i;/* Variables used in state transitions.     */int         intrpt_code;

6.HB

/* Include files.                   */#include    <oms_dist_support.h> //该进程模型使用了外部的头文件,用以产生概率分布/* Special attribute values.        */#define     SSC_INFINITE_TIME       -1.0 //定义无穷大时间为-1。很奇怪的定义。/* Interrupt code values.           */#define     SSC_START               0 //自定义的中断码,开始为0#define     SSC_GENERATE            1 //自定义的中断码,发包为1#define     SSC_STOP                2 //自定义的中断码,停止为2/* Node configuration constants.    */#define     SSC_STRM_TO_LOW         0 //发包的流索引,只有一个流索引,默认为0/* Macro definitions for state transitions. */#define     START       (intrpt_code == SSC_START) //中断码为SSC_START时,满足转移条件#define     DISABLED    (intrpt_code == SSC_STOP)  //中断码为SSC_STOP时,满足转移条件#define     STOP        (intrpt_code == SSC_STOP)    //中断码为SSC_STOP时,满足转移条件#define PACKET_GENERATE (intrpt_code == SSC_GENERATE)//中断码为SSC_GENERATE时,满足转移条件/* Function prototypes.             */static void         ss_packet_generate (void); //FB中的包也需要在这里声明一下?

7.INIT的入口代码

综述:初始化的入口代码,顾名思义是做一些初始化的工作。

  • 读取设置的属性
  • 设置自中断
  • 注册统计量
/* At this initial state, we read the values of source attributes   *//* and schedule a selt interrupt that will indicate our start time  *//* for packet generation.                                           *//* Obtain the object id of the surrounding module.                  */own_id = op_id_self (); //这个进程属于一个process,取得这个process的对象ID/* Read the values of the packet generation parameters, i.e. the    *//* attribute values of the surrounding module.                      *///核心函数op_ima_obj_attr_get()通过对象ID读取我们设置的5个Module Attribute的值//特别注意的是interarrival_str和size_str是临时变量//format_str、&start_time、&stop_time是状态变量,为什么?op_ima_obj_attr_get (own_id, "Packet Interarrival Time", interarrival_str);op_ima_obj_attr_get (own_id, "Packet Size",              size_str);op_ima_obj_attr_get (own_id, "Packet Format",            format_str);op_ima_obj_attr_get (own_id, "Start Time",               &start_time);op_ima_obj_attr_get (own_id, "Stop Time",                &stop_time);/* Load the PDFs that will be used in computing the packet          *//* interarrival times and packet sizes.                             *///通过头文件里的函数oms_dist_load_from_string()获得分布函数的句柄//注意两个句柄都是state variable,类型为Omst_dist_handle//这两个句柄还不是具体的分布的数值interarrival_dist_ptr = oms_dist_load_from_string (interarrival_str);pksize_dist_ptr       = oms_dist_load_from_string (size_str);/* Verify the existence of the packet format to be used for generated packets.      *///包格式的相关设置if (strcmp (format_str, "NONE") == 0)    {    /* We will generate unformatted packets. Set the flag.          */    generate_unformatted = OPC_TRUE;    }else    {    /* We will generate formatted packets. Turn off the flag.       */    generate_unformatted = OPC_FALSE;    /* Get the list of all available packet formats.                */    pk_format_names_lptr = prg_tfile_name_list_get (PrgC_Tfile_Type_Packet_Format);    /* Search the list for the requested packet format.             */    format_found = OPC_FALSE;    for (i = prg_list_size (pk_format_names_lptr); ((format_found == OPC_FALSE) && (i > 0)); i--)        {        /* Access the next format name and compare with requested   */        /* format name.                                             */        found_format_str = (char *) prg_list_access (pk_format_names_lptr, i - 1);         if (strcmp (found_format_str, format_str) == 0)            format_found = OPC_TRUE;        }    if (format_found == OPC_FALSE)        {        /* The requested format does not exist. Generate            */        /* unformatted packets.                                     */        generate_unformatted = OPC_TRUE;        /* Display an appropriate warning.                          */        op_prg_odb_print_major ("Warning from simple packet generator model (simple_source):",                                 "The specified packet format", format_str,                                "is not found. Generating unformatted packets instead.", OPC_NIL);        }    /* Destroy the lits and its elements since we don't need it     */    /* anymore.                                                     */    prg_list_free (pk_format_names_lptr);    prg_mem_free  (pk_format_names_lptr);    }   /* Make sure we have valid start and stop times, i.e. stop time is  *//* not earlier than start time.                                     *///我们设置的开始时间和结束时间不一定合法,比如结束时间比开始时间还早,需要做一些判断if ((stop_time <= start_time) && (stop_time != SSC_INFINITE_TIME))//上面这一行有一个很特别的地方,我们设置的stop_time是infinity,这里竟然把infinity和-1相比,?//说明对于opnet来说,就是用infinity表示的-1    {    /* Stop time is earlier than start time. Disable the source.    */    start_time = SSC_INFINITE_TIME;  //开始时间设为-1    /* Display an appropriate warning.                              */    //显示合适的警告信息    op_prg_odb_print_major ("Warning from simple packet generator model (simple_source):",                             "Although the generator is not disabled (start time is set to a finite value),",                            "a stop time that is not later than the start time is specified.",                            "Disabling the generator.", OPC_NIL);    }/* Schedule a self interrupt that will indicate our start time for  *//* packet generation activities. If the source is disabled,         *//* schedule it at current time with the appropriate code value.     */if (start_time == SSC_INFINITE_TIME) //开始时间为-1时马上产生SSC_STOP自中断    {    op_intrpt_schedule_self (op_sim_time (), SSC_STOP);    }else                                 //开始时间设置合理时,在开始的时间产生SSC_START自中断    {    op_intrpt_schedule_self (start_time, SSC_START);    /* In this case, also schedule the interrupt when we will stop  */    /* generating packets, unless we are configured to run until    */    /* the end of the simulation.                                   */    if (stop_time != SSC_INFINITE_TIME)//开始时间不为-1时,在结束时产生SSC_STOP自中断        {        op_intrpt_schedule_self (stop_time, SSC_STOP);        }/*      至此,我们可以总结一下,初始化的过程中已过考虑了四种情况:    1.结束时间小于开始时间且结束时间不为-1,永远不发包,显示警告信息,然后马上产生SSC_STOP自中断    2.结束时间不为-1,意味着在仿真期间会提前结束发包,在发包结束时产生SSC_STOP自中断    3.正常的设置了时间,在开始时间也即10s时,产生SSC_START自中断。*/      //通过分布函数句柄产生的下一个包的时间间隔,间隔是state variable。有啥用???    next_intarr_time = oms_dist_outcome (interarrival_dist_ptr);    /* Make sure that interarrival time is not negative. In that case it */    /* will be set to 0.                                                 */    if (next_intarr_time <0)        {        next_intarr_time = 0.0;        }    }//注册统计量/* Register the statistics that will be maintained by this model.   */bits_sent_hndl      = op_stat_reg ("Generator.Traffic Sent (bits/sec)",         OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL);packets_sent_hndl   = op_stat_reg ("Generator.Traffic Sent (packets/sec)",      OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL);packet_size_hndl    = op_stat_reg ("Generator.Packet Size (bits)",              OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL);interarrivals_hndl  = op_stat_reg ("Generator.Packet Interarrival Time (secs)", OPC_STAT_INDEX_NONE, OPC_STAT_LOCAL);

8.INIT的出口代码
一句话总结初始状态就是设置了一个自中断。初始状态是非强制状态,初始状态的入口程序执行完后,控制权回到仿真核心手里,仿真核心将下一个时间推到时间列表的开头,触发了10s处的自中断程序。仿真核心将控制权交到进程手里,初始进程先执行出口处的代码。

/* Determine the code of the interrupt, which is used in evaluating *//* state transition conditions.                                     */intrpt_code = op_intrpt_code (); //得到当前的中断码,可能是SSC_STOP也可能是SSC_START

9.FB
如果START条件满足,执行ss_packet_generate (void)

  • 通过分布句柄得到包的大小
  • 通过包格式的设定,产生有无格式的包
  • 写入统计量
  • 发包
static void ss_packet_generate (void)    {    Packet*             pkptr;    double              pksize;    /** This function creates a packet based on the packet generation       **/    /** specifications of the source model and sends it to the lower layer. **/    FIN (ss_packet_generate ());    /* Generate a packet size outcome.                  */    pksize = (double) ceil (oms_dist_outcome (pksize_dist_ptr));//产生包的大小,向上舍入    /* Create a packet of specified format and size.    */    if (generate_unformatted == OPC_TRUE)        {        /* We produce unformatted packets. Create one.  */        pkptr = op_pk_create (pksize); //使用op_pk_creat()函数产生无格式包        }    else        {        /* Create a packet with the specified format.   */        pkptr = op_pk_create_fmt (format_str); //使用op_pk_creat_fmt()函数产生有格式包        op_pk_total_size_set (pkptr, pksize);        }    /* Update the packet generation statistics.         */    //写入统计数据    op_stat_write (packets_sent_hndl, 1.0);    op_stat_write (packets_sent_hndl, 0.0);    op_stat_write (bits_sent_hndl, (double) pksize);    op_stat_write (bits_sent_hndl, 0.0);    op_stat_write (packet_size_hndl, (double) pksize);    op_stat_write (interarrivals_hndl, next_intarr_time);    /* Send the packet via the stream to the lower layer.   */    op_pk_send (pkptr, SSC_STRM_TO_LOW); //发包    FOUT;    }   

10.generate状态的入口代码
一个功能:产生下一个中断。
貌似入口处的核心功能就是产生中断。

/* At the enter execs of the "generate" state we schedule the       *//* arrival of the next packet.                                      *///通过分布函数句柄得到下一个包的产生时间间隔next_intarr_time = oms_dist_outcome (interarrival_dist_ptr);/* Make sure that interarrival time is not negative. In that case it *//* will be set to 0.                                                 */if (next_intarr_time <0)    {    next_intarr_time = 0;    }//在当前时间+间隔时间后,产生自中断,中断号为SSC_GENERATE,注意返回值为Evhandle类型next_pk_evh      = op_intrpt_schedule_self (op_sim_time () + next_intarr_time, SSC_GENERATE);

11.generate状态的出口代码
执行完入口代码后,分析同上,中断发生时,执行generate状态的出口代码:

/* Determine the code of the interrupt, which is used in evaluating *//* state transition conditions.                                     */intrpt_code = op_intrpt_code (); //获取中断号

12.stop状态的入口代码
因为init状态和generate状态都容易产生SSC_STOP中断,需要处理。

/* When we enter into the "stop" state, it is the time for us to    *//* stop generating traffic. We simply cancel the generation of the  *//* next packet and go into a silent mode by not scheduling anything *//* else.                                                            */if (op_ev_valid (next_pk_evh) == OPC_TRUE)    {    op_ev_cancel (next_pk_evh); //如果下一个事件仍然有效,就取消该事件,使用事件句柄    }

tags:opnet

0 0
原创粉丝点击