📄 disksim_diskctlr.c
字号:
/* * DiskSim Storage Subsystem Simulation Environment (Version 3.0) * Revision Authors: John Bucy, Greg Ganger * Contributors: John Griffin, Jiri Schindler, Steve Schlosser * * Copyright (c) of Carnegie Mellon University, 2001, 2002, 2003. * * 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 "disksim_global.h"#include "disksim_iosim.h"#include "disksim_stat.h"#include "disksim_disk.h"#include "disksim_ioqueue.h"#include "disksim_bus.h"#include "inline.h"/* internal functions, to avoid function ordering warnings */static void disk_buffer_sector_done (disk *currdisk, ioreq_event *curr);static void disk_buffer_seekdone (disk *currdisk, ioreq_event *curr);int disk_enablement_function (ioreq_event *currioreq);static void disk_got_remapped_sector (disk *currdisk, ioreq_event *curr);static void disk_check_bus (disk *currdisk, diskreq *currdiskreq);static void disk_release_hda (disk *currdisk, diskreq *currdiskreq);static void disk_check_hda (disk *currdisk, diskreq *currdiskreq, int ok_to_check_bus);static ioreq_event* disk_buffer_transfer_size (disk *currdisk, diskreq *currdiskreq, ioreq_event *curr);static void disk_activate_read (disk *currdisk, diskreq *currdiskreq, int setseg, int ok_to_check_bus);static void disk_activate_write (disk *currdisk, diskreq *currdiskreq, int setseg, int ok_to_check_bus);static double disk_buffer_estimate_acctime(disk *currdisk, ioreq_event *curr, double maxtime);int disk_set_depth(int diskno, int inbusno, int depth, int slotno){ disk *currdisk = getdisk (diskno); int cnt; cnt = currdisk->numinbuses; currdisk->numinbuses++; ddbg_assert3(((cnt + 1) <= MAXINBUSES), ("Too many inbuses specified for disk %d - %d\n", diskno, (cnt+1))); currdisk->inbuses[cnt] = inbusno; currdisk->depth[cnt] = depth; currdisk->slotno[cnt] = slotno; return(0);}int disk_get_depth (int diskno){ disk *currdisk = getdisk (diskno); return(currdisk->depth[0]);}int disk_get_slotno (int diskno){ disk *currdisk = getdisk (diskno); return(currdisk->slotno[0]);}int disk_get_inbus (int diskno){ disk *currdisk = getdisk (diskno); return(currdisk->inbuses[0]);}int disk_get_maxoutstanding (int diskno){ disk *currdisk = getdisk (diskno); return(currdisk->maxqlen);}double disk_get_blktranstime (ioreq_event *curr){ disk *currdisk = getdisk (curr->devno); double tmptime; tmptime = bus_get_transfer_time(disk_get_busno(curr), 1, (curr->flags & READ)); if(tmptime < currdisk->blktranstime) { tmptime = currdisk->blktranstime; } return(tmptime);}INLINE int disk_get_busno (ioreq_event *curr){ disk *currdisk = getdisk (curr->devno); intchar busno; int depth; busno.value = curr->busno; depth = currdisk->depth[0]; return(busno.byte[depth]);}/* **- disk_send_event_up_path Acquires the bus (if not already acquired), then uses bus_delay to send the event up the path. If the bus is already owned by this device or can be acquired immediately (interleaved bus), the event is sent immediately. Otherwise, disk_bus_ownership_grant will later send the event. */ static void disk_send_event_up_path (ioreq_event *curr, double delay){ disk *currdisk = getdisk (curr->devno); int busno; int slotno; /* fprintf (outputfile, "Disk_send_event_up_path - devno %d, type %d, cause %d, blkno %d\n", curr->devno, curr->type, curr->cause, curr->blkno); */ busno = disk_get_busno(curr); slotno = currdisk->slotno[0]; /* Put new request at head of buswait queue */ curr->next = currdisk->buswait; currdisk->buswait = curr; curr->tempint1 = busno; curr->time = delay; if(currdisk->busowned == -1) { /* fprintf (outputfile, "Must get ownership of the bus first\n"); */ if(curr->next) { fprintf(stderr,"Multiple bus requestors detected in " "disk_send_event_up_path\n"); /* Is this OK? Strange that the new requester is put on the head? */ } if(bus_ownership_get(busno, slotno, curr) == FALSE) { /* Remember when we started waiting (only place this is written) */ currdisk->stat.requestedbus = simtime; } else { bus_delay(busno, DEVICE, curr->devno, delay, curr); /* Never for SCSI */ } } else if(currdisk->busowned == busno) { /* fprintf (outputfile, "Already own bus - so send it on up\n"); */ bus_delay(busno, DEVICE, curr->devno, delay, curr); } else { ddbg_assert2(0, "Wrong bus owned for transfer desired"); }}/* * disk_bus_ownership_grant * * Calls bus_delay to handle the event that the disk has been granted * the bus. I believe this is always initiated by a call to * disk_send_even_up_path. */void disk_bus_ownership_grant(int devno, ioreq_event *curr, int busno, double arbdelay){ disk *currdisk = getdisk (devno); ioreq_event *tmp; tmp = currdisk->buswait; while ((tmp != NULL) && (tmp != curr)) { tmp = tmp->next; } ddbg_assert3(tmp != 0, ("Bus ownership granted to unknown disk request - " "devno %d, busno %d", devno, busno)); currdisk->busowned = busno; currdisk->stat.waitingforbus += simtime - currdisk->stat.requestedbus; ddbg_assert(arbdelay == (simtime - currdisk->stat.requestedbus)); currdisk->stat.numbuswaits++; bus_delay(busno, DEVICE, devno, tmp->time, tmp);}void disk_bus_delay_complete(int devno, ioreq_event *curr, int sentbusno){ disk *currdisk = getdisk (devno); intchar slotno; intchar busno; int depth; /* * fprintf (outputfile, "Entered disk_bus_delay_complete\n"); */ if(curr == currdisk->buswait) { currdisk->buswait = curr->next; } else { ioreq_event *tmp = currdisk->buswait; while ((tmp->next != NULL) && (tmp->next != curr)) { tmp = tmp->next; } ddbg_assert3(tmp->next == curr, ("Bus delay complete for unknown disk " "request - devno %d, busno %d", devno, busno.value)); tmp->next = curr->next; } busno.value = curr->busno; slotno.value = curr->slotno; depth = currdisk->depth[0]; slotno.byte[depth] = slotno.byte[depth] >> 4; curr->time = 0.0; if(depth == 0) { intr_request ((event *)curr); } else { bus_deliver_event(busno.byte[depth], slotno.byte[depth], curr); }}static void disk_prepare_for_data_transfer(ioreq_event *curr){ disk *currdisk = getdisk(curr->devno); diskreq *currdiskreq = curr->ioreq_hold_diskreq; /* fprintf (outputfile, "%f, Entering disk_prepare_for_data_transfer: diskno = %d\n", simtime, curr->devno); */ if(currdiskreq->flags & FINAL_WRITE_RECONNECTION_1) { currdiskreq->flags |= FINAL_WRITE_RECONNECTION_2; } addtoextraq((event *) curr); disk_check_bus(currdisk,currdiskreq);}/* check to see if current prefetch should be aborted */static void disk_check_prefetch_swap (disk *currdisk){ ioreq_event *nextioreq; diskreq *nextdiskreq; int setseg = FALSE; if(disk_printhack && (simtime >= disk_printhacktime)) { fprintf (outputfile, "%12.6f Entering disk_check_prefetch_swap for disk %d\n", simtime, currdisk->devno); fflush(outputfile); } ddbg_assert(currdisk->effectivehda != 0); ddbg_assert(currdisk->effectivehda->seg != 0); { int ispureprefetch = (currdisk->effectivehda->seg->access->flags & BUFFER_BACKGROUND) && (currdisk->effectivehda->seg->access->flags & READ); ddbg_assert2(ispureprefetch, "effectivehda->seg->access is not a pure " "prefetch"); } nextioreq = ioqueue_show_next_request(currdisk->queue); if(nextioreq) { nextdiskreq = nextioreq->ioreq_hold_diskreq; if(!nextdiskreq->seg) { setseg = TRUE; disk_buffer_select_segment(currdisk,nextdiskreq,FALSE); } if(nextioreq->flags & READ) { disk_activate_read(currdisk,nextdiskreq,setseg,TRUE); } else { disk_activate_write(currdisk,nextdiskreq,setseg,TRUE); } }}/* send completion up the line */static void disk_request_complete(disk *currdisk, diskreq *currdiskreq, ioreq_event *curr){ ioreq_event *tmpioreq = currdiskreq->ioreqlist; diskreq *nextdiskreq; double delay; if(disk_printhack && (simtime >= disk_printhacktime)) { fprintf (outputfile, "%12.6f %8p " " Entering disk_request_complete\n", simtime, currdiskreq); fflush(outputfile); } // printf("disk_request_complete %f\n", simtime); ddbg_assert(currdisk->effectivebus == currdiskreq); if(curr->blkno != tmpioreq->blkno) { addtoextraq((event *) curr); curr = ioreq_copy(tmpioreq); } currdisk->lastflags = curr->flags; ddbg_assert(currdisk->outstate == DISK_TRANSFERING); currdiskreq->flags |= COMPLETION_SENT; if(currdisk->const_acctime) { ddbg_assert2(!(currdiskreq->flags & HDA_OWNED), "HDA_OWNED set for fixed-access-time disk"); ddbg_assert2(ioqueue_get_specific_request(currdisk->queue,tmpioreq), "ioreq_event not found"); disk_interferestats(currdisk, tmpioreq); /* GROK: this would seem to leak (or worse) for concatenating schedulers */ ddbg_assert2(ioqueue_physical_access_done(currdisk->queue,tmpioreq), "ioreq_event not found"); currdisk->currentbus = currdisk->currenthda = currdisk->effectivehda = NULL; tmpioreq = ioqueue_show_next_request(currdisk->queue); if(tmpioreq) { nextdiskreq = (diskreq*) tmpioreq->ioreq_hold_diskreq; if(nextdiskreq->ioreqlist->flags & READ) { disk_activate_read(currdisk, nextdiskreq, FALSE, TRUE); } else { disk_activate_write(currdisk, nextdiskreq, FALSE, TRUE); } } } else if(tmpioreq->flags & READ) { while (tmpioreq) { int evtfound = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -