94 lines
2.6 KiB
C
94 lines
2.6 KiB
C
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
|
|
|
|
#define N 5
|
|
|
|
typedef struct {
|
|
double time;
|
|
size_t nread;
|
|
} resultT;
|
|
|
|
int cmptime(const void *a, const void *b) {
|
|
const resultT *aa = a, *bb = b;
|
|
if (aa->time < bb->time) {
|
|
return -1;
|
|
} else if (aa->time > bb->time) {
|
|
return +1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
resultT median (resultT *v, int n) {
|
|
// n is small, keep it simple
|
|
qsort(v, n, sizeof(*v), cmptime);
|
|
return v[n / 2];
|
|
|
|
}
|
|
|
|
|
|
int main(int argc, char **argv) {
|
|
resultT **results = calloc(sizeof(*results), argc);
|
|
assert(results);
|
|
for (int i = 1; i < argc; i++) {
|
|
results[i] = calloc(sizeof(**results), N);
|
|
assert(results[i]);
|
|
}
|
|
|
|
for (int j = 0; j < N; j++) {
|
|
for (int i = 1; i < argc; i++) {
|
|
struct timespec t0, t1;
|
|
clock_gettime(CLOCK_MONOTONIC, &t0);
|
|
size_t nread = 0;
|
|
|
|
int out[2];
|
|
if (pipe(out) == -1) {
|
|
printf("%s: cannot create pipe: %s\n", argv[0], strerror(errno));
|
|
exit(1);
|
|
}
|
|
|
|
pid_t pid = fork();
|
|
switch(pid) {
|
|
case -1:
|
|
fprintf(stderr, "%s: cannot fork: %s\n", argv[0], strerror(errno));
|
|
exit(1);
|
|
case 0:
|
|
dup2(out[1], 1);
|
|
// close(out[0]);
|
|
// close(out[1]);
|
|
execl(argv[i], argv[i], (char *)NULL);
|
|
fprintf(stderr, "%s: cannot exec %s: %s\n", argv[0], argv[i], strerror(errno));
|
|
exit(1);
|
|
default: {
|
|
close(out[1]);
|
|
ssize_t n;
|
|
char buf[16];
|
|
while ((n = read(out[0], buf, sizeof(buf))) > 0) {
|
|
nread += n;
|
|
}
|
|
int status;
|
|
while (waitpid(pid, &status, 0) != pid);
|
|
}
|
|
}
|
|
clock_gettime(CLOCK_MONOTONIC, &t1);
|
|
results[i][j].time = (t1.tv_sec - t0.tv_sec) * 1E9 + (t1.tv_nsec - t0.tv_nsec);
|
|
results[i][j].nread = nread;
|
|
fprintf(stderr, "%s: %s completed in %f ns\n", argv[0], argv[i], results[i][j].time);
|
|
}
|
|
}
|
|
for (int i = 1; i < argc; i++) {
|
|
resultT m = median(results[i], N);
|
|
printf("%-20s %8.3f ms %2zd bytes\n", argv[i], m.time / 1E6, m.nread);
|
|
}
|
|
return 0;
|
|
}
|