mems_disksim.c
来自「disksim是一个非常优秀的磁盘仿真工具」· C语言 代码 · 共 1,418 行 · 第 1/3 页
C
1,418 行
/* * DiskSim Storage Subsystem Simulation Environment (Version 4.0) * Revision Authors: John Bucy, Greg Ganger * Contributors: John Griffin, Jiri Schindler, Steve Schlosser * * Copyright (c) of Carnegie Mellon University, 2001-2008. * * This software is being provided by the copyright holders under the * following license. By obtaining, using and/or copying this software, * you agree that you have read, understood, and will comply with the * following terms and conditions: * * Permission to reproduce, use, and prepare derivative works of this * software is granted provided the copyright and "No Warranty" statements * are included with all reproductions and derivative works and associated * documentation. This software may also be redistributed without charge * provided that the copyright and "No Warranty" statements are included * in all redistributions. * * NO WARRANTY. THIS SOFTWARE IS FURNISHED ON AN "AS IS" BASIS. * CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER * EXPRESSED OR IMPLIED AS TO THE MATTER INCLUDING, BUT NOT LIMITED * TO: WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY * OF RESULTS OR RESULTS OBTAINED FROM USE OF THIS SOFTWARE. CARNEGIE * MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT * TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT. * COPYRIGHT HOLDERS WILL BEAR NO LIABILITY FOR ANY USE OF THIS SOFTWARE * OR DOCUMENTATION. * *//* mems_disksim.c * * Functions integrating the memsdevice simulator with disksim. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "mems_global.h"#include "mems_internals.h"#include "mems_mapping.h"#include "disksim_ioqueue.h" /* Provides ioqueue_cleanstats() */#include "disksim_bus.h" /* Provides bus_get_transfer_time() */#include "config.h"#include "modules/modules.h"/* read-only global vars used during mems_statinit */static char *statdesc_request_energy_uj = "Per-request energy (uJ)";static char *statdesc_seek_time = "Seek time";static char *statdesc_x_seek_time = "X Seek time";static char *statdesc_y_seek_time = "Y Seek time";static char *statdesc_turnaround_time = "Initial turnaround time";static char *statdesc_turnaround_number = "Initial turnaround number";static char *statdesc_stream_turnaround_time = "Streaming turnaround time";static char *statdesc_stream_turnaround_number = "Streaming turnaround number";static char *statdesc_subtrack_accesses = "Subtrack accesses";static char *statdesc_tips_per_access = "Average tips per access";static char *statdesc_inactive_time = "Inactive time";static char *statdesc_prefetched_blocks = "Prefetched blocks";struct device_header mems_hdr_initializer;/************************************************************************ * Functions related to mapping physical organization ************************************************************************//* Return the inbus number for the device */intmems_get_busno (ioreq_event *curr){ mems_t *dev = getmems(curr->devno); intchar busno; int depth; busno.value = curr->busno; depth = dev->depth[0]; /* Only one bus connection allowed */ return busno.byte[depth];}/* How far down the bus hierarchy is this device? */intmems_get_depth (int devno){ mems_t *dev = getmems(devno); return dev->depth[0]; /* Only one bus connection allowed */}/* Which inbus connects to the device? */intmems_get_inbus (int devno){ mems_t *dev = getmems(devno); return dev->inbuses[0]; /* Only one bus connection allowed */}/* In which slot on the bus is the device attached? */intmems_get_slotno (int devno){ mems_t *dev = getmems(devno); return dev->slotno[0];}/* Set the inbus information (where, which slot, how deep) */intmems_set_depth (int devno, int inbusno, int depth, int slotno){ mems_t *dev = getmems(devno); int count; count = dev->numinbuses; dev->numinbuses++; if ((count + 1) > MAXINBUSES) { fprintf(stderr,"Too many inbuses specified for memsdevice %d--%d\n", devno, count + 1); exit(1); } dev->inbuses[count] = inbusno; dev->depth [count] = depth; dev->slotno [count] = slotno; return 0;}/************************************************************************ * ioqueue support functions ************************************************************************//* Get the number of sectors per cylinder */intmems_get_avg_sectpercyl (int devno){ mems_t *dev = getmems(devno); return mems_get_blocks_per_cylinder(&dev->sled[0]);}/* Find the cylinder, surface, and block mapping of a block */voidmems_get_mapping (int maptype, int devno, int blkno, int *cylptr, int *surfaceptr, int *blkptr){ mems_t *dev = getmems(devno); mems_sled_t *sled = mems_lbn_to_sled(dev, blkno); tipsector_coord_set_t up, dn; tipset_t tipset; if ((blkno < 0) || (blkno >= dev->numblocks)) { fprintf(stderr, "Invalid blkno at mems_get_mapping (%d)\n", blkno); exit(1); } mems_lbn_to_position(blkno, sled, &up, &dn, &tipset, cylptr, surfaceptr, blkptr);}/* Get the number of cylinders (e.g., X distance bits) in the device */intmems_get_numcyls (int devno){ mems_t *dev = getmems(devno); return mems_get_number_of_cylinders(dev);}doublemems_get_acctime (int devno, ioreq_event *req, double maxtime){ // fprintf(stderr, "Entering mems_get_acctime()\n"); /* This function can be extended to calculate the access time * for any request. It's not extended yet. We shouldn't ever * get here, so just die. */ assert(FALSE); return 0.0;}double mems_get_seektime (int devno, ioreq_event *req, int checkcache, double maxtime){ mems_t *dev = getmems(req->devno); mems_sled_t *sled = mems_lbn_to_sled(dev, req->blkno); double up_time; double dn_time; tipsector_coord_set_t up; tipsector_coord_set_t dn; tipset_t tipset; // fprintf(stderr, "Entering mems_get_seektime()\n"); mems_lbn_to_position(req->blkno, sled, &up, &dn, &tipset, NULL, NULL, NULL); up_time = mems_seek_time(sled, &sled->pos, &up.servo_start, NULL, NULL, NULL, NULL); dn_time = mems_seek_time(sled, &sled->pos, &dn.servo_start, NULL, NULL, NULL, NULL); return min(up_time, dn_time);}voidmems_get_average_position (tipsector_coord_set_t *up, tipsector_coord_set_t *down, coord_t *average){ assert(up->servo_start.x_pos == down->servo_start.x_pos); average->x_pos = up->servo_start.x_pos; average->y_pos = (up->servo_start.y_pos + down->servo_start.y_pos) / 2; average->y_vel = 0;}/* * mems_get_distance * * return the distance from the current position, or a given lbn, to the position * of req. * * devno - the number of the device in question. * * req - a pointer to the request, which gives the destination position. we're * trying to find the distance to this point. * * exact - if equal to -1, then use the sled's current position as the starting * point. else, this gives the lbn to use as the starting position. * * direction - ignored for now. * */// #define DISTANCE_DEBUGintmems_get_distance (int devno, ioreq_event *req, int exact, int direction){ coord_t *start_position; coord_t *dest_position; mems_t *dev = getmems(devno); mems_sled_t *sled = mems_lbn_to_sled(dev, req->blkno); tipsector_coord_set_t up, down; tipset_t tipset; int distance1, distance2; int x1, x2, y1, y2;#ifdef DISTANCE_DEBUG fprintf(outputfile, "mems_get_distance -- devno = %d, req->blkno = %d, exact = %d, direction = %d\n", devno, req->blkno, exact, direction);#endif if (exact == -1) { start_position = mems_get_current_position(sled); } else { // find the starting position mems_lbn_to_position(exact, sled, &up, &down, &tipset, NULL, NULL, NULL); start_position = (coord_t *)malloc(sizeof(coord_t)); mems_get_average_position(&up, &down, start_position); } // dest_position = (coord_t *)malloc(sizeof(coord_t)); // find the destination position mems_lbn_to_position(req->blkno, sled, &up, &down, &tipset, NULL, NULL, NULL); // mems_get_average_position(&up, &down, dest_position); x1 = start_position->x_pos; x2 = up.servo_start.x_pos; y1 = start_position->y_pos; y2 = up.servo_start.y_pos;#ifdef DISTANCE_DEBUG fprintf(outputfile, "mems_get_distance -- UP - x1 = %d, y1 = %d, x2 = %d, y2 = %d\n", x1, y1, x2, y2);#endif distance1 = (int)(sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))); x1 = start_position->x_pos; x2 = down.servo_start.x_pos; y1 = start_position->y_pos; y2 = down.servo_start.y_pos;#ifdef DISTANCE_DEBUG fprintf(outputfile, "mems_get_distance -- DOWN - x1 = %d, y1 = %d, x2 = %d, y2 = %d\n", x1, y1, x2, y2);#endif distance2 = (int)(sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))); if (exact != -1) { free(start_position); }#ifdef DISTANCE_DEBUG fprintf(outputfile, "mems_get_distance -- distance1 = %d, distance2 = %d\n", distance1, distance2);#endif if (distance1 < distance2) {#ifdef DISTANCE_DEBUG fprintf(outputfile, "returning distance1 = %d\n", distance1);#endif return (distance1); } else {#ifdef DISTANCE_DEBUG fprintf(outputfile, "returning distance2 = %d\n", distance2);#endif return (distance2); }}#undef DISTANCE_DEBUGdoublemems_get_servtime (int devno, ioreq_event *req, int checkcache, double maxtime){ // fprintf(stderr, "Entering mems_get_servtime() --"); return mems_get_seektime(devno, req, checkcache, maxtime);}/************************************************************************ * General / informational for disksim components ************************************************************************//* Return the bulk sector transfer time (the greater of the device bulk * sector transfer time and the bus bulk sector transfer time) */doublemems_get_blktranstime (ioreq_event *curr){ mems_t *dev = getmems(curr->devno); double tmptime; /* return min(bus_blktranstime,dev_blktranstime) */ tmptime = bus_get_transfer_time(mems_get_busno(curr), 1, (curr->flags & READ)); if (tmptime < dev->blktranstime) { /* FIXME: Should there be a distinction between read/write times? */ tmptime = dev->blktranstime; } return tmptime;}/* What's the maximum number of outstanding requests on the device? */intmems_get_maxoutstanding (int devno){ mems_t *dev = getmems(devno); return dev->maxqlen;}/* How many blocks are available across all sleds on the device? */intmems_get_number_of_blocks (int devno){ mems_t *dev = getmems(devno); if (dev->numblocks == 0) mems_check_numblocks(dev); return dev->numblocks;}/************************************************************************ * Statistics stuff ************************************************************************/static voidmems_statinit (int devno, int firsttime){ mems_t *dev = getmems(devno); int j; /* First initialize device statistics */ if (firsttime) { stat_initialize (statdeffile, statdesc_request_energy_uj, &dev->stat.request_energy_uj); stat_initialize (statdeffile, statdesc_seek_time, &dev->stat.seek_time); stat_initialize (statdeffile, statdesc_x_seek_time, &dev->stat.x_seek_time); stat_initialize (statdeffile, statdesc_y_seek_time, &dev->stat.y_seek_time); stat_initialize (statdeffile, statdesc_turnaround_time, &dev->stat.turnaround_time); stat_initialize (statdeffile, statdesc_turnaround_number, &dev->stat.turnaround_number); stat_initialize (statdeffile, statdesc_stream_turnaround_time, &dev->stat.stream_turnaround_time); stat_initialize (statdeffile, statdesc_stream_turnaround_number, &dev->stat.stream_turnaround_number); stat_initialize (statdeffile, statdesc_subtrack_accesses, &dev->stat.subtrack_accesses); stat_initialize (statdeffile, statdesc_tips_per_access, &dev->stat.tips_per_access); stat_initialize (statdeffile, statdesc_inactive_time, &dev->stat.inactive_time); stat_initialize (statdeffile, statdesc_prefetched_blocks, &dev->stat.prefetched_blocks); } else { stat_reset (&dev->stat.request_energy_uj); stat_reset (&dev->stat.seek_time); stat_reset (&dev->stat.x_seek_time); stat_reset (&dev->stat.y_seek_time); stat_reset (&dev->stat.turnaround_time); stat_reset (&dev->stat.turnaround_number); stat_reset (&dev->stat.stream_turnaround_time); stat_reset (&dev->stat.stream_turnaround_number); stat_reset (&dev->stat.subtrack_accesses); stat_reset (&dev->stat.tips_per_access); stat_reset (&dev->stat.inactive_time); stat_reset (&dev->stat.prefetched_blocks); } dev->stat.total_energy_j = 0.0; dev->stat.servicing_energy_j = 0.0; dev->stat.startup_energy_j = 0.0; dev->stat.idle_energy_j = 0.0; dev->stat.inactive_energy_j = 0.0; dev->stat.num_spinups = 0; dev->stat.num_spindowns = 0; dev->stat.num_buffer_accesses = 0; dev->stat.num_buffer_hits = 0; dev->stat.num_initial_turnarounds = 0; dev->stat.num_stream_turnarounds = 0; /* Now initialize sled statistics */ for (j=0; j < dev->num_sleds; j++) { if (firsttime) { stat_initialize (statdeffile, statdesc_request_energy_uj, &dev->sled[j].stat.request_energy_uj); stat_initialize (statdeffile, statdesc_seek_time, &dev->sled[j].stat.seek_time); stat_initialize (statdeffile, statdesc_x_seek_time, &dev->sled[j].stat.x_seek_time); stat_initialize (statdeffile, statdesc_y_seek_time, &dev->sled[j].stat.y_seek_time); stat_initialize (statdeffile, statdesc_turnaround_time, &dev->sled[j].stat.turnaround_time); stat_initialize (statdeffile, statdesc_turnaround_number, &dev->sled[j].stat.turnaround_number); stat_initialize (statdeffile, statdesc_stream_turnaround_time, &dev->sled[j].stat.stream_turnaround_time); stat_initialize (statdeffile, statdesc_stream_turnaround_number,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?