?? mech_g1.c
字號:
/* diskmodel (version 1.0) * 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. *//* * DiskSim Storage Subsystem Simulation Environment (Version 2.0) * Revision Authors: Greg Ganger * Contributors: Ross Cohen, John Griffin, Steve Schlosser * * Copyright (c) of Carnegie Mellon University, 1999. * * Permission to reproduce, use, and prepare derivative works of * this software for internal use is granted provided the copyright * and "No Warranty" statements are included with all reproductions * and derivative works. 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. *//* * DiskSim Storage Subsystem Simulation Environment * Authors: Greg Ganger, Bruce Worthington, Yale Patt * * Copyright (C) 1993, 1995, 1997 The Regents of the University of Michigan * * 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 use, copy, modify, distribute, and sell this software * and its documentation for any purpose and without fee or royalty is * hereby granted, provided that the full text of this NOTICE appears on * ALL copies of the software and documentation or portions thereof, * including modifications, that you make. * * THIS SOFTWARE IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, * BUT NOT LIMITATION, COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR * WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR * THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY * THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. COPYRIGHT * HOLDERS WILL BEAR NO LIABILITY FOR ANY USE OF THIS SOFTWARE OR * DOCUMENTATION. * * This software is provided AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESSED OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS * OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR ANY DAMAGES, * INCLUDING SPECIAL , INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, * WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN CONNECTION WITH THE * USE OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS * BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH DAMAGES * * The names and trademarks of copyright holders or authors may NOT be * used in advertising or publicity pertaining to the software without * specific, written prior permission. Title to copyright in this software * and any associated documentation will at all times remain with copyright * holders. */#include "dm_config.h"#include "dm.h"#include "marshal.h"#include "mech_g1.h"#include "mech_g1_private.h"// Port of first generation (disksim) disk mechanics implementationstatic dm_time_t dm_seek_time_g1(struct dm_disk_if *d, struct dm_mech_state *start_track, struct dm_mech_state *end_track, int rw){ struct dm_mech_g1 *m = (struct dm_mech_g1 *)d->mech; dm_time_t seektime, hst, result = 0; seektime = m->seekfn(d,start_track,end_track,rw); // seektime -= 700 * DM_TIME_USEC; hst = m->hdr.dm_headswitch_time(d,start_track->head,end_track->head); result = hst > seektime ? hst : seektime; if((result != 0) && (rw == 0)) { result += m->seekwritedelta; } return result;}// computes how long to reposition from the first head position to// the second// does not change the state of the diskstatic dm_time_t dm_pos_time_g1(struct dm_disk_if *d, struct dm_mech_state *initial, struct dm_pbn *start, int len, int rw, int immed, struct dm_mech_acctimes *breakdown){ dm_angle_t seekrotate; struct dm_mech_state end_track, state = *initial; dm_time_t seektime = 0; dm_time_t result = 0; dm_time_t latency = 0; // struct dm_mech_g1 *m = (struct dm_mech_g1 *)d->mech; end_track.head = start->head; end_track.cyl = start->cyl; seektime = d->mech->dm_seek_time(d, &state, &end_track, rw); state.head = start->head; state.cyl = start->cyl; // advance the angle by how far we rotated during the seek seekrotate = d->mech->dm_rotate(d, &seektime); state.theta += seekrotate; // initial rotational latency given our new position latency = d->mech->dm_latency(d, &state, start->sector, len, immed, 0); result = seektime + latency; if(breakdown) { breakdown->seektime = seektime; breakdown->initial_latency = latency; breakdown->initial_xfer = 0; breakdown->addl_latency = 0; breakdown->addl_xfer = 0; } return result;}// computes the access time for an access time on a single trackstatic dm_time_t dm_acctime_track(struct dm_disk_if *d, struct dm_mech_state *istate, struct dm_pbn *start, int len, int rw, int immed, struct dm_mech_state *result_state, struct dm_mech_acctimes *breakdown){ // struct dm_mech_state start_track; struct dm_mech_state temp; // struct dm_pbn seekdest; struct dm_mech_state state = *istate; dm_time_t seektime, latency, xfertime, initxfer; dm_time_t addtolatency = 0, result = 0, *atlp; // start by seeking/headswitching/writesettling temp.cyl = start->cyl; temp.head = start->head; seektime = d->mech->dm_seek_time(d, &state, &temp, rw); // we're on track now state.head = start->head; state.cyl = start->cyl; // advance the angle by how far we rotated during the seek temp.theta = d->mech->dm_rotate(d, &seektime); state.theta += temp.theta; // initial rotational latency given our new position atlp = immed ? &addtolatency : 0; latency = d->mech->dm_latency(d, &state, start->sector, len, immed, atlp); // if zero-latency access, add intermediate rotational latency latency += immed ? *atlp : 0; // data transfer xfertime = d->mech->dm_xfertime(d, &state, len); result = seektime + latency + xfertime; if(result_state) { result_state->head = start->head; result_state->cyl = start->cyl; result_state->theta = istate->theta; result_state->theta += d->mech->dm_rotate(d, &result); } // little gross; need to break down the xfertime for zero-latency access if(immed) { int firstsect = d->mech->dm_access_block(d, &state, start->sector, len, immed); initxfer = d->mech->dm_xfertime(d, &state, len - firstsect + 1); } else { initxfer = xfertime; } if(breakdown) { breakdown->seektime = seektime; breakdown->initial_latency = latency - addtolatency; breakdown->initial_xfer = initxfer; breakdown->addl_latency = addtolatency; breakdown->addl_xfer = xfertime - initxfer; } return result;}// Note that this is an ESTIMATE and if there are defects,// the result here will be SMALLER than the correct value.// This works for accesses spanning multiple tracks. In this case,// the access time breakdown is as follows: single track// accesses are normal. Multi-track accesses// report the initial seek and rotation as the positioning time// before the first transfer begins. All additional xfertime // and postime is reported as initial transfer time.static dm_time_t dm_acctime_g1(struct dm_disk_if *d, struct dm_mech_state *istate, struct dm_pbn *start, int len, int rw, int immed, struct dm_mech_state *result_state, struct dm_mech_acctimes *breakdown){ struct dm_pbn pbn = *start; int lbnhigh; // highest lbn on the current track int l; // first lbn to read int lastlbn; // last lbn to read struct dm_mech_state s = *istate; struct dm_mech_state s2; dm_time_t result = 0; if(breakdown) { breakdown->seektime = 0; breakdown->initial_latency = 0; breakdown->initial_xfer = 0; breakdown->addl_latency = 0; breakdown->addl_xfer = 0; } // back translate the pbn l = d->layout->dm_translate_ptol(d, &pbn, 0); // last lbn we're going to read lastlbn = l+len-1; do { struct dm_mech_acctimes ibreak; // intermediate // l = d->layout->dm_translate_ptol(d, &pbn, 0); d->layout->dm_translate_ltop(d, l, MAP_FULL, &pbn, 0); d->layout->dm_get_track_boundaries(d, &pbn, 0, // first lbn on track &lbnhigh, 0); // remapsector ddbg_assert((lbnhigh != DM_SLIPPED) && (lbnhigh != DM_REMAPPED)); if(lbnhigh > lastlbn) { lbnhigh = lastlbn; } // redundant?? // d->layout->dm_translate_ltop(d, l, MAP_FULL, &pbn, 0); // access from l to lbnhigh at each step result += dm_acctime_track(d, &s, &pbn, lbnhigh - l + 1, rw, immed, &s2, &ibreak); s = s2; l = lbnhigh + 1; if(breakdown) { if((pbn.cyl == start->cyl) && (pbn.head == start->head) && (pbn.sector == start->sector)) { breakdown->seektime = ibreak.seektime; breakdown->initial_latency = ibreak.initial_latency; breakdown->initial_xfer = ibreak.initial_xfer; if(lbnhigh == lastlbn) { // single track access breakdown->addl_latency = ibreak.addl_latency; breakdown->addl_xfer = ibreak.addl_xfer; } else { breakdown->initial_xfer += ibreak.addl_latency; breakdown->initial_xfer += ibreak.addl_xfer; } } else {/* breakdown->initial_xfer += ibreak.seektime; *//* breakdown->initial_xfer += ibreak.initial_latency; *//* breakdown->initial_xfer += ibreak.initial_xfer; *//* breakdown->initial_xfer += ibreak.addl_latency; *//* breakdown->initial_xfer += ibreak.addl_xfer; */ } } } while(lastlbn > lbnhigh); return result;}// compute the rotational latency incurred for the given// (possibly "zero-latency") accessstatic dm_time_t dm_latency_g1(struct dm_disk_if *d, struct dm_mech_state *begin, int start_sect, int len, int immed, dm_time_t *addtolatency){ struct dm_pbn tmppbn; int sectors; // dm_angle_t trackstart; dm_angle_t start, end; dm_angle_t theta = begin->theta; // rotational position of the disk dm_time_t result; // dm_time_t period = d->mech->dm_period(d); tmppbn.head = begin->head; tmppbn.cyl = begin->cyl; tmppbn.sector = 0; // XXX sector may make a difference to g4 layout! sectors = d->layout->dm_get_sectors_pbn(d, &tmppbn); ddbg_assert(len <= sectors); tmppbn.head = begin->head; tmppbn.cyl = begin->cyl; tmppbn.sector = start_sect; start = d->layout->dm_pbn_skew(d, &tmppbn); // printf("%s() skew %f\n", __func__, dm_angle_itod(start)); // non-zero-latency if(!immed) { // printf("mech_g1::latency skew = %f distance = %f\n", // dm_angle_itod(start), dm_angle_itod(start - theta)); // rottime does the Right Thing if theta > start result = d->mech->dm_rottime(d, theta, start); if(addtolatency) { *addtolatency = 0; } return result; } else { dm_angle_t extra = 0; tmppbn.sector = (start_sect + len - 1); // % sectors; if(tmppbn.sector >= sectors) { tmppbn.sector = sectors - 1; } // d->layout->dm_convert_ptoa(d, &tmppbn, &end, 0); end = d->layout->dm_pbn_skew(d, &tmppbn); // head is outside of the access if(((theta <= start) && (start < end)) || ( (end < theta) && (theta <= start) ) || ( (start < end) && (end <= theta)) || (tmppbn.sector == start_sect)) { extra = 0; } // head is in the middle of the access else { tmppbn.head = begin->head; tmppbn.cyl = begin->cyl; tmppbn.sector = d->mech->dm_access_block(d, begin, start_sect, len, immed); start = d->layout->dm_pbn_skew(d, &tmppbn); if(len != sectors) { int extrasectors = sectors - len; struct dm_pbn tmppbn2; tmppbn2.head = begin->head; tmppbn2.cyl = begin->cyl; tmppbn2.sector = extrasectors; extra = d->layout->dm_get_sector_width(d, &tmppbn2, extrasectors); ddbg_assert(extra != 0); } else { extra = 0; }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -