#include #include #include #include #include #include #include #define ENABLE_TRACING 1 #define BUFSIZE (192 << 12) static void clear_trace(void) { #if ENABLE_TRACING int fd = open("/sys/kernel/debug/tracing/trace", O_WRONLY); if (fd < 0) perror("open trace"); int res = write(fd, &fd, sizeof fd); if (res != sizeof fd) perror("clear trace"); close(fd); #endif } static void dump_trace(char *save) { #if ENABLE_TRACING int fd = open("/sys/kernel/debug/tracing/trace", O_RDONLY); if (fd < 0) perror("open trace"); int fd_out = open(save, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (fd_out < 0) perror("open save"); while ( 1 ) { char buf[8000]; int res = read(fd, buf, sizeof buf); if (res <= 0) break; write(fd_out, buf, res); } close(fd_out); close(fd); #endif } static void toggle_tracing(char val) { (void)val; #if ENABLE_TRACING int fd = open("/sys/kernel/debug/tracing/tracing_on", O_WRONLY); if (fd < 0) perror("open toggle"); int res = write(fd, &val, 1); if (res != 1) perror(__func__); close(fd); #endif } static int64_t now(void) { struct timespec spec; clock_gettime(CLOCK_MONOTONIC, &spec); return spec.tv_sec*1000000000LL + spec.tv_nsec; } int main(void) { struct sched_param param = { .sched_priority = 50 }; int err = sched_setscheduler(0, SCHED_FIFO, ¶m); printf("sched_setscheduler=%d\n", err); char *buf = malloc(BUFSIZE); if (buf == NULL) return 2; memset(buf, '+', BUFSIZE); int flags = O_WRONLY | O_CREAT | O_TRUNC | O_SYNC; int fd = open("foob", flags, 0600); if (fd < 0) return 3; clear_trace(); strcpy(buf, "WARM UP"); write(fd, buf, 4096); strcpy(buf, "SHOW TIME"); int64_t t0 = now(); toggle_tracing('1'); write(fd, buf, BUFSIZE); toggle_tracing('0'); int64_t t1 = now(); close(fd); printf("LAT = %9lld\n", t1-t0); dump_trace("/tmp/trace.one"); return 0; }