RF_DiskQueueData_t * rf_CvscanDequeue(void *q_in) { RF_CvscanHeader_t *hdr = (RF_CvscanHeader_t *) q_in; long range, i, sum_dist_left, sum_dist_right; RF_DiskQueueData_t *ret; RF_DiskQueueData_t *tmp; DO_CHECK_STATE(hdr); if (hdr->left_cnt == 0 && hdr->right_cnt == 0) return ((RF_DiskQueueData_t *) NULL); range = RF_MIN(hdr->range_for_avg, RF_MIN(hdr->left_cnt, hdr->right_cnt)); for (i = 0, tmp = hdr->left, sum_dist_left = ((hdr->direction == rf_cvscan_RIGHT) ? range * hdr->change_penalty : 0); tmp != (RF_DiskQueueData_t *) NULL && i < range; tmp = tmp->next, i++) { sum_dist_left += hdr->cur_block - tmp->sectorOffset; } for (i = 0, tmp = hdr->right, sum_dist_right = ((hdr->direction == rf_cvscan_LEFT) ? range * hdr->change_penalty : 0); tmp != (RF_DiskQueueData_t *) NULL && i < range; tmp = tmp->next, i++) { sum_dist_right += tmp->sectorOffset - hdr->cur_block; } if (hdr->right_cnt == 0 || sum_dist_left < sum_dist_right) { hdr->direction = rf_cvscan_LEFT; hdr->cur_block = hdr->left->sectorOffset + hdr->left->numSector; hdr->left_cnt = RF_MAX(hdr->left_cnt - 1, 0); tmp = hdr->left; ret = (ReqDequeue(&hdr->left)) /*->parent*/ ; } else { hdr->direction = rf_cvscan_RIGHT; hdr->cur_block = hdr->right->sectorOffset + hdr->right->numSector; hdr->right_cnt = RF_MAX(hdr->right_cnt - 1, 0); tmp = hdr->right; ret = (ReqDequeue(&hdr->right)) /*->parent*/ ; } ReBalance(hdr); if (hdr->left_cnt == 0 && hdr->right_cnt == 0 && hdr->burner != (RF_DiskQueueData_t *) NULL) { /* ** restore low priority requests for next dequeue */ RF_DiskQueueData_t *burner = hdr->burner; hdr->nxt_priority = burner->priority; while (burner != (RF_DiskQueueData_t *) NULL && burner->priority == hdr->nxt_priority) { RF_DiskQueueData_t *next = burner->next; RealEnqueue(hdr, burner); burner = next; } hdr->burner = burner; } DO_CHECK_STATE(hdr); return (ret); }
void * rf_CvscanCreate(RF_SectorCount_t sectPerDisk, RF_AllocListElem_t * clList, RF_ShutdownList_t ** listp) { RF_CvscanHeader_t *hdr; long range = 2; /* Currently no mechanism to change these */ long penalty = sectPerDisk / 5; RF_MallocAndAdd(hdr, sizeof(RF_CvscanHeader_t), (RF_CvscanHeader_t *), clList); bzero((char *) hdr, sizeof(RF_CvscanHeader_t)); hdr->range_for_avg = RF_MAX(range, 1); hdr->change_penalty = RF_MAX(penalty, 0); hdr->direction = rf_cvscan_RIGHT; hdr->cur_block = 0; hdr->left_cnt = hdr->right_cnt = 0; hdr->left = hdr->right = (RF_DiskQueueData_t *) NULL; hdr->burner = (RF_DiskQueueData_t *) NULL; DO_CHECK_STATE(hdr); return ((void *) hdr); }
void rf_crunch_list(RF_ReconMap_t *mapPtr, RF_ReconMapListElem_t *listPtr) { RF_ReconMapListElem_t *pt, *p = listPtr; if (!p) return; pt = p; p = p->next; while (p) { if (pt->stopSector >= p->startSector - 1) { pt->stopSector = RF_MAX(pt->stopSector, p->stopSector); pt->next = p->next; rf_FreeReconMapListElem(mapPtr, p); p = pt->next; } else { pt = p; p = p->next; } } }
/* Updates the size fields of a status descriptor. */ void rf_update_size(RF_ReconMap_t *mapPtr, int size) { mapPtr->size += size; mapPtr->maxSize = RF_MAX(mapPtr->size, mapPtr->maxSize); }