diff --git a/f3write.c b/f3write.c index 5dd90d5..b7e1a4a 100644 --- a/f3write.c +++ b/f3write.c @@ -150,13 +150,13 @@ static int write_all(int fd, const char *buf, size_t count) return 0; } -static int write_chunk(int fd, ssize_t chunk_size, uint64_t *poffset) +static int write_chunk(int fd, size_t chunk_size, uint64_t *poffset) { - char buf[MAX_WRITE_SIZE]; + char buf[MAX_BUFFER_SIZE]; while (chunk_size > 0) { - ssize_t turn_size = chunk_size <= MAX_WRITE_SIZE - ? chunk_size : MAX_WRITE_SIZE; + size_t turn_size = chunk_size <= MAX_BUFFER_SIZE + ? chunk_size : MAX_BUFFER_SIZE; int ret; chunk_size -= turn_size; *poffset = fill_buffer(buf, turn_size, *poffset); @@ -203,10 +203,8 @@ static int create_and_fill_file(const char *path, long number, size_t size, remaining = size; start_measurement(fw); while (remaining > 0) { - ssize_t write_size = fw->block_size * - (fw->blocks_per_delay - fw->written_blocks); - assert(write_size > 0); - if ((size_t)write_size > remaining) + size_t write_size = get_rem_chunk_size(fw); + if (write_size > remaining) write_size = remaining; saved_errno = write_chunk(fd, write_size, &offset); if (saved_errno) diff --git a/libflow.c b/libflow.c index 2e70ebb..7177c35 100644 --- a/libflow.c +++ b/libflow.c @@ -19,22 +19,22 @@ static inline void move_to_inc_at_start(struct flow *fw) } void init_flow(struct flow *fw, uint64_t total_size, - long max_write_rate, int progress, + long max_process_rate, int progress, flow_func_flush_chunk_t func_flush_chunk) { fw->total_size = total_size; - fw->total_written = 0; + fw->total_processed = 0; fw->progress = progress; fw->block_size = 512; /* Bytes */ fw->blocks_per_delay = 1; /* 512B/s */ fw->delay_ms = 1000; /* 1s */ - fw->max_write_rate = max_write_rate <= 0 - ? DBL_MAX : max_write_rate * 1024.; + fw->max_process_rate = max_process_rate <= 0 + ? DBL_MAX : max_process_rate * 1024.; fw->measured_blocks = 0; fw->measured_time_ms = 0; fw->erase = 0; fw->func_flush_chunk = func_flush_chunk; - fw->written_blocks = 0; + fw->processed_blocks = 0; fw->acc_delay_us = 0; assert(fw->block_size > 0); assert(fw->block_size % SECTOR_SIZE == 0); @@ -104,16 +104,16 @@ static void report_progress(struct flow *fw, double inst_speed) * the initial free space isn't exactly reported * by the kernel; this issue has been seen on Macs. */ - if (fw->total_size < fw->total_written) - fw->total_size = fw->total_written; - percent = (double)fw->total_written * 100 / fw->total_size; + if (fw->total_size < fw->total_processed) + fw->total_size = fw->total_processed; + percent = (double)fw->total_processed * 100 / fw->total_size; erase(fw->erase); fw->erase = printf("%.2f%% -- %.2f %s/s", percent, inst_speed, unit); assert(fw->erase > 0); if (has_enough_measurements(fw)) fw->erase += pr_time( - (fw->total_size - fw->total_written) / + (fw->total_size - fw->total_processed) / get_avg_speed(fw)); fflush(stdout); } @@ -188,14 +188,14 @@ static inline int is_rate_above(const struct flow *fw, long delay, double inst_speed) { /* We use logical or here to enforce the lowest limit. */ - return delay > fw->delay_ms || inst_speed > fw->max_write_rate; + return delay > fw->delay_ms || inst_speed > fw->max_process_rate; } static inline int is_rate_below(const struct flow *fw, long delay, double inst_speed) { /* We use logical and here to enforce both limist. */ - return delay <= fw->delay_ms && inst_speed < fw->max_write_rate; + return delay <= fw->delay_ms && inst_speed < fw->max_process_rate; } static inline int flush_chunk(const struct flow *fw, int fd) @@ -244,20 +244,20 @@ static inline uint64_t diff_timeval_us(const struct timeval *t1, t2->tv_usec - t1->tv_usec; } -int measure(int fd, struct flow *fw, ssize_t written) +int measure(int fd, struct flow *fw, ssize_t processed) { - ldiv_t result = ldiv(written, fw->block_size); + ldiv_t result = ldiv(processed, fw->block_size); struct timeval t2; int64_t delay; double bytes_k, inst_speed; assert(result.rem == 0); - fw->written_blocks += result.quot; - fw->total_written += written; + fw->processed_blocks += result.quot; + fw->total_processed += processed; - if (fw->written_blocks < fw->blocks_per_delay) + if (fw->processed_blocks < fw->blocks_per_delay) return 0; - assert(fw->written_blocks == fw->blocks_per_delay); + assert(fw->processed_blocks == fw->blocks_per_delay); if (flush_chunk(fw, fd) < 0) return -1; /* Caller can read errno(3). */ @@ -269,10 +269,12 @@ int measure(int fd, struct flow *fw, ssize_t written) bytes_k = fw->blocks_per_delay * fw->block_size * 1000.0; inst_speed = bytes_k / delay; - if (delay < fw->delay_ms && inst_speed > fw->max_write_rate) { - /* Wait until inst_speed == fw->max_write_rate (if possible). */ - double wait_ms = round((bytes_k - delay * fw->max_write_rate) - / fw->max_write_rate); + if (delay < fw->delay_ms && inst_speed > fw->max_process_rate) { + /* Wait until inst_speed == fw->max_process_rate + * (if possible). + */ + double wait_ms = round((bytes_k - delay * fw->max_process_rate) + / fw->max_process_rate); if (wait_ms < 0) { /* Wait what is possible. */ @@ -297,7 +299,7 @@ int measure(int fd, struct flow *fw, ssize_t written) } /* Update mean. */ - fw->measured_blocks += fw->written_blocks; + fw->measured_blocks += fw->processed_blocks; fw->measured_time_ms += delay; switch (fw->state) { @@ -340,9 +342,9 @@ int measure(int fd, struct flow *fw, ssize_t written) case FW_STEADY: { if (delay <= fw->delay_ms) { - if (inst_speed < fw->max_write_rate) { + if (inst_speed < fw->max_process_rate) { move_to_inc(fw); - } else if (inst_speed > fw->max_write_rate) { + } else if (inst_speed > fw->max_process_rate) { move_to_dec(fw); } } else if (fw->blocks_per_delay > 1) { @@ -359,7 +361,7 @@ int measure(int fd, struct flow *fw, ssize_t written) report_progress(fw, inst_speed); /* Reset accumulators. */ - fw->written_blocks = 0; + fw->processed_blocks = 0; fw->acc_delay_us = 0; __start_measurement(fw); return 0; @@ -371,7 +373,7 @@ int end_measurement(int fd, struct flow *fw) int saved_errno; int ret = 0; - if (fw->written_blocks <= 0) + if (fw->processed_blocks <= 0) goto out; if (flush_chunk(fw, fd) < 0) { diff --git a/libflow.h b/libflow.h index b3f7b79..cc3ca98 100644 --- a/libflow.h +++ b/libflow.h @@ -8,10 +8,10 @@ struct flow; typedef int (*flow_func_flush_chunk_t)(const struct flow *fw, int fd); struct flow { - /* Total number of bytes to be written. */ + /* Total number of bytes to be processed. */ uint64_t total_size; - /* Total number of bytes already written. */ - uint64_t total_written; + /* Total number of bytes already processed. */ + uint64_t total_processed; /* If true, show progress. */ int progress; /* Block size in bytes. */ @@ -20,10 +20,10 @@ struct flow { unsigned int delay_ms; /* Increment to apply to @blocks_per_delay. */ int64_t step; - /* Blocks to write before measurement. */ + /* Blocks to process before measurement. */ int64_t blocks_per_delay; - /* Maximum write rate in bytes per second. */ - double max_write_rate; + /* Maximum processing rate in bytes per second. */ + double max_process_rate; /* Number of measured blocks. */ uint64_t measured_blocks; /* Measured time. */ @@ -42,10 +42,10 @@ struct flow { * Initialized while measuring */ - /* Number of blocks written since last measurement. */ - int64_t written_blocks; + /* Number of blocks processed since last measurement. */ + int64_t processed_blocks; /* - * Accumulated delay before @written_blocks reaches @blocks_per_delay + * Accumulated delay before @processed_blocks reaches @blocks_per_delay * in microseconds. */ uint64_t acc_delay_us; @@ -55,15 +55,15 @@ struct flow { struct timeval t1; }; -/* If @max_write_rate <= 0, the maximum write rate is infinity. - * The unit of @max_write_rate is KB per second. +/* If @max_process_rate <= 0, the maximum processing rate is infinity. + * The unit of @max_process_rate is KB per second. */ void init_flow(struct flow *fw, uint64_t total_size, - long max_write_rate, int progress, + long max_process_rate, int progress, flow_func_flush_chunk_t func_flush_chunk); void start_measurement(struct flow *fw); -int measure(int fd, struct flow *fw, ssize_t written); +int measure(int fd, struct flow *fw, ssize_t processed); int end_measurement(int fd, struct flow *fw); static inline int has_enough_measurements(const struct flow *fw) @@ -84,6 +84,14 @@ static inline double get_avg_speed(struct flow *fw) return get_avg_speed_given_time(fw, fw->measured_time_ms); } -#define MAX_WRITE_SIZE (1<<21) /* 2MB */ +static inline size_t get_rem_chunk_size(struct flow *fw) +{ + ssize_t ret = (fw->blocks_per_delay - fw->processed_blocks) * + fw->block_size; + assert(ret > 0); + return ret; +} + +#define MAX_BUFFER_SIZE (1<<21) /* 2MB */ #endif /* HEADER_LIBFLOW_H */