OPNET学习笔记之gna_ftp_mgr进程模型
首先注意bgsim intrpt属性为disable,估计本进程会由gna_profile_mgr 进程调用并提供初始化参数。
状态变量注意:GnaT_Cli_Ftp_Params_Info* ftp_client_info_ptr;和GnaT_Nam_Appl* application_info_ptr;是由profile提供的参数。
//---------------------------------------------------------------------------------------------------------------------------INIT入口代码
/** This state initialize variables. **/
/* Create a handle for tracking dynamically allocated objects */
cmo_handle = prg_cmo_define ("gna_ftp_mgr dynamic memory"); //注意动态分配的对象(这里不是内存???)
/* Acquire the application information from the argument memory. 从父进程的参数内存得到进程初始化参数*/
if ((application_info_ptr = (GnaT_Nam_Appl *)op_pro_argmem_access ()) == OPC_NIL)
{
/* Stop the simulation if the application information can not be accessed. */
ftp_mgr_error ("Unable to get the application information from the parent profile manager process", OPC_NIL, OPC_NIL);
}
/* Schedule the first entry or query for the database application. */
/* A request/query should be sent as soon as the application */
/* manager is spawned since it marks the start of the application. */
op_intrpt_schedule_self (op_sim_time (), GNAC_FTP_CLIENT_SPAWN); //马上调用一个自中断,使下一步马上进入get/put状态
/* Schedule the end of the application.该进程仿真结束,时间 = 进程仿真持续时间 + 当前时间 */
end_of_application = application_info_ptr->application_duration + op_sim_time ();
ending_event_handle = op_intrpt_schedule_self (end_of_application, GNAC_FTP_MGR_KILL); //调用另一个自中断,当到达进程结束时间时中断
/* Create a structure in charge of sending all information to the FTP client. This structure will tell whether the client */
/* should generate a request or an entry, its size ... 分配内存,用于存储FTP client端的信息*/
ftp_client_info_ptr = (GnaT_Cli_Ftp_Params_Info*) prg_cmo_alloc (cmo_handle, sizeof (GnaT_Cli_Ftp_Params_Info));
/* Get traffic scaling factor. 应在profile中已经定义好的信息*/
temp_app_desc = (GnaT_Ftp_Desc *) application_info_ptr->application_comp_ptr->application_ptr->application_desc_ptr;
inter_request_time_dist_handle = oms_dist_scaled_load_from_string (temp_app_desc->inter_request_time_dist_name_ptr, 1 / application_info_ptr->scaling_factor);
/* Set type of service in structure passed to FTP client. */
ftp_client_info_ptr->tos = temp_app_desc->tos;
/* Pass to client global information structure. */
ftp_client_info_ptr->app_info_ptr = application_info_ptr;
/* Set the apptracking info from the PTC memory */
ftp_client_info_ptr->apptrack_profile_info_ptr = (ApptrackT_Profile_Info*) op_pro_parmem_access ();
//只是收集相关信息,然后进入IDLE,没有用到动态子进程。
//---------------------------------------------------------------------------------------------------------------------------
由于init状态是强制状态,且其中定义了自中断(开始/结束进程),故从本状态会马上跳到get/put状态
//---------------------------------------------------------------------------------------------------------------------------get/put状态
/** Spawns a client process for a "get" or a "put" to the FTP server. A client is spawned for **/
/** each potential TCP connection. 该状态调用子进程处理**/
/* Spawns a FTP child process. */
ftp_cli_phandle = op_pro_create ("gna_ftp_cli", OPC_NIL); //创建,还没有调用,
/* Get the FTP description. FTP描述 */
temp_app_desc = (GnaT_Ftp_Desc *) application_info_ptr->application_comp_ptr->application_ptr->application_desc_ptr;
/* Get a random number to choose whether the request will be a "get" or a "put". */
random_number = op_dist_uniform (1.0);
/* Set the corresponding request. */
if (random_number >= temp_app_desc->command_mix)
{
/* The request is a "put". */
if (trace_active || trace_arch_active)
{
op_prg_odb_print_major ("FTP Manager spawning a FTP (\"gna_ftp_cli\") process for PUT command", OPC_NIL);
}
ftp_client_info_ptr->request_type = GnaC_App_Type_Ftp_Put;
}
else
{
/* The request is a "get". */
if (trace_active || trace_arch_active)
{
op_prg_odb_print_major ("FTP Manager spawning a FTP (\"gna_ftp_cli\") process for GET command", OPC_NIL);
}
ftp_client_info_ptr->request_type = GnaC_App_Type_Ftp_Get;
}
/* Set packet size */
ftp_client_info_ptr->request_size = ceil (tpal_dist_positive_outcome(temp_app_desc->file_size_dist_handle,
application_info_ptr->application_comp_ptr->application_ptr->application_name_ptr, "File size" ));
/* Select a server among the list of servers corresponding to the symbolic server name. 注意这里选择server,通过symbolic name*/
ftp_client_info_ptr->server_name = app_server_name_select (application_info_ptr);
/* Invoke FTP client. 这时FTP client应进入open状态*/
op_pro_invoke (ftp_cli_phandle, ftp_client_info_ptr);
/* Compute the next time a request will be made. */
scheduled_time = op_sim_time () + tpal_dist_positive_outcome (inter_request_time_dist_handle,
application_info_ptr->application_comp_ptr->application_ptr->application_name_ptr, "Inter-request time");
/* Schedule next request unless application is over. */
if (scheduled_time <= end_of_application)
{
op_intrpt_schedule_self (scheduled_time, GNAC_FTP_CLIENT_SPAWN); //等间隔时间过后,再发出FTP 请求
/* Check whether this interrupt is scheduled at the same time as the ending interrupt. */
if (end_of_application == scheduled_time)
{
/* Cancel ending interrupt that is lower in interrupt stack. Schedule an interrupt to end the application when over. */
/* Keep the handle of the interrupt in charge of destroying the process. Some applications may close at the same time. */
/* The interrupt can be then cancelled and scheduled again so this ending interrupt occurs last. */
op_ev_cancel (ending_event_handle);
ending_event_handle = op_intrpt_schedule_self (end_of_application, GNAC_FTP_MGR_KILL);
}
}
//---------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------