mems_internals.c

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

C
1,010
字号
   *   * begin = current velocity; end = new velocity;   * below = new position BELOW current position;   * above = new position ABOVE current position   *   *	begin UP	end UP		below	(1) turn, seek, turn   *					above	(2) seek   *   *			end DOWN	below	(3) turn, seek   *					above	(4) seek, turn   *   *	begin DOWN	end UP		below	(5) seek, turn   *					above	(6) turn, seek   *   *			end DOWN	below	(7) seek   *					above	(8) turn, seek, turn   */  /*  fprintf(__OUTPUTFILE__, "memsdevice_seek_time::  begin->y_vel = %d, end->y_vel = %d\n",	  begin->y_vel, end->y_vel);  fprintf(__OUTPUTFILE__, "memsdevice_seek_time::  begin->y_pos = %d, end->y1_pos = %d\n",	  begin->y_pos, end->y1_pos);  fprintf(__OUTPUTFILE__, "memsdevice_seek_time::  end->y1_pos = %d, end->y2_pos = %d\n",	  end->y1_pos, end->y2_pos);  */  turnaround_time = 0.0;  number_of_turns = 0;  if (begin->y_vel >= 0) {    if (end->y_vel > 0) {	/* final direction == begining direction */      if (begin->y_pos >= end->y_pos) {	/* case (1) */	turnaround_time = find_turnaround_time((begin->y_pos * bit_width),					       begin->y_vel,					       y_accel,					       spring_factor, y_length_nm);	turnaround_time += find_turnaround_time((end->y_pos * bit_width),						end->y_vel,						y_accel,						spring_factor, y_length_nm);	number_of_turns = 2;	/*	fprintf(__OUTPUTFILE__, "memsdevice_seek_time::  finding turnarounds - case 1 - turnaround_time = %f\n",		turnaround_time);	*/      } else {					/* no need to turn around */	/* case (2) */	number_of_turns = 0;	/*	fprintf(__OUTPUTFILE__, "memsdevice_seek_time::  finding turnarounds - case 2 - turnaround_time = %f\n",		turnaround_time);	*/      }    } else {			/* final direction != begining direction */      if (begin->y_pos >= end->y_pos) {	/* case (3) */	turnaround_time = find_turnaround_time((begin->y_pos * bit_width),					       begin->y_vel,					       y_accel,					       spring_factor, y_length_nm);	number_of_turns = 1;	/*	fprintf(__OUTPUTFILE__, "memsdevice_seek_time::  finding turnarounds - case 3 - turnaround_time = %f\n",		turnaround_time);	*/      } else {	/* case (4) */        turnaround_time = find_turnaround_time((end->y_pos * bit_width),					       end->y_vel,					       y_accel,					       spring_factor, y_length_nm);	number_of_turns = 1;	/*	fprintf(__OUTPUTFILE__, "memsdevice_seek_time::  finding turnarounds - case 4 - turnaround_time = %f\n",		turnaround_time);	*/      }    }  } else {	/* begin.y_vel < 0.0 */    if (end->y_vel > 0) {	/* final direction != begining direction */      if (begin->y_pos >= end->y_pos) {	/* case (5) */	turnaround_time = find_turnaround_time((end->y_pos * bit_width),					       end->y_vel,					       y_accel,					       spring_factor, y_length_nm);	number_of_turns = 1;	/*	fprintf(__OUTPUTFILE__, "memsdevice_seek_time::  finding turnarounds - case 5 - turnaround_time = %f\n",		turnaround_time);	*/      } else {	/* case (6) */	turnaround_time = find_turnaround_time((begin->y_pos * bit_width),					       begin->y_vel,					       y_accel,					       spring_factor, y_length_nm);	number_of_turns = 1;	/*	fprintf(__OUTPUTFILE__, "memsdevice_seek_time::  finding turnarounds - case 6 - turnaround_time = %f\n",		turnaround_time);	*/      }    } else {			/* final direction == begining direction */      if (begin->y_pos >= end->y_pos) {	/* no need to turn around */	/* case (7) */	number_of_turns = 0;	/*	fprintf(__OUTPUTFILE__, "memsdevice_seek_time::  finding turnarounds - case 7 - turnaround_time = %f\n",		turnaround_time);	*/	dist_y_equiv_nm = 0;      } else {	/* case (8) */	turnaround_time = find_turnaround_time((begin->y_pos * bit_width),					       begin->y_vel,					       y_accel,					       spring_factor, y_length_nm);	turnaround_time += find_turnaround_time((end->y_pos * bit_width),						end->y_vel,						y_accel,						spring_factor, y_length_nm);	number_of_turns = 2;	/*	fprintf(__OUTPUTFILE__, "memsdevice_seek_time::  finding turnarounds - case 8 - turnaround_time = %f\n",		turnaround_time);	*/      }    }  }    dist_y_nm = (double)abs(end->y_pos - begin->y_pos) * sled->bit_length_nm;    /*  fprintf(__OUTPUTFILE__, "memsdevice_seek_time::  begin->y_pos = %d, bit_width = %f, y_begin_nm = %f\n",	  begin->y_pos, bit_width, y_begin_nm);  fprintf(__OUTPUTFILE__, "memsdevice_seek_time::  end->y1_pos = %d, bit_width = %f, y_end_nm = %f\n",	  end->y1_pos, bit_width, y_end_nm);    fprintf(__OUTPUTFILE__, "memsdevice_seek_time:: find_seek_time_piecewise - y_begin_nm = %f, y_end_nm = %f\n",	  y_begin_nm, y_end_nm);  */  if (sled->dev->seek_function == MEMS_SEEK_HONG) {    seek_time_y =      find_seek_time_hong_y((begin->y_pos * bit_width),			    (end->y_pos * bit_width),			    spring_factor, y_accel,			    y_length_nm, y_access_speed_nm_s)      +      turnaround_time;  } else {    if (sled->dev->precompute_seek_count > 0) {      seek_time_y =	mems_find_precomputed_seek_time(sled,					(begin->y_pos * bit_width), (end->y_pos * bit_width),					_Y_SEEK_)	+	turnaround_time;    } else {      seek_time_y =	find_seek_time_piecewise((begin->y_pos * bit_width), (end->y_pos * bit_width),				 spring_factor, y_accel,				 y_length_nm, y_access_speed_nm_s)	+ turnaround_time;    }  }  /*  if (distance != NULL) {    if (distance_direction == 1) {      *distance = (int)sqrt(dist_x_nm * dist_x_nm + ((dist_y_nm + dist_y_equiv_nm) * (dist_y_nm + dist_y_equiv_nm)));    } else {      *distance = (int)sqrt(dist_x_nm * dist_x_nm + dist_y_nm * dist_y_nm);    }    // fprintf (__OUTPUTFILE__, "dist_x = %f, dist_y = %f; dist = %d\n", dist_x_nm, dist_y_nm, *distance);  }  */  if (return_turnaround_time != NULL) {    *return_turnaround_time = (turnaround_time) * 1000.0;  }  if (return_turnaround_number != NULL) {    *return_turnaround_number = number_of_turns;  }  if (return_x_seek_time != NULL) {    *return_x_seek_time = seek_time_x * 1000.0;  }  if (return_y_seek_time != NULL) {    *return_y_seek_time = seek_time_y * 1000.0;  }  /*  fprintf (stderr, "turnaround_time = %f, number_of_turns = %d\n",	   (turnaround_time * 1000.0), number_of_turns);  */  if (_VERBOSE_) {    printf("dist_x = %f; dist_y = %f; seek_time_x = %f; seek_time_y = %f\n",	   dist_x_nm, dist_y_nm, seek_time_x, seek_time_y);  }  /*  total seek time is the max of the seek time in the two dimensions  */  total_time = max(seek_time_x, seek_time_y);  /*  convert to milliseconds  */  return (total_time * (double)1000.0);}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *  This implements the seek cache. *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/doublemems_seek_time_seekcache (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){  struct mems_seekcache *s;  int i;  /* First check if value is cached */  for (i = 0; i < MEMS_SEEKCACHE; i++) {    s = &sled->seekcache[i];    if (mems_equal_coords(begin, &s->begin) &&	mems_equal_coords(end, &s->end)) {      if (return_x_seek_time) *return_x_seek_time = s->x_seek_time;      if (return_y_seek_time) *return_y_seek_time = s->y_seek_time;      if (return_turnaround_time) *return_turnaround_time = s->turnaround_time;      if (return_turnaround_number) *return_turnaround_number = s->turnaround_number;      return s->time;    }  }  s = &sled->seekcache[sled->seekcache_next];  mems_coord_t_copy(begin, &s->begin);  mems_coord_t_copy(end, &s->end);  s->time = mems_seek_time(sled, &s->begin, &s->end, &s->x_seek_time, &s->y_seek_time, &s->turnaround_time, &s->turnaround_number);  if (return_x_seek_time) *return_x_seek_time = s->x_seek_time;  if (return_y_seek_time) *return_y_seek_time = s->y_seek_time;  if (return_turnaround_time) *return_turnaround_time = s->turnaround_time;  if (return_turnaround_number) *return_turnaround_number = s->turnaround_number;  sled->seekcache_next++;  if (sled->seekcache_next == MEMS_SEEKCACHE) sled->seekcache_next = 0;  // fprintf(stderr, "mems_seek_time_seekcache::  s->time = %f\n", s->time);  return s->time;}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *  These implement the pre-computed seek functions *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/voidmems_print_precomputed_seek_times(mems_t *dev) {  int i;  for (i = 0; i <= dev->precompute_seek_count; i++) {    printf("i = %d, distance = %d, x_seek = %f, y_seek = %f\n",	   i, dev->precompute_seek_distances[i], dev->precompute_x_seek_times[i], dev->precompute_y_seek_times[i]);  }}doublemems_find_precomputed_seek_time(mems_sled_t *sled,				double start_offset_nm, double end_offset_nm,				int direction) {  double seektime = 0.0;  int dist_nm;  int i;      mems_t *dev = sled->dev;  dist_nm = (int)find_dist_nm(start_offset_nm, end_offset_nm);  if (_VERBOSE_) {    fprintf(__OUTPUTFILE__, "mems_find_precomputed_seek_time::  entry - start_offset_nm = %f, end_offset_nm = %f\n",	    start_offset_nm, end_offset_nm);    fprintf(__OUTPUTFILE__, "mems_find_precomputed_seek_time::  dist_nm = %d\n",	    dist_nm);  }  // fprintf(stderr, "dist_nm = %d\n", dist_nm);    // mems_print_precomputed_seek_times(dev);  if (dist_nm) {    for (i=0; i <= dev->precompute_seek_count; i++) {      /*      printf("i = %d, dist = %d, x_seek = %f, y_seek = %f\n",	     i, dev->precompute_seek_distances[i], dev->precompute_x_seek_times[i], dev->precompute_y_seek_times[i]);      */      if (dist_nm <= dev->precompute_seek_distances[i]) {	if (dist_nm == dev->precompute_seek_distances[i]) {	  // fprintf(stderr, "found precomputed seek distance %d\n", dist_nm);	  seektime = (direction == _X_SEEK_) ?	    dev->precompute_x_seek_times[i] :	    dev->precompute_y_seek_times[i];	} else {	  double ddiff =	    (double) (dist_nm - dev->precompute_seek_distances[(i-1)])	    /	    (double) (dev->precompute_seek_distances[i] - dev->precompute_seek_distances[(i-1)]);	  /*	  fprintf(stderr, "did not find precompute seek distance %d\n", dist_nm);	  fprintf(stderr, "ddiff = %f\n", ddiff);	  fprintf(stderr, "i = %d\n", i);	  */	  if (direction == _X_SEEK_) {	    seektime = dev->precompute_x_seek_times[(i-1)];	    // fprintf(stderr, "seektime = %f\n", seektime);	    	    seektime += ddiff * (dev->precompute_x_seek_times[i] - dev->precompute_x_seek_times[(i-1)]);	    /*	    fprintf(stderr, "times[i] = %f, times[i-1] = %f\n",		    dev->precompute_x_seek_times[i], dev->precompute_x_seek_times[(i-1)]);	    fprintf(stderr, "seektime = %f\n", seektime);	    */	  } else {	    seektime = dev->precompute_y_seek_times[(i-1)];	    // fprintf(stderr, "seektime = %f\n", seektime);	    seektime += ddiff * (dev->precompute_y_seek_times[i] - dev->precompute_y_seek_times[(i-1)]);	    /*	    fprintf(stderr, "times[i] = %f, times[i-1] = %f\n",		    dev->precompute_y_seek_times[i], dev->precompute_y_seek_times[(i-1)]);	    fprintf(stderr, "seektime = %f\n", seektime);	    */	  }	}	break;      }    }    if (seektime == 0.0) {      fprintf(stderr, "Seek distance exceeds precompute seek curve: %d\n", dist_nm);      exit(0);    }  }  if (_VERBOSE_) {    fprintf(__OUTPUTFILE__, "mems_find_precompute_seek_time::  finished - seektime = %f\n",	    seektime);  }  // fprintf(stderr, "seektime / 1000.0 = %f\n", (seektime / 1000.0));  return(seektime / 1000.0);}voidmems_precompute_seek_curve(mems_t *dev) {  coord_t begin, end;  double x_seek_time, y_seek_time;  int sled_length_bits;  int offset;  int bit_step;  int nm_step;  int i;  double num_time_constants = dev->sled[0].num_time_constants;  int precompute_seek_count = dev->precompute_seek_count;  dev->sled[0].num_time_constants = 0.0;  dev->precompute_seek_count = 0;  sled_length_bits = (int) (dev->sled[0].x_length_nm / dev->sled[0].bit_length_nm);  bit_step = sled_length_bits / precompute_seek_count;  nm_step = (sled_length_bits * dev->sled[0].bit_length_nm) / precompute_seek_count;  dev->precompute_seek_distances = (int *)malloc((precompute_seek_count + 1) * sizeof(int));  dev->precompute_x_seek_times = (double *)malloc((precompute_seek_count + 1) * sizeof(double));  dev->precompute_y_seek_times = (double *)malloc((precompute_seek_count + 1) * sizeof(double));  /*  printf("precompute_seek_count = %d, bit_step = %d, nm_step = %d\n",	 precompute_seek_count, bit_step, nm_step);  */  //  for(offset = 0; offset <= sled_length_bits; offset += bit_step) {  for(i = 0; i < precompute_seek_count; i++) {        offset = i * bit_step;    // if (verbose) fprintf(stdout, "main:  starting a new seek (monkey)\n");    begin.x_pos = 0;    begin.y_pos = 0;    begin.y_vel = 0;    end.x_pos = offset;    end.y_pos = 0;    end.y_vel = 0;        /*    printf("begin = %d, end = %d\n",	   begin.y_vel, end.y_vel);    */    x_seek_time = mems_seek_time(&(dev->sled[0]),				  &begin, &end,				  NULL, NULL,				  NULL, NULL);    begin.x_pos = 0;    begin.y_pos = 0;    begin.y_vel = dev->sled[0].y_access_speed_bit_s;        end.x_pos = 0;    end.y_pos = offset;    end.y_vel = dev->sled[0].y_access_speed_bit_s;    /*    printf("begin = %d, end = %d\n",	   begin.y_pos, end.y_pos);    */    y_seek_time = mems_seek_time(&(dev->sled[0]),				  &begin, &end,				  NULL, NULL,				  NULL, NULL);    /*    fprintf(stdout, "%d, %d, %d, %f, %f\n",	    i, (i * nm_step), (offset * dev->sled[0].bit_length_nm), x_seek_time, y_seek_time);    */    dev->precompute_seek_distances[i] = offset * dev->sled[0].bit_length_nm;    dev->precompute_x_seek_times[i]   = x_seek_time;    dev->precompute_y_seek_times[i]   = y_seek_time;    /*    fprintf(stdout, "%d, %d, %f, %f\n",	    i, (offset * dev->sled[0].bit_length_nm),	    dev->precompute_x_seek_times[i],	    dev->precompute_y_seek_times[i]);    */  }  begin.x_pos = 0;  begin.y_pos = 0;  begin.y_vel = 0;    end.x_pos = sled_length_bits;  end.y_pos = 0;  end.y_vel = 0;  x_seek_time = mems_seek_time(&(dev->sled[0]),				&begin, &end,				NULL, NULL,				NULL, NULL);    begin.x_pos = 0;  begin.y_pos = 0;  begin.y_vel = dev->sled[0].y_access_speed_bit_s;    end.x_pos = 0;  end.y_pos = sled_length_bits;  end.y_vel = dev->sled[0].y_access_speed_bit_s;    y_seek_time = mems_seek_time(&(dev->sled[0]),				&begin, &end,				NULL, NULL,				NULL, NULL);    dev->precompute_seek_distances[precompute_seek_count] = sled_length_bits * dev->sled[0].bit_length_nm;  dev->precompute_x_seek_times[precompute_seek_count]   = x_seek_time;  dev->precompute_y_seek_times[precompute_seek_count]   = y_seek_time;  /*  fprintf(stdout, "%d, %d, %d, %f, %f\n",	  precompute_seek_count, (precompute_seek_count * nm_step), sled_length_bits * dev->sled[0].bit_length_nm, x_seek_time, y_seek_time);  */  dev->sled[0].num_time_constants = num_time_constants;  dev->precompute_seek_count = precompute_seek_count;}

⌨️ 快捷键说明

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