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

📄 mems_mapping.c

📁 disksim是一个非常优秀的磁盘仿真工具
💻 C
字号:
/* * 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_mapping.c * * Functions to map logical block numbers to physical locations on * the memsdevice. */#include "mems_global.h"#include "mems_mapping.h"mems_sled_t *mems_lbn_to_sled (mems_t *dev, int lbn){  /* This function determines to which sled a particular request maps,   * and returns that sled number [0 through N-1].   *   * This function may (easily) be extended to support data   * replication -- need to add support in mems_request_arrive   * in order to do this.   */  int i;  if (lbn < 0 || lbn >= dev->numblocks) {    fprintf(stderr, "LBN %d outside valid range (%d)\n", lbn, dev->numblocks);    exit(1);  }  /* The obvious case: only one sled */  if (dev->num_sleds == 1) return &dev->sled[0];  /* Simple division:   * If there are 100 sectors across 4 sleds, they are divided as:   *	 0-24	sled 0   *	25-49	sled 1   *	50-74	sled 2   *	75-99	sled 3   */  for (i = 0; i < dev->num_sleds; i++) {    int sled_lastblock = (i+1) * dev->numblocks / dev->num_sleds - 1;    if (lbn <= sled_lastblock) break;  }  // fprintf(stderr, "LBN %d maps to sled %d (numblocks=%d, num_sleds=%d)\n", lbn, i, dev->numblocks, dev->num_sleds);  return &dev->sled[i];}/* Terminology time. * * A "cell" is the set of tipsectors used to read a block.  Example: * If the sled is at <0,0> and you turn on 64 tips to read block 0, * the 64 tipsectors read form a "cell". * * A "row" is a group of cells that can be read simultaneously. * Example:  If the sled is at <0,0> and you can turn on 640 tips * simultaneously, then you have a "row" of 10 cells. * * A "column" is a group of rows that can be read in a single sweep * of the sled.  If there are 5 columns, then it takes 5 sweeps to * read all the data in a cylinder (e.g., all the data at a given * X offset). */static inline int rows_per_column (mems_sled_t *sled) {  return     (sled->y_length_nm / sled->bit_length_nm - sled->servo_burst_length_bits)    / (sled->servo_burst_length_bits + sled->tip_sector_length_bits);}static inline int columns_per_cylinder (mems_sled_t *sled) {  return sled->tips_usable / sled->tips_simultaneous;}static inline int cells_per_row (mems_sled_t *sled) {  return sled->tips_simultaneous / sled->tip_sectors_per_lbn;}static inline int cells_per_column (mems_sled_t *sled) {  return cells_per_row(sled) * rows_per_column(sled);}static inline int cells_per_cylinder (mems_sled_t *sled) {  return cells_per_column(sled) * columns_per_cylinder(sled);}static inline void shift_coordset (tipsector_coord_set_t *cs, mems_sled_t *sled){  int x_shift = sled->x_length_nm / sled->bit_length_nm / 2;  int y_shift = (rows_per_column(sled) * (sled->servo_burst_length_bits + sled->tip_sector_length_bits) + sled->servo_burst_length_bits) / 2;  /* Shift the X position right by (num_cylinders/2) */  cs->servo_start.x_pos     -= x_shift;  cs->tipsector_start.x_pos -= x_shift;  cs->tipsector_end.x_pos   -= x_shift;  /* Shift the Y position up.  This uses a slightly more complicated   * formula (FIXME: explain it!) */  cs->servo_start.y_pos     -= y_shift;  cs->tipsector_start.y_pos -= y_shift;  cs->tipsector_end.y_pos   -= y_shift;}voidmems_lbn_to_position (int lbn,		      mems_sled_t *sled,		      tipsector_coord_set_t *up,		      tipsector_coord_set_t *dn,		      tipset_t *tipset,		      int *cylptr, int *surfaceptr, int *blkptr){  /* This function maps a logical block number to a set of starting   * and ending coordinates and velocities. */  int locallbn            = lbn % sled->numblocks;  int y_access_speed_nm_s = sled->y_access_speed_bit_s * sled->bit_length_nm;  int cylinder;  int column;  int row;  int cell;  cylinder =  locallbn / cells_per_cylinder(sled);  column   = (locallbn % cells_per_cylinder(sled)) / cells_per_column(sled);  row      = (locallbn % cells_per_column(sled)) / cells_per_row(sled);  cell     =  locallbn % cells_per_row(sled);    /* X position is always the cylinder number */  up->servo_start.x_pos = up->tipsector_start.x_pos = up->tipsector_end.x_pos = cylinder;  dn->servo_start.x_pos = dn->tipsector_start.x_pos = dn->tipsector_end.x_pos = cylinder;    /* Velocity is always positive in "up" direction, negative in "dn" */  up->servo_start.y_vel = up->tipsector_start.y_vel = up->tipsector_end.y_vel = y_access_speed_nm_s;  dn->servo_start.y_vel = dn->tipsector_start.y_vel = dn->tipsector_end.y_vel = -y_access_speed_nm_s;    /* Row inversion:   * Rows are inverted on odd-numbered columns because of the   * streaming nature of the layout:   *   *       cylinder0   *    col0  col1  col2   *    ----  ----  ----   *    row0  row2  row0   *    row1  row1  row1   *    row2  row0  row2   *   * However, if [and only if] columns_per_cylinder() is odd,   * the even-numbered columns should be inverted instead:   *   *                          cylinder1   *                       col0  col1  col2   *                       ----  ----  ----   *                       row0  row2  row0   *                       row1  row1  row1   *                       row2  row0  row2   *   * In this example, you can immediately turn around from   * cyl0/col2/row2 and start streaming from cyl1/col0/row0.   */    if (sled->layout_policy == MEMS_LAYOUT_STREAMING) {    if (columns_per_cylinder(sled) % 2) {      if (cylinder % 2) {	/* odd cylinder, so invert even-numbered columns */	if (!(column % 2)) row = rows_per_column(sled) - row - 1;      } else {	/* even cylinder, so invert odd-numbered columns */	if (column % 2) row = rows_per_column(sled) - row - 1;      }    } else {      /* always invert odd-numbered columns */      if (column % 2) row = rows_per_column(sled) - row - 1;    }  }    /* Calculate the "up" Y positions */  up->servo_start.y_pos = row * (sled->servo_burst_length_bits + sled->tip_sector_length_bits);  up->tipsector_start.y_pos = up->servo_start.y_pos + sled->servo_burst_length_bits;  up->tipsector_end.y_pos = up->tipsector_start.y_pos + sled->tip_sector_length_bits;    /* Calculate the "dn" Y positions based on the "up" positions */  dn->servo_start.y_pos = up->tipsector_end.y_pos + sled->servo_burst_length_bits;  dn->tipsector_start.y_pos = up->tipsector_end.y_pos;  dn->tipsector_end.y_pos = up->tipsector_start.y_pos;    /* Tipset found by [offset in current column] + [column shift] */  tipset->tip_start = cell * sled->tip_sectors_per_lbn + column * sled->tips_simultaneous;  tipset->tip_end = tipset->tip_start + sled->tip_sectors_per_lbn - 1;  tipset->num_tips = tipset->tip_end - tipset->tip_start + 1;    /* Finally, "shift" the positions so the sled is centered on [0,0] */  shift_coordset(up, sled);  shift_coordset(dn, sled);    /* Note: These must be -below- the row inversion above! */  if (cylptr) *cylptr = cylinder;  if (surfaceptr) *surfaceptr = column;  if (blkptr) *blkptr = row * cells_per_row(sled) + cell;}intmems_get_number_of_cylinders (mems_t *dev){  return dev->sled[0].x_length_nm / dev->sled[0].bit_length_nm;}intmems_get_blocks_per_cylinder (mems_sled_t *sled){  return cells_per_cylinder(sled);}voidmems_check_numblocks (mems_t *dev) {  int numcylinders = mems_get_number_of_cylinders(dev);  int numblocks = cells_per_cylinder(&dev->sled[0]) * numcylinders * dev->num_sleds;  int i;  if (dev->numblocks == 0) {	/* Set numblocks here */    dev->numblocks = numblocks;    for (i = 0; i < dev->num_sleds; i++) dev->sled[i].numblocks = numblocks / dev->num_sleds;    /*    fprintf(stderr, "Setting dev->numblocks = %d, sled->numblocks = %d\n", dev->numblocks, dev->sled[0].numblocks);    */  } else {	/* Check numblocks and warn if necessary */    if (dev->numblocks != numblocks) {      fprintf(stderr, "Warning: dev->numblocks inconsistent (spec: %d, actual: %d)\n", dev->numblocks, numblocks);    }    for (i = 0; i < dev->num_sleds; i++) {      if (dev->sled[i].numblocks != numblocks / dev->num_sleds) {	fprintf(stderr, "Warning: sled[%d]->numblocks inconsistent (spec: %d, actual: %d)\n", i, dev->sled[i].numblocks, numblocks / dev->num_sleds);      }    }  }  return;}intmems_centermost_lbn (mems_sled_t * sled) {  /* Horiz offset = (x_length_bits / 2) times cells_per_cylinder */  /* Vertical offset = 1/2 cells_per_cylinder */  int horiz_offset = (sled->x_length_nm / sled->bit_length_nm / 2) * cells_per_cylinder(sled);  int vert_offset = cells_per_cylinder(sled) / 2;  return horiz_offset + vert_offset;}

⌨️ 快捷键说明

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