Commit 0d79bd8e authored by Konstantin Khlebnikov's avatar Konstantin Khlebnikov

ioping: add option for speed limit

Handle interval time as interval between requests starts.
Speed limit just set interval according to request size.
Signed-off-by: default avatarKonstantin Khlebnikov <koct9i@gmail.com>
parent 232f611e
...@@ -6,6 +6,7 @@ ioping \- simple disk I/O latency monitoring tool ...@@ -6,6 +6,7 @@ ioping \- simple disk I/O latency monitoring tool
.OP \-ABCDLRWYykq .OP \-ABCDLRWYykq
.OP \-c count .OP \-c count
.OP \-i interval .OP \-i interval
.OP \-l speed
.OP \-t time .OP \-t time
.OP \-s size .OP \-s size
.OP \-S wsize .OP \-S wsize
...@@ -31,6 +32,9 @@ Stop after \fIcount\fR requests. ...@@ -31,6 +32,9 @@ Stop after \fIcount\fR requests.
.BI \-i \ interval .BI \-i \ interval
Set time between requests to \fIinterval\fR (\fB1s\fR). Set time between requests to \fIinterval\fR (\fB1s\fR).
.TP .TP
.BI \-l \ speed
Set \fIspeed\fR limit in bytes per second. Set interval to request-size / speed.
.TP
.BI \-t \ time .BI \-t \ time
Minimal valid request time for cache misses (\fB0us\fR). Minimal valid request time for cache misses (\fB0us\fR).
Cache hits are ignored in statistics. Cache hits are ignored in statistics.
......
...@@ -306,6 +306,7 @@ void usage(void) ...@@ -306,6 +306,7 @@ void usage(void)
"\n" "\n"
" -c <count> stop after <count> requests\n" " -c <count> stop after <count> requests\n"
" -i <interval> interval between requests (1s)\n" " -i <interval> interval between requests (1s)\n"
" -l <speed> speed limit in bytes per second\n"
" -t <time> minimal valid request time (0us)\n" " -t <time> minimal valid request time (0us)\n"
" -s <size> request size (4k)\n" " -s <size> request size (4k)\n"
" -S <wsize> working set size (1m)\n" " -S <wsize> working set size (1m)\n"
...@@ -493,6 +494,7 @@ int custom_interval, custom_deadline; ...@@ -493,6 +494,7 @@ int custom_interval, custom_deadline;
long long interval = NSEC_PER_SEC; long long interval = NSEC_PER_SEC;
struct timespec interval_ts; struct timespec interval_ts;
long long deadline = 0; long long deadline = 0;
long long speed_limit = 0;
long long min_valid_time = 0; long long min_valid_time = 0;
...@@ -519,7 +521,7 @@ void parse_options(int argc, char **argv) ...@@ -519,7 +521,7 @@ void parse_options(int argc, char **argv)
exit(1); exit(1);
} }
while ((opt = getopt(argc, argv, "hvkALRDCWYBqyi:t:w:s:S:c:o:p:P:")) != -1) { while ((opt = getopt(argc, argv, "hvkALRDCWYBqyi:t:w:s:S:c:o:p:P:l:")) != -1) {
switch (opt) { switch (opt) {
case 'h': case 'h':
usage(); usage();
...@@ -531,6 +533,9 @@ void parse_options(int argc, char **argv) ...@@ -531,6 +533,9 @@ void parse_options(int argc, char **argv)
randomize = 0; randomize = 0;
default_size = 1<<18; default_size = 1<<18;
break; break;
case 'l':
speed_limit = parse_size(optarg);
break;
case 'R': case 'R':
if (!custom_interval) if (!custom_interval)
interval = 0; interval = 0;
...@@ -1061,14 +1066,17 @@ int main (int argc, char **argv) ...@@ -1061,14 +1066,17 @@ int main (int argc, char **argv)
parse_options(argc, argv); parse_options(argc, argv);
interval_ts.tv_sec = interval / NSEC_PER_SEC;
interval_ts.tv_nsec = interval % NSEC_PER_SEC;
if (!size) if (!size)
size = default_size; size = default_size;
if (size <= 0) if (size <= 0)
errx(1, "request size must be greather than zero"); errx(1, "request size must be greater than zero");
if (custom_interval && speed_limit)
errx(1, "speed limit and interval cannot be set simultaneously");
if (speed_limit)
interval = size * NSEC_PER_SEC / speed_limit;
#ifdef MAX_RW_COUNT #ifdef MAX_RW_COUNT
if (size > MAX_RW_COUNT) if (size > MAX_RW_COUNT)
...@@ -1237,6 +1245,8 @@ skip_preparation: ...@@ -1237,6 +1245,8 @@ skip_preparation:
period_deadline = time_start + period_time; period_deadline = time_start + period_time;
time_next = time_start;
while (!exiting) { while (!exiting) {
request++; request++;
part_request++; part_request++;
...@@ -1269,8 +1279,12 @@ skip_preparation: ...@@ -1269,8 +1279,12 @@ skip_preparation:
errx(3, "request returned more than expected: %zu", ret_size); errx(3, "request returned more than expected: %zu", ret_size);
time_now = now(); time_now = now();
time_next += interval;
if ((time_now - time_next) > 0)
time_next = time_now;
this_time = time_now - this_time; this_time = time_now - this_time;
time_next = time_now + interval;
if (this_time >= min_valid_time) { if (this_time >= min_valid_time) {
part_valid++; part_valid++;
...@@ -1354,8 +1368,13 @@ skip_preparation: ...@@ -1354,8 +1368,13 @@ skip_preparation:
if (deadline && time_next >= deadline) if (deadline && time_next >= deadline)
break; break;
if (interval) if ((time_next - time_now) > 0) {
long long delta = time_next - time_now;
interval_ts.tv_sec = delta / NSEC_PER_SEC;
interval_ts.tv_nsec = delta % NSEC_PER_SEC;
nanosleep(&interval_ts, NULL); nanosleep(&interval_ts, NULL);
}
} }
time_now = now(); time_now = now();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment