Skip to content

Instantly share code, notes, and snippets.

@satoru-takeuchi
Created February 13, 2021 13:45
Show Gist options
  • Save satoru-takeuchi/fb50591c99fc401b23bbb9179eca6706 to your computer and use it in GitHub Desktop.
Save satoru-takeuchi/fb50591c99fc401b23bbb9179eca6706 to your computer and use it in GitHub Desktop.
#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