flashsim源码阅读-1

今天主要看的是上层的代码逻辑,不深究具体的变量赋值。
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.cflash.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
2
3
4
5
6
7
8
void disksim_run_simulation ()
{
int event_count = 0;
while (disksim->stop_sim == FALSE) {
disksim_simulate_event(event_count);
event_count++;
}
}

下面进入disksim_simulate_event()函数,这个函数输入参数是int类型的event_count,该函数,该函数也在disksim.c中定义。对这个函数咱一步步阅读,先给出这个函数的完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
void disksim_simulate_event (int num)
{
event *curr;

if ((curr = getnextevent()) == NULL) {
disksim_simstop ();
}
else {

switch(disksim->trace_mode) {
case DISKSIM_NONE:
case DISKSIM_MASTER:
// fprintf(outputfile, "*** DEBUG TRACE\t%f\t%d\t%d\n",
// simtime, curr->type, num);
// fflush(outputfile);
break;

case DISKSIM_SLAVE:
break;
}

simtime = curr->time;

if (curr->type == INTR_EVENT) {
intr_acknowledge (curr);
}
else if ((curr->type >= IO_MIN_EVENT) && (curr->type <= IO_MAX_EVENT)) {
io_internal_event ((ioreq_event *)curr);
}
else if ((curr->type >= PF_MIN_EVENT) && (curr->type <= PF_MAX_EVENT)) {
pf_internal_event(curr);
}
else if (curr->type == TIMER_EXPIRED) {
timer_event *timeout = (timer_event *) curr;
(*timeout->func) (timeout);
}
else if ((curr->type >= MEMS_MIN_EVENT)
&& (curr->type <= MEMS_MAX_EVENT)) {
io_internal_event ((ioreq_event *)curr);
}
else if (curr->type == CHECKPOINT) {
if (disksim->checkpoint_interval) {
disksim_register_checkpoint(simtime + disksim->checkpoint_interval);
}
disksim_checkpoint (disksim->checkpointfilename);
}
else if (curr->type == STOP_SIM) {
disksim_simstop ();
}
else if (curr->type == EXIT_DISKSIM) {
exit (0);
}
else {
fprintf(stderr, "Unrecognized event in simulate: %d\n", curr->type);
exit(1);
}


#ifdef FDEBUG
fprintf (outputfile, "Event handled, going for next\n");
fflush (outputfile);
#endif
}
}

首先函数先定义了一个event结构体指针curr:
event是个结构体类型,在disksim_global.h的头文件中定义如下:

1
2
3
4
5
6
7
8
typedef struct ev {
double time;
int type;
struct ev *next;
struct ev *prev;
int temp;
char space[DISKSIM_EVENT_SPACESIZE];
} event;

熟悉双链表的话,可以用这个结构体作为双链表的节点,里面有前驱和后继指针。再读下disksim_simulate_event()下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
 if ((curr = getnextevent()) == NULL) {
disksim_simstop ();
}
else {
switch(disksim->trace_mode) {
case DISKSIM_NONE:
case DISKSIM_MASTER:
break;

case DISKSIM_SLAVE:
break;
}

看到了curr = getnextevent()这个调用,getnextevent()这个函数也在disksim.c中定义了。暂不深究。看看disksim_simstop ()这个函数,在disksim.c中也定义了:

1
2
3
4
void 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;

simtimedisksim结构变量中的一个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);|
关于具体类型说明,明天再分析。

热评文章