/* Spike for testing filesystem log polling. How much of a load does filesystem polling for updates (as opposed to waiting on inotify) impose on current hardware? This program stats a file 60 times a second to find out. I tried it on my Ryzen 5 3500U laptop, plugged in, running at 2700MHz and got these results (edited transcript): $ time ./60hz-logpoll tmp.dumb tmp.dumb is now 357888 bytes. tmp.dumb is now 357893 bytes. tmp.dumb is now 357898 bytes. tmp.dumb is now 357903 bytes. ^C real 0m10.084s user 0m0.021s sys 0m0.001s $ time ./60hz-logpoll tmp.dumb tmp.dumb is now 357903 bytes. tmp.dumb is now 357908 bytes. tmp.dumb is now 357920 bytes. tmp.dumb is now 357927 bytes. tmp.dumb is now 357939 bytes. tmp.dumb is now 357951 bytes. ^C real 2m16.818s user 0m0.066s sys 0m0.213s We can’t *really* trust the user and system numbers these days, but in the first case we used 22ms over 10 seconds, which is 0.22% of a core (or 0.05% of the whole CPU), and in the second case we used 279ms over 137 seconds, which is 0.204% of a core. */ #include #include #include #include #include double now() { struct timeval tv; gettimeofday(&tv, 0); return tv.tv_sec + 1e-6 * tv.tv_usec; } void clock_tick(double hz, double *target) { *target += 1.0/hz; double wait = *target - now(); if (wait > 0) usleep(wait * 1e6); } int main(int argc, char **argv) { if (argc != 2) { fprintf(stderr, "Usage: %s logfile\n" "Prints a message every time `logfile` grows.\n", argv[0]); return 1; } int fd = open(argv[1], O_RDONLY); if (fd < 0) { perror(argv[1]); return 2; } double target = now(); off_t size = 0; struct stat st; for (;;) { if (fstat(fd, &st)) { perror("fstat"); return 3; } if (st.st_size != size) { size = st.st_size; printf("%s is now %ld bytes.\n", argv[1], (long)size); fflush(stdout); } clock_tick(60, &target); } }