Skip to content

Instantly share code, notes, and snippets.

@hashbrowncipher
Created March 24, 2022 06:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hashbrowncipher/729f4bc047f0b05071acd9c9c17f6344 to your computer and use it in GitHub Desktop.
Save hashbrowncipher/729f4bc047f0b05071acd9c9c17f6344 to your computer and use it in GitHub Desktop.
//Invoke like `./bin <frequency in Hz (e.g. 100)> <filename to read>`
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#define DEVICE_NAME "/sys/block/nvme0n1/stat"
unsigned long get_io_ticks() {
char b[4096];
char * buf = b;
bzero(buf, 4096);
int fd = open(DEVICE_NAME, O_RDONLY);
read(fd, buf, 4096);
close(fd);
for(int i=0; i<9; i++) {
buf += strspn(buf, " ");
buf = strchr(buf, ' ')+1;
}
buf += strspn(buf, " ");
char * delim = strchr(buf, ' ');
*delim = 0;
return atoi(buf) / 10;
}
int main(int argc, char ** argv) {
struct timespec ts;
int interval = 1000 * 1000 / atoi(argv[1]);
time_t stamp = 0;
int interval_stamp = 0;
int slept = 0;
ulong saved_ticks = 0;
int fd = open(argv[2], O_DIRECT | O_RDONLY);
if(fd < 0) {
perror("open");
exit(1);
}
void * buf = valloc(4096);
while(true) {
if(pread(fd, buf, 4096, 0) < 0) {
perror("pread");
exit(1);
}
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
int uclock = ts.tv_nsec / 1000;
int sleep;
if(uclock / interval > interval_stamp) {
sleep = 0;
} else {
sleep = interval - uclock % interval;
}
interval_stamp = (uclock / interval) + 1;
if(stamp != ts.tv_sec) {
unsigned long ticks = get_io_ticks();
printf(
"disk read time: %d%%, kernel util: %lu%%\n",
100 - slept / 10000, ticks - saved_ticks
);
saved_ticks = ticks;
stamp = ts.tv_sec;
slept = 0;
}
if(sleep > 0) {
slept += sleep;
usleep(sleep);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment