/*
- * Copyright (c) 2016-2018 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2016-2020 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
}
// scale access time by (distance in blocks from previous I/O / maximum blocks)
- access_time_scale = weighted_scale_factor((double)blkdiff / BLK_MAX(mp));
+ access_time_scale = weighted_scale_factor((double)blkdiff / (double)BLK_MAX(mp));
+ if (__builtin_isnan(access_time_scale)) {
+ return;
+ }
// most cases should pass in extents==1 for optimal delay calculation, otherwise just multiply delay by extents
- delay_usec = (uint64_t)(((uint64_t)extents * info->access_time_usec) * access_time_scale);
+ double temp = (((double)extents * (double)info->access_time_usec) * access_time_scale);
+ if (temp <= 0) {
+ delay_usec = 0;
+ } else if (temp >= (double)(18446744073709549568ULL)) { /* highest 64-bit unsigned integer representable as a double */
+ delay_usec = UINT64_MAX;
+ } else {
+ delay_usec = (uint64_t)temp;
+ }
if (info->read_throughput_mbps && (bp->b_flags & B_READ)) {
delay_usec += (uint64_t)(total_size / ((double)(info->read_throughput_mbps * 1024 * 1024 / 8) / USEC_PER_SEC));
while (delay_usec) {
microuptime(&start);
- delay(delay_usec);
+ assert(delay_usec <= INT_MAX);
+ delay((int)delay_usec);
microuptime(&elapsed);
timevalsub(&elapsed, &start);
if (elapsed.tv_sec * USEC_PER_SEC < delay_usec) {