rf_geometry.c
来自「RAIDFrame是个非常好的磁盘阵列RAID仿真工具」· C语言 代码 · 共 890 行 · 第 1/2 页
C
890 行
/* By first multiplying 'phys' by the sectors per track in the current zone divided by the sectors per track in the previous zone, we convert a given physical sector in one zone to an equivalent physical sector in another zone. */ phys = ((phys * z->zone.sec_per_track / previous_spt) + (((z->zone.num_sectors - 1) % z->zone.sec_per_track) + (z->zone.track_skew * z->zone.num_cylinders * disk->geom->tracks_per_cyl) + (long) ceil( (double) z->zone.sec_per_track * (disk->geom->seek_constant_coeff) / disk->geom->revolution_time) * z->zone.num_cylinders)) % z->zone.sec_per_track; previous_spt = z->zone.sec_per_track; z = z->next; } /* The final physical sector equals the physical sector up to the particular zone, plus the physical sector caused by the sector offset into this zone. */ phys = ((phys * z->zone.sec_per_track / previous_spt) + ((sector % z->zone.sec_per_track) + (z->zone.track_skew * (sector / z->zone.sec_per_track)) + (long) ceil( (RF_TICS_t) z->zone.sec_per_track * (disk->geom->seek_constant_coeff) / disk->geom->revolution_time) * (sector / (z->zone.sec_per_track * disk->geom->tracks_per_cyl)))) % z->zone.sec_per_track; return( phys );}/* ** When each disk starts up, its index mark is a fraction (f) of a rotation ** ahead from its heads (in the direction of rotation). The sector ** under its heads is at a fraction f of a rotation from the index ** mark. After T time has past, T/rotation_time revolutions have occured, so ** the sector under the heads is at a fraction FRAC(f+T/rotation_time) of a ** rotation from the index mark. If the target block is at physical sector ** X relative to its index mark, then it is at fraction (X/sectors_per_track), ** so the rotational delay is ** ((X/sectors_per_track)-FRAC(f+T/rotation_time)) * revolution_time ** if this is positive, otherwise it is ** (1+(X/sectors_per_track)-FRAC(f+T/rotation_time)) * revolution_time */#define FRAC(a) ( (a) - (long) floor(a) )static RF_TICS_t Delay_to(cur_time, block, disk) RF_TICS_t cur_time; RF_SectorNum_t block; RF_DiskState_t *disk;{ RF_TICS_t tmp; RF_ZoneList_t *z; long sector = block * disk->sectors_per_block; z = disk->geom->zbr_data; /* This while-loop finds the zone to which sector belongs. */ while (sector >= z->zone.num_sectors) { sector = sector - z->zone.num_sectors; z = z->next; } tmp = ( (RF_TICS_t) Find_phys_sector(block,disk)/z->zone.sec_per_track - FRAC(disk->index_offset+cur_time/disk->geom->revolution_time) ) * disk->geom->revolution_time; if( tmp < 0 ) tmp += disk->geom->revolution_time; if( tmp < 0 ) RF_PANIC(); return( tmp );}/* Hmmm...they seem to be computing the head switch time as * equal to the track skew penalty. Is this an approximation? * (MCH) */static RF_TICS_t Seek_time( to_cyl, to_track, from_cyl, from_track, disk ) long to_cyl; long to_track; long from_cyl; long from_track; RF_DiskState_t *disk;{ long cyls = ABS_DIFF( from_cyl, to_cyl ) - 1; RF_TICS_t seek = 0.0; RF_ZoneList_t * z; /* printf("Seek_time: from_cyl %ld, to_cyl %ld, from_trk %ld, to_trk %ld\n",from_cyl, to_cyl, from_track, to_track); */ if( from_cyl != to_cyl ) { z = disk->geom->zbr_data; /* This while-loop finds the zone to which to_cyl belongs. */ while (to_cyl >= z->zone.num_cylinders) { to_cyl = to_cyl - z->zone.num_cylinders; z = z->next; } seek = disk->geom->seek_constant_coeff + disk->geom->seek_linear_coeff * cyls + disk->geom->seek_sqrt_coeff * sqrt( (double) cyls ) + z->zone.track_skew * disk->geom->revolution_time / z->zone.sec_per_track; } else if( from_track != to_track ) { /* from_track and to_track must lie in the same zone. */ z = disk->geom->zbr_data; /* This while-loop finds the zone to which from_cyl belongs. */ while (from_cyl >= z->zone.num_cylinders) { from_cyl = from_cyl - z->zone.num_cylinders; z = z->next; } seek = z->zone.track_skew * disk->geom->revolution_time / z->zone.sec_per_track; } return( seek );}static RF_TICS_t Seek(cur_time, block, disk, update) RF_TICS_t cur_time; RF_SectorNum_t block; RF_DiskState_t *disk; long update;{ long cur_cyl, cur_track; /* ** current location is derived from the time, ** current track and current cylinder ** ** update current location as you go */ RF_ASSERT( block <= disk->last_block_index ); cur_cyl = disk->cur_cyl; cur_track = disk->cur_track; if (update) { disk->cur_cyl = Find_cyl( block, disk ); disk->cur_track = Find_track( block, disk ); } return( Seek_time( disk->cur_cyl, disk->cur_track, cur_cyl, cur_track, disk ) );}static RF_TICS_t Rotate(cur_time, block, disk, update) RF_TICS_t cur_time; RF_SectorNum_t block; RF_DiskState_t *disk; long update;{ /* ** current location is derived from the time, ** current track and current cylinder ** ** block the process until at the appropriate block ** updating current location as you go */ RF_ASSERT( block <= disk->last_block_index ); return( Delay_to( cur_time, block, disk ) );}static RF_TICS_t Seek_Rotate(cur_time, block, disk, update) RF_TICS_t cur_time; RF_SectorNum_t block; RF_DiskState_t *disk; long update;{ RF_TICS_t seek, delay; RF_ASSERT( block <= disk->last_block_index ); seek = Seek( cur_time, block, disk, update ); delay = seek + Rotate( cur_time+seek, block, disk, update ); return( delay );}static RF_TICS_t GAP(sec_per_track, disk) long sec_per_track; RF_DiskState_t *disk;{ RF_TICS_t tmp = (disk->geom->revolution_time/(100*sec_per_track)); return (tmp);}RF_TICS_t Block_access_time(cur_time, block, numblocks, disk, update) RF_TICS_t cur_time; RF_SectorNum_t block; RF_SectorCount_t numblocks; RF_DiskState_t *disk; long update;{ RF_TICS_t delay = 0; long cur = block, end = block + numblocks; long sector, tmp; RF_ZoneList_t * z; /* ** this is the same as Seek_Rotate by merit of the mapping ** except that the access ends before the gap to the next block */ RF_ASSERT( numblocks > 0 && end-1 <= disk->last_block_index ); while( cur < end ) { sector = cur * disk->sectors_per_block; z = disk->geom->zbr_data; /* This while-loop finds the zone to which sector belongs. */ while (sector >= z->zone.num_sectors) { sector = sector - z->zone.num_sectors; z = z->next; } tmp = RF_MIN( end - cur, z->zone.sec_per_track - cur % z->zone.sec_per_track ); delay += tmp * disk->geom->revolution_time / z->zone.sec_per_track - GAP(z->zone.sec_per_track, disk); cur += tmp; if( cur != end ) delay += Seek_Rotate( cur_time+delay, cur, disk, update ); } return( delay );}static void Zero_stats(disk) RF_DiskState_t *disk;{ char traceFileName[64]; disk->stats.num_events = 0; disk->stats.seek_sum = 0; disk->stats.seekSq_sum = 0; disk->stats.rotate_sum = 0; disk->stats.rotateSq_sum = 0; disk->stats.transfer_sum = 0; disk->stats.transferSq_sum = 0; disk->stats.access_sum = 0; disk->stats.accessSq_sum = 0; disk->stats.sleep_sum=0; disk->stats.idle_sum=0; disk->stats.rw_sum=0; disk->stats.spinup_sum=0; disk->stats.last_acc=0; if (rf_diskTrace){ sprintf (traceFileName,"rf_diskTracer%dc%d\0",disk->row,disk->col); if ( (disk->traceFile= fopen(traceFileName, "w")) == NULL) { perror(traceFileName); RF_PANIC();} }}static RF_TICS_t Update_stats(cur_time, seek, rotate, transfer, disk) RF_TICS_t cur_time; RF_TICS_t seek; RF_TICS_t rotate; RF_TICS_t transfer; RF_DiskState_t *disk;{ RF_TICS_t spinup=0; RF_TICS_t sleep=0; RF_TICS_t idle=0; disk->stats.num_events++; disk->stats.seek_sum += seek; disk->stats.seekSq_sum += seek*seek; disk->stats.rotate_sum += rotate; disk->stats.rotateSq_sum += rotate*rotate; disk->stats.transfer_sum += transfer; disk->stats.transferSq_sum += transfer*transfer; disk->stats.access_sum += seek+rotate+transfer; disk->stats.accessSq_sum += (seek+rotate+transfer)*(seek+rotate+transfer);/* ASSERT (cur_time - disk->stats.last_acc >= 0); */ if (cur_time-disk->stats.last_acc>disk->geom->time_to_sleep){ idle=disk->geom->time_to_sleep; sleep = cur_time - disk->stats.last_acc - idle; spinup=disk->geom->time_to_spinup; rf_globalSpinup = spinup; } else{ idle=cur_time - disk->stats.last_acc; } disk->stats.sleep_sum+=sleep; disk->stats.idle_sum+=idle; disk->stats.rw_sum+=seek+rotate+transfer; disk->stats.spinup_sum+=spinup; if (rf_diskTrace){ fprintf(disk->traceFile,"%g %g\n",disk->stats.last_acc,2.0); fprintf(disk->traceFile,"%g %g\n",(disk->stats.last_acc+idle),2.0); if (sleep){ fprintf(disk->traceFile,"%g %g\n",(disk->stats.last_acc+idle),1.0); fprintf(disk->traceFile,"%g %g\n",(disk->stats.last_acc+idle+sleep),1.0); } if (spinup){ fprintf(disk->traceFile,"%g %g\n",(cur_time),4.0); fprintf(disk->traceFile,"%g %g\n",(cur_time+spinup),4.0); } fprintf(disk->traceFile,"%g %g\n",(cur_time+spinup),3.0); fprintf(disk->traceFile,"%g %g\n",(cur_time+spinup+seek+rotate+transfer),3.0); } disk->stats.last_acc=cur_time+spinup+seek+rotate+transfer; return(spinup);}void rf_StopStats(disk, cur_time) RF_DiskState_t *disk; RF_TICS_t cur_time;{ RF_TICS_t sleep=0; RF_TICS_t idle=0; if (cur_time - disk->stats.last_acc > disk->geom->time_to_sleep){ sleep = cur_time - disk->stats.last_acc-disk->geom->time_to_sleep; idle = disk->geom->time_to_sleep; } else{ idle=cur_time - disk->stats.last_acc; } disk->stats.sleep_sum+=sleep; disk->stats.idle_sum+=idle; if (rf_diskTrace){ fprintf(disk->traceFile,"%g %g\n",disk->stats.last_acc,2.0); fprintf(disk->traceFile,"%g %g\n",(disk->stats.last_acc+idle),2.0); if (sleep){ fprintf(disk->traceFile,"%g %g\n",(disk->stats.last_acc+idle),1.0); fprintf(disk->traceFile,"%g %g\n",(disk->stats.last_acc+idle+sleep),1.0); } fclose(disk->traceFile); }}/* Sometimes num_events is zero because the disk was failed at the start * of the simulation and never replaced. This causes a crash on some * architectures, which is why we have the conditional. */void rf_Report_stats( RF_DiskState_t *disk, long *numEventsPtr, RF_TICS_t *avgSeekPtr, RF_TICS_t *avgRotatePtr, RF_TICS_t *avgTransferPtr, RF_TICS_t *avgAccessPtr, RF_TICS_t *SleepPtr, RF_TICS_t *IdlePtr, RF_TICS_t *RwPtr, RF_TICS_t *SpinupPtr){ *numEventsPtr = disk->stats.num_events; if (disk->stats.num_events) { *avgSeekPtr = disk->stats.seek_sum / disk->stats.num_events; *avgRotatePtr = disk->stats.rotate_sum / disk->stats.num_events; *avgTransferPtr = disk->stats.transfer_sum / disk->stats.num_events; *avgAccessPtr = disk->stats.access_sum / disk->stats.num_events; } else { *avgSeekPtr = 0; *avgRotatePtr = 0; *avgTransferPtr = 0; *avgAccessPtr = 0; } *SleepPtr = disk->stats.sleep_sum; *IdlePtr = disk->stats.idle_sum; *RwPtr = disk->stats.rw_sum ; *SpinupPtr = disk->stats.spinup_sum ;}int rf_Access_time( access_time, cur_time, block, numblocks, disk, media_done_time, update ) RF_TICS_t *access_time; RF_TICS_t cur_time; RF_SectorNum_t block; RF_SectorCount_t numblocks; RF_DiskState_t *disk; RF_TICS_t *media_done_time; long update; /* 1 => update disk state, 0 => don't */{ /* * first move to the start of the data, then sweep to the end */ RF_TICS_t spinup=0; RF_TICS_t seek = Seek( cur_time, block, disk, update ); RF_TICS_t rotate = Rotate( cur_time+seek, block, disk, update ); RF_TICS_t transfer = Block_access_time( cur_time+seek+rotate, block, numblocks, disk, update ); if (update) spinup=Update_stats(cur_time, seek, rotate, transfer, disk ); *media_done_time = seek+rotate+transfer; *access_time =( seek+rotate+transfer+spinup); return(0);}/* added to take into account the fact that maping code acounts for the disk label */void rf_GeometryDoReadCapacity(disk, numBlocks, blockSize) RF_DiskState_t *disk; RF_SectorCount_t *numBlocks; int *blockSize;{ *numBlocks= (disk->last_block_index + 1 )-rf_protectedSectors; *blockSize= (disk->sectors_per_block*512 ); /* in bytes */}/* END GEOMETRY ROUTINES **********************************************/static void rf_DiskParam(numCyls, minSeek, avgSeek, maxSeek, a, b, c) long numCyls; RF_TICS_t minSeek; RF_TICS_t avgSeek; RF_TICS_t maxSeek; RF_TICS_t *a; RF_TICS_t *b; RF_TICS_t *c;{ if (minSeek == avgSeek && minSeek == maxSeek) { *a = 0.0; *b = 0.0; *c = minSeek; } else { *a = ( 15 * avgSeek - 10 * minSeek - 5 * maxSeek ) / ( 3 * sqrt( (double) numCyls )); *b = ( 7 * minSeek + 8 * maxSeek - 15 * avgSeek ) / ( 3 * numCyls ); *c = minSeek; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?