📄 disksim_ctlrsmart.c
字号:
if (currctlr->hostwaiters) {
curr->next = currctlr->hostwaiters->next;
currctlr->hostwaiters->next = curr;
} else {
curr->next = curr;
}
currctlr->hostwaiters = curr;
return;
}
/* Time for DMA */
curr->time = simtime + ((double) curr->bcount * currctlr->blktranstime);
currctlr->hosttransfer = TRUE;
addtointq((event *) curr);
}
static void controller_smart_request_arrive (controller *currctlr, ioreq_event *curr)
{
/*
fprintf (outputfile, "Request arrived at smart controller: devno %d, blkno %d, flags %x\n", curr->devno, curr->blkno, curr->flags);
*/
/* Cache will call "done" function if cache access doesn't block */
cache_get_block(currctlr->cache, curr, &disksim->donefunc_ctlrsmart_read, currctlr);
}
static void controller_smart_access_complete (controller *currctlr, ioreq_event *curr)
{
struct ioq *queue = currctlr->devices[curr->devno].queue;
ioreq_event *done = ioreq_copy(curr);
int devno = curr->devno;
int numout;
/* Responds to completion interrupt */
done->type = IO_INTERRUPT_COMPLETE;
currctlr->outbusowned = controller_get_downward_busno(currctlr, done, NULL);
controller_send_event_down_path(currctlr, done, currctlr->ovrhd_disk_complete);
currctlr->outbusowned = -1;
/* Handles request completion, including call-backs into cache */
curr = ioqueue_physical_access_done(queue, curr);
while ((done = curr)) {
curr = curr->next;
/* call back into cache with completion -- let it do request_complete */
controller_smart_wakeup(currctlr, cache_disk_access_complete(currctlr->cache, done));
}
/* Initiate another request, if any pending */
numout = ioqueue_get_reqoutstanding(queue);
if ((numout < currctlr->devices[devno].maxoutstanding) && (curr = ioqueue_get_next_request(queue))) {
controller_send_event_down_path(currctlr, curr, currctlr->ovrhd_disk_request);
}
}
static void controller_smart_ready_to_transfer (controller *currctlr, ioreq_event *curr)
{
curr->type = IO_INTERRUPT_COMPLETE;
curr->cause = RECONNECT;
currctlr->outbusowned = controller_get_downward_busno(currctlr, curr, NULL);
controller_send_event_down_path(currctlr, curr, currctlr->ovrhd_disk_ready);
currctlr->outbusowned = -1;
}
static void controller_smart_disconnect (controller *currctlr, ioreq_event *curr)
{
curr->type = IO_INTERRUPT_COMPLETE;
currctlr->outbusowned = controller_get_downward_busno(currctlr, curr, NULL);
controller_send_event_down_path(currctlr, curr, currctlr->ovrhd_disk_disconnect);
currctlr->outbusowned = -1;
}
static void controller_smart_reconnect_to_transfer (controller *currctlr, ioreq_event *curr)
{
curr->type = IO_INTERRUPT_COMPLETE;
currctlr->outbusowned = controller_get_downward_busno(currctlr, curr, NULL);
controller_send_event_down_path(currctlr, curr, currctlr->ovrhd_disk_reconnect);
currctlr->outbusowned = -1;
}
static void controller_smart_interrupt_arrive (controller *currctlr, ioreq_event *curr)
{
switch (curr->cause) {
case COMPLETION:
controller_smart_access_complete(currctlr, curr);
break;
case RECONNECT:
controller_smart_reconnect_to_transfer(currctlr, curr);
break;
case DISCONNECT:
controller_smart_disconnect(currctlr, curr);
break;
case READY_TO_TRANSFER:
controller_smart_ready_to_transfer(currctlr, curr);
break;
default:
fprintf(stderr, "Unknown interrupt cause in smart_interrupt_arrive: %d\n", curr->cause);
exit(1);
}
}
static void controller_smart_interrupt_complete (controller *currctlr, ioreq_event *curr)
{
switch (curr->cause) {
case COMPLETION:
addtoextraq((event *) curr);
break;
default:
fprintf(stderr, "Unknown interrupt cause in smart_interrupt_complete: %d\n", curr->cause);
exit(1);
}
}
void controller_smart_event_arrive (controller *currctlr, ioreq_event *curr)
{
switch (curr->type) {
case IO_ACCESS_ARRIVE:
controller_smart_request_arrive(currctlr, curr);
break;
case IO_INTERRUPT_ARRIVE:
controller_smart_interrupt_arrive(currctlr, curr);
break;
case IO_INTERRUPT_COMPLETE:
controller_smart_interrupt_complete(currctlr, curr);
break;
case DEVICE_DATA_TRANSFER_COMPLETE:
controller_smart_disk_data_transfer(currctlr, curr);
break;
case CONTROLLER_DATA_TRANSFER_COMPLETE:
if (curr->tempptr1) {
controller_smart_disk_data_transfer_complete(currctlr, curr);
} else {
controller_smart_host_data_transfer_complete(currctlr, curr);
}
break;
case IO_QLEN_MAXCHECK:
curr->tempint1 = currctlr->ctlno;
curr->tempint2 = currctlr->maxoutstanding;
curr->bcount = cache_get_maxreqsize(currctlr->cache);
break;
default:
fprintf(stderr, "Unknown event type arriving at 53c700 controller: %d\n", curr->type);
exit(1);
}
}
void controller_smart_setcallbacks ()
{
disksim->issuefunc_ctlrsmart = controller_smart_issue_access;
disksim->queuefind_ctlrsmart = controller_smart_queuefind;
disksim->wakeupfunc_ctlrsmart = controller_smart_wakeup;
disksim->donefunc_ctlrsmart_read = controller_smart_host_data_transfer;
disksim->donefunc_ctlrsmart_write = controller_smart_request_complete;
ioqueue_setcallbacks ();
cache_setcallbacks ();
}
void controller_smart_initialize (controller *currctlr)
{
int numdevs = device_get_numdevices();
device *currdev;
int i;
controller_smart_setcallbacks ();
currctlr->numdevices = numdevs;
currctlr->devices = (device *) DISKSIM_malloc(numdevs * sizeof(device));
ASSERT(currctlr->devices != NULL);
for (i=0; i<numdevs; i++) {
currdev = &currctlr->devices[i];
currdev->devno = i;
currdev->busy = FALSE;
currdev->flag = 0;
currdev->queue = ioqueue_copy(currctlr->queue);
ioqueue_initialize(currdev->queue, i);
iosim_get_path_to_device (0, i, &currdev->buspath, &currdev->slotpath);
currdev->maxoutstanding = currctlr->maxdiskqsize;
}
cache_initialize(currctlr->cache, &disksim->issuefunc_ctlrsmart, currctlr, &disksim->queuefind_ctlrsmart, currctlr, &disksim->wakeupfunc_ctlrsmart, currctlr, numdevs);
}
void controller_smart_resetstats (controller *currctlr)
{
int numdevs = device_get_numdevices();
int i;
for (i=0; i<numdevs; i++) {
ioqueue_resetstats(currctlr->devices[i].queue);
}
cache_resetstats(currctlr->cache);
}
void controller_smart_printstats (controller *currctlr, char *prefix)
{
ctlrinfo_t *ctlrinfo = disksim->ctlrinfo;
int devno;
char devprefix[181];
struct ioq **queueset = DISKSIM_malloc (currctlr->numdevices * sizeof(void *));
if (ctlrinfo->ctl_printcachestats) {
cache_printstats(currctlr->cache, prefix);
}
for (devno=0; devno<currctlr->numdevices; devno++) {
queueset[devno] = currctlr->devices[devno].queue;
}
sprintf (devprefix, "%sdevices ", prefix);
ioqueue_printstats (queueset, currctlr->numdevices, devprefix);
if ((ctlrinfo->ctl_printperdiskstats) && (currctlr->numdevices > 1)) {
for (devno=0; devno<currctlr->numdevices; devno++) {
struct ioq *queue = currctlr->devices[devno].queue;
if (ioqueue_get_number_of_requests(queue)) {
sprintf(devprefix, "%sdevice #%d ", prefix, devno);
ioqueue_printstats(&queue, 1, devprefix);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -