mems_internals.c

来自「disksim是一个非常优秀的磁盘仿真工具」· C语言 代码 · 共 1,010 行 · 第 1/2 页

C
1,010
字号
/* * 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. * */#include "mems_global.h"#include "mems_internals.h"#include "mems_piecewise_seek.h"#include "mems_hong_seek.h"/*  this allows the output mechanism to be defined at compile time so *  that you can compile the seek code on its own for testing.  otherwise, *  all logging is done to the disksim output file */#ifdef __SEPERATE__#define __OUTPUTFILE__  stderr#else#define __OUTPUTFILE__  outputfile#endif/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * *  mems_get_current_position() * *  returns the current position of the sled specified *  by the sled pointer. * *  inputs: *    mems_sled *sled - pointer to the sled structure * *  outputs: *    coord_t * - a pointer to the coord_t in the sled structure * *  modifies: * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/coord_t *mems_get_current_position(mems_sled_t *sled) {  //  ASSERT(pos != NULL);  // pos = &sled->pos;  return (&sled->pos);}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * *  mems_equal_coords() * *  returns TRUE if the two coordinates are equal * *  inputs: *    coord_t *one - first coordinate *    coord_t *two - second coordinate * *  outputs: *    int - TRUE if they are equal, false if they are not * *  modifies: *    nothing * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/intmems_equal_coords(coord_t *one, coord_t *two) {    if ((one->x_pos == two->x_pos) && (one->y_pos == two->y_pos) && (one->y_vel == two->y_vel)) {    return TRUE;  } else {    return FALSE;  }}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * *  mems_equal_coord_sets() * *  returns TRUE if the two coordinate sets are equal * *  inputs: *    tipsector_coord_set_t *one - first coordinate set *    tipsector_coord_set_t *two - second coordinate set * *  outputs: *    int - TRUE if they are equal, false if they are not * *  modifies: *    nothing * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/int mems_equal_coord_sets (tipsector_coord_set_t *one, tipsector_coord_set_t *two){  return (mems_equal_coords(&one->servo_start, &two->servo_start) &&	  mems_equal_coords(&one->tipsector_start, &two->tipsector_start) &&	  mems_equal_coords(&one->tipsector_end, &two->tipsector_end));}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * *  mems_media_access_time() * *  returns the time it takes to access the media between *  two coordinates.  this is called to find out how long *  a read or write will take.  it assumes that the device *  can read and write at the same rate. * *  inputs: *    mems_sled *sled - a pointer to the sled structure *    coord_t *start - the starting coordinate *    coord_t *end - the destination coordinate * *  outputs: *    double - the amount of time in milliseconds to access *             data between the two points. * *  modifies: *    nothing * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/doublemems_media_access_time (mems_sled_t *sled, coord_t *start, coord_t *end){  double time;		/* seconds */  double velocity;	/* nanometers per second */  double distance;	/* nanometers */  velocity = (double)(sled->y_access_speed_bit_s * sled->bit_length_nm);  distance = (fabs ((double)(start->y_pos - end->y_pos))) * sled->bit_length_nm;  time = distance / velocity;  /* convert to milliseconds */  time *= 1000.0;  /*  fprintf (stderr, "access: time = %f ms, dist = %f nm, vel = %f nm/s\n", time, distance, velocity);  */  return (time);}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * *  mems_coord_t_copy() * *  copies one coord_t into another * *  inputs: *    coord_t *source - coordinate to be copied *    coord_t *dest - coordinate to be copied into * *  outputs: *    none * *  modifies: *    dest * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/voidmems_coord_t_copy (coord_t *source, coord_t *dest) {    dest->x_pos = source->x_pos;  dest->y_pos = source->y_pos;  dest->y_vel = source->y_vel;}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * *  mems_coord_t_copy() * *  copies one tipsector_coord_set_t into another * *  inputs: *    tipsector_coord_set_t *source - coordinate set to be copied *    tipsector_coord_set_t *dest - coordinate set to be copied into * *  outputs: *    none * *  modifies: *    dest * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/voidmems_tipsector_coord_set_t_copy (tipsector_coord_set_t *source, tipsector_coord_set_t *dest) {  mems_coord_t_copy(&source->servo_start, &dest->servo_start);  mems_coord_t_copy(&source->tipsector_start, &dest->tipsector_start);  mems_coord_t_copy(&source->tipsector_end, &dest->tipsector_end);}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * *  mems_commit_move() * *  actually records a new position in the sled structure. *  this allows the upper levels of the simulator to call *  the seek time calcluation functions without changing *  the sled state. * *  inputs: *    mems_sled *sled - pointer to the sled structure *    coord_t *pos - pointer to the updated coordinate * *  outputs: *    none * *  modifies: *    sled->pos - updates sled->pos to be the new coordinate * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/voidmems_commit_move(mems_sled_t *sled,		  coord_t *pos) {  mems_coord_t_copy(pos, &sled->pos);}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * *  find_settle_time() * *  finds the settle time, which is given thusly: * *  settle time = num_time_constants * (1 / (2 pi * resonant frequency)) * *  in this version of the model, the settle time is _not_ *  dependent on the seek distance or the spring_factor * *  inputs: *    double num_time_constants - the number of time constants to *           add to a seek *    double resonant_frequency - resonant frequency of the sled * *  outputs: *    double - the settle time * *  modifies: *    nothing * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/doublefind_settle_time(double num_time_constants, double resonant_frequency) {  return (num_time_constants * (1.0 / ((6.2831853) * (resonant_frequency))));}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * *  find_turnaround_time() * *  finds the turnaround time.  this is a function of the sled velocity, *  the actuator acceleration and the spring forces.  that makes it also *  a function of position (offset). * *  inputs: *    double offset_nm - the offset at which the turnaround occurs *    double velocity_nm_s - the sled velocity *    double base_accel_nm_s_s - the actuator acceleration *    double spring_factor - the spring_factor *    double length_nm - the length of the square * *  outputs: *    double - the turnaround time * *  modifies: *    nothing * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/doublefind_turnaround_time(double offset_nm, double velocity_nm_s, double base_accel_nm_s_s,		     double spring_factor, double length_nm) {    double turnaround_time;  double spring_accel;    if (_VERBOSE_) {    fprintf(__OUTPUTFILE__, "find_turnaround_time::  entry\n");        fprintf(__OUTPUTFILE__, "find_turnaround_time::  offset_nm = %f, length_nm = %f\n",	    offset_nm, length_nm);  }  /*  scale the base acceleration by the spring_factor and the offset  */  spring_accel = (base_accel_nm_s_s * (spring_factor * (fabs(offset_nm) / (length_nm / 2.0))));    if ( ((offset_nm < 0.0) && (velocity_nm_s > 0.0)) ||       ((offset_nm > 0.0) && (velocity_nm_s < 0.0))       )    {      /*  the springs will hurt my acceleration  */      spring_accel = -spring_accel;    }  /*  turnaround time is the time to stop the sled plus the time to accelerate it back to      velocity.  these are equal, so it's just twice the time to stop.  */  turnaround_time = 2.0 * (fabs(velocity_nm_s)) / (base_accel_nm_s_s + spring_accel);  if (_VERBOSE_) {    fprintf(__OUTPUTFILE__, "find_turnaround_time::  velocity_nm_s = %f, base_accel_nm_s_s = %f, spring_accel = %f\n",	    velocity_nm_s, base_accel_nm_s_s, spring_accel);        fprintf(__OUTPUTFILE__, "find_turnaround_time::  turnaround_time = %f\n", turnaround_time);  }  return turnaround_time;}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * *  mems_seek_time() * *  this function finds the seek time from point to point, *  taking into account all turnarounds that might have to *  take place.  it also returns some useful statistics *  that may be recorded by the calling function. * *  inputs: *    mems_sled *sled - a pointer to the sled structure *    coord_t *begin - the beginning coordinate *    coord_t *end - the end coordinate *    double *return_x_seek_time - a pointer into which to return the x seek time *    double *return_y_seek_time - a pointer into which to return the y seek time *    double *return_turnaround_time - a pointer into which to return the turnaround time *    double *return_turnaround_number - a pointer into which to return the number of turnarounds * *  outputs: *    double - the total seek time * *  modifies: *    return_x_seek_time *    return_y_seek_time *    return_turnaround_time *    return_turnaround_number * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/doublemems_seek_time (mems_sled_t *sled,		coord_t *begin, coord_t *end,		double *return_x_seek_time, double *return_y_seek_time,		double *return_turnaround_time, int *return_turnaround_number){  double seek_time_x=0.0;	/* second */  double seek_time_y=0.0;	/* second */  double dist_x_nm=0.0;		  double dist_y_nm=0.0;		  int dist_y_equiv_nm=0.0;	/* used for equivalent distance calc */  double x_accel=0.0;           /* nanometer/sec/sec */  double y_accel=0.0;		/* nanometer/sec/sec */  double bit_width=0.0;		/* nanometer */  double turnaround_time=0.0;	/* second */  double settling_time_x=0.0;   /* second */  int y_access_speed_nm_s;  double total_time;		/* second */  int number_of_turns;  double spring_factor = 0.0;  int x_length_nm = 0;  int y_length_nm = 0;  /* sled = &dev->sled[sledno]; */    /*  fprintf(__OUTPUTFILE__, "\nmemsdevice_seek_time::  begin->x_pos = %d, begin->y_pos = %d, begin->y_vel = %d\n",	  begin->x_pos, begin->y_pos, begin->y_vel);  fprintf(__OUTPUTFILE__, "memsdevice_seek_time::  end->x_pos   = %d, end->y_pos = %d, end->y_vel = %d\n",	  end->x_pos, end->y_pos, end->y_vel);  */  /*  first check to see if begin == end  */  if (mems_equal_coords(begin, end)) {    //    fprintf(__OUTPUTFILE__, "memsdevice_seek_time::  begin == end!\n");    // fprintf(stderr, "memsdevice_seek_time::  begin == end!\n");    if (return_turnaround_time != NULL) {      *return_turnaround_time = 0.0;    }        if (return_turnaround_number != NULL) {      *return_turnaround_number = 0;    }        if (return_x_seek_time != NULL) {      *return_x_seek_time = 0.0;    }        if (return_y_seek_time != NULL) {      *return_y_seek_time = 0.0;    }    return 0.0;  }  /*  initialize some variables to values given in the sled structure  */    x_accel = (double)sled->x_accel_nm_s2;  y_accel = (double)sled->y_accel_nm_s2;  bit_width = (double)sled->bit_length_nm;  y_access_speed_nm_s = sled->y_access_speed_bit_s * sled->bit_length_nm;  x_length_nm = sled->x_length_nm;  y_length_nm = sled->y_length_nm;  spring_factor = sled->spring_factor;  /*  fprintf(__OUTPUTFILE__, "memsdevice_seek_time::  begin->x_pos = %d, bit_width = %f, x_begin_nm = %f\n",	  begin->x_pos, bit_width, x_begin_nm);  fprintf(__OUTPUTFILE__, "memsdevice_seek_time::  end->x_pos = %d, bit_width = %f, x_end_nm = %f\n",	  end->x_pos, bit_width, x_end_nm);  */  if (end->x_pos == begin->x_pos) {    dist_x_nm = (double)0.0;    seek_time_x = (double)0.0;  } else {    /*  find the x settle time  */    settling_time_x = find_settle_time(sled->num_time_constants, sled->sled_resonant_freq_hz);    /*    fprintf(__OUTPUTFILE__, "settling_time_x = %f\n", settling_time_x);    */    /*    fprintf(__OUTPUTFILE__, "memsdevice_seek_time:: find_seek_time_piecewise - x_begin_nm = %f, x_end_nm = %f\n",	    x_begin_nm, x_end_nm);    */    /*  find the base seek time in x  */    if (sled->dev->seek_function == MEMS_SEEK_HONG) {      seek_time_x = find_seek_time_hong_x((begin->x_pos * bit_width),					  (end->x_pos * bit_width),					  spring_factor, x_accel,					  x_length_nm)	+	settling_time_x;    } else {      if (sled->dev->precompute_seek_count > 0) {	seek_time_x =	  mems_find_precomputed_seek_time(sled,					  (begin->x_pos * bit_width), (end->x_pos * bit_width),					  _X_SEEK_)	  +	  settling_time_x;      } else {	seek_time_x =	  find_seek_time_piecewise((begin->x_pos * bit_width), (end->x_pos * bit_width),				   spring_factor, x_accel,				   x_length_nm, 0.0)	  +	  settling_time_x;      }    }  }  /* Now calculate seek time in Y direction.   * First, general values needed in the calculations.   *   * there are eight cases to account for:

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?