Created
February 13, 2021 13:45
-
-
Save satoru-takeuchi/fb50591c99fc401b23bbb9179eca6706 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sys/types.h> | |
#include <sys/wait.h> | |
#include <time.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <err.h> | |
#define NLOOP_FOR_ESTIMATION 1000000000UL | |
#define NSECS_PER_MSEC 1000000UL | |
#define NSECS_PER_SEC 1000000000UL | |
static unsigned long nloop_per_msec; | |
static int total; | |
static struct timespec start; | |
struct timespec *logbuf; | |
static inline long diff_nsec(struct timespec before, struct timespec after) | |
{ | |
return ((after.tv_sec * NSECS_PER_SEC + after.tv_nsec) | |
- (before.tv_sec * NSECS_PER_SEC + before.tv_nsec)); | |
} | |
static unsigned long estimate_loops_per_msec() | |
{ | |
struct timespec before, after; | |
clock_gettime(CLOCK_MONOTONIC, &before); | |
unsigned long i; | |
for (i = 0; i < NLOOP_FOR_ESTIMATION; i++) | |
; | |
clock_gettime(CLOCK_MONOTONIC, &after); | |
return NLOOP_FOR_ESTIMATION * NSECS_PER_MSEC / diff_nsec(before, after); | |
} | |
static void child_fn(int id, struct timespec *buf) | |
{ | |
int i; | |
for (i = 0; i < total; i++) { | |
struct timespec now; | |
unsigned long j; | |
for (j = 0; j < nloop_per_msec; j++) | |
; | |
clock_gettime(CLOCK_MONOTONIC, &now); | |
buf[i] = now; | |
} | |
for (i = 0; i < total; i++) { | |
printf("%d\t%ld\t%d\n", id, diff_nsec(start, buf[i]) / NSECS_PER_MSEC, (i+1)*100/total); | |
} | |
exit(EXIT_SUCCESS); | |
} | |
int main(int argc, char *argv[]) | |
{ | |
if (argc < 3) { | |
fprintf(stderr, "usage: %s <nproc> <total[ms]>\n", argv[0]); | |
exit(EXIT_FAILURE); | |
} | |
int nproc = atoi(argv[1]); | |
total = atoi(argv[2]); | |
if (nproc < 1) { | |
fprintf(stderr, "<nproc>(%d) should be >= 1\n", nproc); | |
exit(EXIT_FAILURE); | |
} | |
if (total < 1) { | |
fprintf(stderr, "<total>(%d) should be >= 1\n", total); | |
exit(EXIT_FAILURE); | |
} | |
puts("estimating the workload which takes just one milli-second..."); | |
nloop_per_msec = estimate_loops_per_msec(); | |
puts("end estimation"); | |
fflush(stdout); | |
logbuf = malloc(total * sizeof(struct timespec)); | |
if (!logbuf) | |
err(EXIT_FAILURE, "failed to allocate log buffer"); | |
clock_gettime(CLOCK_MONOTONIC, &start); | |
int i; | |
for (i = 0; i < nproc; i++) { | |
pid_t pid = fork(); | |
if (pid < 0) { | |
exit(EXIT_FAILURE); | |
} else if (pid == 0) { | |
child_fn(i, logbuf); | |
abort(); | |
} | |
} | |
for (i = 0; i < nproc; i++) | |
wait(NULL); | |
exit(EXIT_SUCCESS); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment