⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mems_piecewise_seek.c

📁 disksim是一个非常优秀的磁盘仿真工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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 <math.h>#include "mems_global.h"#include "mems_piecewise_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/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *  These are helper functions for the piecewise-linear *  seek time model. *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*//*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * *  find_dist_nm() * *  returns the distance in nanometers from start_offset *  to end_offset.  remember that these are _offsets_ from *  the center of the sled. * *  inputs: *    mems_sled_t *sled - a pointer to the sled structure *    coord_t *start - the starting coordinate *    coord_t *end - the destination coordinate * *  outputs: *    double - the distance in nm from start_offset to *             end_offset * *  modifies: *    nothing * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/doublefind_dist_nm(double start_offset, double end_offset) {  double dist_nm;  if (((start_offset > 0.0) && (end_offset > 0.0)) ||      ((start_offset < 0.0) && (end_offset < 0.0))) {    /*  we're on the same side of the sled  */    dist_nm = fabs(end_offset - start_offset);  } else {    dist_nm = fabs(start_offset) + fabs(end_offset);  }  if (_VERBOSE_) {    fprintf(__OUTPUTFILE__, "find_dist_nm::  start_offset = %f, end_offset = %f, dist_nm = %f\n",	    start_offset, end_offset, dist_nm);  }  return dist_nm;}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * *  find_local_actuator_direction() * *  returns the direction which the actuators are pulling *  the sled, INWARD or OUTWARD.  this is used to determine *  if the actuators are helping the seek or hurting the *  seek.  see below for more. * *  inputs: *    double start_offset_nm - the start offset of the seek *    double end_offset_nm - the end offset of the seek *    int overall_actuator_direction - the direction the *                         actuators are acting. * *  outputs: *    int - INWARD if the actuators are pulling the sled *          toward the center, OUTWARD if the actuators are *          pulling toward the edge. * *  modifies: *    nothing * *  what's really going on here: * *    okay, what's the difference between INWARD, OUTWARD, OVERALL_POSITIVE, *  OVERALL_NEGATIVE, etc, and what is this function for anyway?  second question *  first:  given start and end offsets, this fuction tells you if the actuators *  are pulling the sled toward the rest position (INWARD) or away from the rest *  position (OUTWARD).  for example, if the overall_actuator_direction is *  OVERALL_POSITIVE, and the seek is entirely on the positive half of the square, *  then the actuators are pulling the sled OUTWARD.  when the seek crosses the *  center line, then the function decides based the larger portion of the seek. *  i think that answers the second question, too.  it's used to determine when *  the springs will help the seek and when they'll hurt. * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/int find_local_actuator_direction(double start_offset_nm, double end_offset_nm,				  int overall_actuator_direction) {  if (_VERBOSE_) {    fprintf(__OUTPUTFILE__, "find_local_actuator_direction::  start_offset_nm = %f, end_offset_nm = %f\n",	    start_offset_nm, end_offset_nm);        if (overall_actuator_direction == OVERALL_POSITIVE)      fprintf(__OUTPUTFILE__, "find_local_actuator_direction::  overall_actuator_direction = OVERALL_POSITIVE\n");    else      fprintf(__OUTPUTFILE__, "find_local_actuator_direction::  overall_actuator_direction = OVERALL_NEGATIVE\n");  }  if ((start_offset_nm <= 0.0) && (end_offset_nm <= 0.0)) {    /*  if the seek is on the negative side  */    if (overall_actuator_direction == OVERALL_POSITIVE) {      if (_VERBOSE_) fprintf(__OUTPUTFILE__, "find_local_actuator_direction::  local_actuator_direction is INWARD (1)\n");      return INWARD;    } else {      if (_VERBOSE_) fprintf(__OUTPUTFILE__, "find_local_actuator_direction::  local_actuator_direction is OUTWARD (2)\n");      return OUTWARD;    }  } else if ((start_offset_nm >= 0.0) && (end_offset_nm >= 0.0)) {    /*  if the seek is on the positive side  */    if (overall_actuator_direction == OVERALL_POSITIVE) {      if (_VERBOSE_) fprintf(__OUTPUTFILE__, "find_local_actuator_direction::  local_actuator_direction is OUTWARD (3)\n");      return OUTWARD;    } else {      if (_VERBOSE_) fprintf(__OUTPUTFILE__, "find_local_actuator_direction::  local_actuator_direction is OUTWARD (4)\n");      return INWARD;    }  } else {    /*  the seek crosses the centerline  */    if (fabs(start_offset_nm) > fabs(end_offset_nm)) {      /*  i move more toward the center than away  */      if (_VERBOSE_) fprintf(__OUTPUTFILE__, "find_local_actuator_direction::  local_actuator_direction is INWARD (5)\n");      return INWARD;    } else {      if (_VERBOSE_) fprintf(__OUTPUTFILE__, "find_local_actuator_direction::  local_actuator_direction is OUTWARD (6)\n");      return OUTWARD;    }  }}  /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * *  adjust_accel() * *  returns the acceleration in the region given by the *  start and end points.  the acceleration at the two points *  is the sum of the actuator acceleration and the spring *  acceleration, which is given by * *      [ actuator_accel *  offset  ] *      [                  -------- ]  *  spring_factor *      [                  length/2 ]  * *  the springs' restoring force is then a function of the *  displacement (offset) and a fraction (spring_factor) of *  the actuator force.  put another way, if the spring_factor *  is 0.10, then at the maximum offset the force from the springs *  will be equal to 10% of the force from the actuators. * *  the returned adjusted acceleration is the average of the *  sums at the start and end points. * *  inputs: *    double accel - the base acceleration from the actuators *    double spring_factor - the spring factor *    double offset_1 - the offset of the starting point *    double offset_2 - the offset of the ending point *    double length - the length of the sled *    int overall_actuator_direction - INWARD if the actuators *          are pulling the sled toward the center, OUTWARD otherwise. * *  outputs: *    double - the adjusted acceleration for the region between *             the start and end offsets, given the base actuator *             acceleration, the spring_factor, the length of the *             sled, and the overall actuator direction * *  modifies: *    nothing * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/double adjust_accel(double accel, double spring_factor,		    double offset_1, double offset_2,		    double length, int overall_actuator_direction) {  double adjusted_accel;  if (find_local_actuator_direction(offset_1, offset_2, overall_actuator_direction) == INWARD) {    /*  springs help  */    if (_VERBOSE_) fprintf(__OUTPUTFILE__, "adjust_accel::  springs helped!\n");  } else {    /*  springs hurt  */    spring_factor = -spring_factor;    if (_VERBOSE_) fprintf(__OUTPUTFILE__, "adjust_accel::  springs hurt!\n");  }  adjusted_accel =    (     (accel      +      (accel * (spring_factor * (fabs(offset_1) / (length / 2))))      )     +     (accel      +      (accel * (spring_factor * (fabs(offset_2) / (length / 2))))      )     ) / 2.0;  if (_VERBOSE_) {    fprintf(__OUTPUTFILE__, "adjust_accel::  offset_1 = %f, offset_2 = %f, accel = %f\n",	    offset_1, offset_2, accel);    fprintf(__OUTPUTFILE__, "adjust_accel::  spring_factor = %f, length = %f\n",	    spring_factor, length);    fprintf(__OUTPUTFILE__, "adjust_accel::  adjusted_accel = %f, diff = %f\n",	    adjusted_accel, ((adjusted_accel / accel) * 100.0) - 100.0);  }  return adjusted_accel;}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * *  find_switch_offset_from_dist() * *  computes the switchpoint offset between start_offset_nm *  and end_offset_nm.  this finds the offset which is the *  midpoint between the two points. * *  inputs: *    double start_offset_nm - the starting offset *    double end_offset_nm - the end offset *    double dist_nm - the distance in nm between the two points *    int direction - the direction of the seek * *  outputs: *    double - the offset of the midpoint in nm * *  modifies: *    nothing * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/doublefind_switch_offset_from_dist (double start_offset_nm, double end_offset_nm,			      double dist_nm, int direction) {  double switch_offset_nm;  if (direction == OVERALL_POSITIVE) {    switch_offset_nm = start_offset_nm + (dist_nm / 2);  } else {    switch_offset_nm = start_offset_nm - (dist_nm / 2);  }  return switch_offset_nm;}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * *  find_overall_seek_direction() * *  finds the direction of the seek - OVERALL_POSITIVE *  or OVERALL_NEGATIVE * *  inputs: *    double start_offset_nm - the starting offset *    double end_offset_nm - the end offset * *  outputs: *    int - OVERALL_POSITIVE if the seek is in the positive *          direction, OVERALL_NEGATIVE if negative. * *  modifies: *    nothing * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/intfind_overall_seek_direction(double start_offset_nm, double end_offset_nm) {    if (end_offset_nm > start_offset_nm) {    return OVERALL_POSITIVE;  } else {    return OVERALL_NEGATIVE;  }}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * *  find_seek_time_piecewise() * *  this is the guts of the seek code.  find_seek_time_piecewise() *  returns the time to seek from start_offset_nm to end_offset_nm *  given the various parameters.  it assumes that the

⌨️ 快捷键说明

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