今天主要看的是上层的代码逻辑,不深究具体的变量赋值。initFlash()函数:
主函数main里面的initFlash()函数里面根据全局变量ftl_type的类型选择了FTL类型操作读写函数flt_op指针。Ftl_type是在一开始的ssd_interface.h头文件定义,但是在ssd_interface.c中直接可以修改值,选择要仿真的FTL算法。initFlash()函数里面调用的nand_init()是对底层的flash块初始化,nand_stat_reset()函数只是对flash块操作记录的重置,并不是对flash块的内容作修改。若对nand的操作进一步深究,则是阅读flash.c和flash.h文件的内容。warmFlash()函数:
是一个预热函数,因为我们做实验的时候希望试验环境能模拟最真实的情况,以我们并不想每次在做实验的时候,trace 数据都是跑在一个全新的 SSD 上面。这个时候我们可以在真实实验之前给 SSD 做一次 warm up,也就是用一些 trace 先让 SSD 跑一会,然后再运行我们需要测试的 trace 文件。单纯做仿真不需要深究,只是需要知道其接口输入的参数是预热trace文件名。
下面开始的是disksim_run_simulation()函数,也就是总体仿真的函数。Disksim_run_simulation函数在Disksim.c函数中定义,输入参数无,返回类型void
该函数判断disksim结构体中的stop_sim来反复执行调用disksim_simulate_event()函数,这里给出截取代码段:
1 | void disksim_run_simulation () |
下面进入disksim_simulate_event()函数,这个函数输入参数是int类型的event_count,该函数,该函数也在disksim.c中定义。对这个函数咱一步步阅读,先给出这个函数的完整代码:
1 | void disksim_simulate_event (int num) |
首先函数先定义了一个event结构体指针curr:event是个结构体类型,在disksim_global.h的头文件中定义如下:
1 | typedef struct ev { |
熟悉双链表的话,可以用这个结构体作为双链表的节点,里面有前驱和后继指针。再读下disksim_simulate_event()下面的代码:
1 | if ((curr = getnextevent()) == NULL) { |
看到了curr = getnextevent()这个调用,getnextevent()这个函数也在disksim.c中定义了。暂不深究。看看disksim_simstop ()这个函数,在disksim.c中也定义了:1
2
3
4void disksim_simstop ()
{
disksim->stop_sim = TRUE;
}
其作用也就是将disksim这个结构体变量中的stop_sim置位TRUE,在上层调用函数disksim_run_simulation ()中的while循环就是依据这个stop_sim判断终止的,也就是说getnextevent()返回空,即当前队列没有event了,仿真停止了。如果不为空,则判断disksim结构体变量中的trace_mode判断trace类型,但是不做操作,该类型有:enum { DISKSIM_MASTER, DISKSIM_SLAVE, DISKSIM_NONE } trace_mode;这是在disksim结构体类型申明里面找到的。三种类型,具体的类型对应什么意思,目前不知道。
下面继续看disksim_simulate_event()下一句代码:
1 | simtime = curr->time; |
simtime是disksim结构变量中的一个double类型的值,表示当前的系统时间。反过来看event的结构定义可以看到也有double time的定义,就是将当前处理的event类型所绑定的时间赋值给系统时间。
再接着读下去,发现是根据当前event中的int type;来处理事件
Type有以下几种类型:
|Type类型|对应调用的函数|
|:-:|:-:|
|INTR_EVENT|intr_acknowledge()|
|IO_MIN_EVENT|io_internal_event()|
|IO_MAX_EVENT|io_internal_event()|
|PF_MIN_EVENT|pf_internal_event()|
|PF_MAX_EVENT|pf_internal_event()|
|TIMER_EXPIRED|(*timeout->func) (timeout)|
|MEMS_MIN_EVENT|io_internal_event ((ioreq_event *)curr)|
|MEMS_MAX_EVENT|io_internal_event ((ioreq_event *)curr);|
|CHECKPOINT|disksim_register_checkpoint(simtime + disksim->checkpoint_interval)|
|CHECKPOINT|disksim_checkpoint (disksim->checkpointfilename);|
|STOP_SIM|disksim_simstop ();|
|EXIT_DISKSIM|exit (0);|
关于具体类型说明,明天再分析。