diff options
author | Mattias Andrée <maandree@kth.se> | 2017-06-18 01:00:29 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2017-06-18 01:00:29 +0200 |
commit | 225db53fbd4b5d7723c95a44370a1c55521dab46 (patch) | |
tree | 8b3eb30a9194a055881b174024ec8767912d4cc6 | |
parent | m (diff) | |
download | yes-silly-225db53fbd4b5d7723c95a44370a1c55521dab46.tar.gz yes-silly-225db53fbd4b5d7723c95a44370a1c55521dab46.tar.bz2 yes-silly-225db53fbd4b5d7723c95a44370a1c55521dab46.tar.xz |
Add limit.c: get the highest rate possible
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r-- | limit.c | 81 |
1 files changed, 81 insertions, 0 deletions
@@ -0,0 +1,81 @@ +/* See LICENSE file for copyright and license details. */ + +#define _GNU_SOURCE +#include <fcntl.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> + + +#ifndef CAPACITY +# define CAPACITY (1 << 20) +#endif + + +int +main(int argc, char *argv[]) +{ + static char buf[1 << 16]; + int rw1[2], rw2[2], n = 0, m; + ssize_t r, p, w; + size_t sum = 0, totsum = 0; + struct timespec start, end; + double rate; + + if (!argc) + *argv = "limit"; + + if (pipe(rw1) || fcntl(*rw1, F_SETPIPE_SZ, CAPACITY) != CAPACITY) + goto fail; + if (pipe(rw2) || fcntl(*rw2, F_SETPIPE_SZ, CAPACITY) != CAPACITY) + goto fail; + + for (n = CAPACITY; n; n -= (int)r) + if ((r = write(rw1[1], buf, n)) < 0) + goto fail; + + if (clock_gettime(CLOCK_MONOTONIC, &start)) + goto fail; + for (;;) { + r = splice(rw1[0], NULL, rw2[1], NULL, CAPACITY, 0); + if (r <= 0) { + if (r < 0) + goto fail; + goto done; + } + for (p = 0; p < r; p += w) { + w = splice(rw2[0], NULL, rw1[1], NULL, r - p, 0); + if (w <= 0) { + if (w < 0) + goto fail; + goto done; + } + } + sum += (size_t)r << 1; + if (++n == 100000) { + if (clock_gettime(CLOCK_MONOTONIC, &end)) + goto fail; + n = 0; + start.tv_sec = end.tv_sec - start.tv_sec; + start.tv_nsec = end.tv_nsec - start.tv_nsec; + rate = (double)start.tv_nsec; + rate /= 1000000000.; + rate += start.tv_sec; + rate = (double)sum / rate; + rate /= 1000000000.; + totsum += sum; + sum = 0; + dprintf(STDERR_FILENO, " %lf GB/s\033[K\n\033[A", rate); + start = end; + } + } + +done: + return 0; + +fail: + perror(*argv); + return 1; +} |