作者 白丁
前面介绍了 syssim_driver 接口。作者留给我们的只是使用该接口的一个小例子。样例中,每次发送请求都是等上一个请求全部完成了才发送下一个请求。而在实际情况中我们更多的是希望请求是按照时间点来发送的。还有一点就是要将原程序中随机生成的 trace 数据改成我们自定义的数据,可以改成从文件中去读取trace 。
原来程序的调用方式是 syssim <parameters file> <output file> <max. block number> ,max. block number表示的是最大的 blkno 主要是在随机生成 trace 时用到,这里我们用不上这个参数,直接把这个参数换成我们的 trace 文件就好了。然后采用这样的方式调用该程序:syssim <parameters file> <output file> <trace file>。这里的trace文件格式是disksim中定义的ascii格式。修改过后的main函数如下:
int
main(int argc, char *argv[])
{
struct
stat
buf;
struct
disksim_interface *disksim;
if (argc != 4 ) {
fprintf(stderr, “usage: %s <param file> <output file> <tracefile>\n”,argv[0]);
exit(1);
}
if (stat(argv[1], &buf) < 0)
panic(argv[1]);
disksim = disksim_interface_initialize(argv[1], argv[2],
syssim_report_completion,
syssim_schedule_callback,
syssim_deschedule_callback,0,0,0);
FILE *tracefile = fopen(argv[3], “r”);
double time;
int devno;
unsigned
long logical_block_number;
int size;
int isread;
double senttime=0.0;
char line[201];
fgets(line,200,tracefile);
while(!feof(tracefile)) {
if(sscanf(line, “%lf %d %ld %d %d”, &time, &devno, &logical_block_number,&size, &isread)!=5){
fprintf(stderr, “Wrong number of arguments for I/O trace event type\n”);
fprintf(stderr, “line: %s”, line);
}
struct
disksim_request *r = malloc(sizeof(struct
disksim_request));
r->start = time;
r->flags = isread;
r->devno = devno;
r->blkno = logical_block_number;
r->bytecount = size * 512;
disksim_interface_request_arrive(disksim, time, r);
fgets(line,200,tracefile);
}
fclose(tracefile);
while(next_event >= 0) {
now = next_event;
next_event = -1;
disksim_interface_internal_event(disksim, now, 0);
}
disksim_interface_shutdown(disksim, now);
print_statistics(&st, “response time”);
exit(0);
}
在syssim_driver.c中有一个 syssim_report_completion()函数,这是一个请求完成时的回调函数,在main函数中给每个请求malloc的内存可以在这里释放,所以可以在这个函数的最后添加free(r)语句来释放内存。
全局变量st有三个字段,分别是n, sum, sqr。st->n表示请求的总数,st->sum表示所有请求的响应时间的总和, st->sqr表示所有请求响应时间的平方和。st->sum/st->n为所有请求的平均响应时间(ms),用来衡量整体的平均响应时间。用sqrt((s->sqr – 2*avg*s->sum + s->n*avg*avg) / s->n)来衡量所有请求的响应时间的离散程度。一个请求完成时,在该请求的回调函数中调用add_statistics()函数来更新统计信息,最后当程序结束时,调用print_statistics()函数,打印输出统计信息。