struct ssd_info simulate(struct ssd_info ssd):
simulate()是核心处理函数,主要实现的功能包括
1,从trace文件中获取一条请求,挂到ssd->request
2,根据ssd是否有dram分别处理读出来的请求,把这些请求处理成为读写子请求,挂到ssd->channel或者ssd上
3,按照事件的先后来处理这些读写子请求。
4,输出每条请求的子请求都处理完后的相关信息到outputfile文件中
这个函数是模拟整个ssd的函数,重中之重,首先打开tracefile文件,不能打开则输出错误信息,接着进入循环处理结构,flag不等于100则进入循环,进入循环首先执行get_request()函数返回一个flag值,flag等于1的话则进入判断语句,如果挂载内存容量没满的话进行缓存管理buffer_management()和分发函数distribute(),如果缓存满了的话则不如挂载内存(挂载内存就是缓存也就是SDRAM)而执行不缓存分发函数从而退出该判断语句,接着进行请求处理函数process()函数,执行完请求处理函数后则执行结果输出函数trace_output()将此条请求处理结果输出到输出到输出结果文件outputfile中,判断flag等于0并且请求队列为空的话说明所有请求处理完成则令flag等于100从而退出请求处理的循环。最后关闭tracefile文件并返回ssd,此simulate()函数结束。
struct ssd_info *simulate(struct ssd_info *ssd)
{
int flag=1;
printf("begin simulating......\n ^o^ OK, please wait a moment, and enjoy music and coffee ^o^ \n");
ssd->tracefile = fopen(ssd->tracefilename,"r");
if(ssd->tracefile == NULL){
printf("the trace file can't open\n");
return NULL;
}
fprintf(ssd->outputfile," arrive lsn size ope begin time response time process time\n");
fflush(ssd->outputfile); //将输出缓冲区内容刷进磁盘
while(flag!=100){
flag=get_requests(ssd); /*给request开辟了内存空间,但是并没有给sub_request开辟空间,因为还没到给request分发子请求的时候。
*返回1表示一条请求已经计算好时间相关的和操作长度相关的一些信息接着该处理这条IO在ssd上的实际操作,返回100表示获取请求失败。*/
if(flag == 1){ //表示已经有一条I/O请求挂载到了ssd->request_queue上了,接着对这条请求进行缓存处理
if (ssd->parameter->dram_capacity!=0){
buffer_management(ssd);//printf("No.%d behind buffer_management\n",debug_count++);
distribute(ssd); //读请求分配子请求函数,这里只处理读请求,写请求已经在buffer_management()函数中处理了根据请求队列和buffer命中的检查,将每个请求分解成子请求,将子请求队列挂在channel上,不同的channel有自己的子请求队列。
//printf("NO.%d behind distribute\n",debug_count++);
}else
no_buffer_distribute(ssd);//printf("No.%d behind buffer_management\n",debug_count);
}
process(ssd);//printf("No.%d behind process \n",debug_count);
trace_output(ssd);//printf("No.%d behind trace_output \n",debug_count);
if(flag == 0 && ssd->request_queue == NULL) //表示已经扫描到了trace文件尾部了,所有I/O请求挂载完成,并且ssd->request_queue请求队列也全部处理完成,则结束循环
flag = 100;
}
fclose(ssd->tracefile);
return ssd;
}