commit e676e270101f6b52b296b74a05fd2788c5ba1f06 Author: Linus Vogel Date: Sun Mar 15 14:57:00 2026 +0100 initial commit, actually done already diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..62c8935 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..36be99c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.31) +project(cputild C) + +set(CMAKE_C_STANDARD 11) + +add_executable(cputild main.c) diff --git a/cputild.service b/cputild.service new file mode 100644 index 0000000..11a400d --- /dev/null +++ b/cputild.service @@ -0,0 +1,12 @@ +[Unit] +Description=Simple daemon that will continuously write the cpu usage to /tmp/cputild +After=network.target + +[Service] +Type=simple +ExecStart=/usr/local/cputild +ExecStop=kill -INT $MAIN_PID +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/main.c b/main.c new file mode 100644 index 0000000..5c98f30 --- /dev/null +++ b/main.c @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include +#include + + +#define STAT_FILE "/proc/stat" +#define OUT_FILE "/tmp/cputild" + +volatile int running = 1; + +void signal_handler_sigint(const int _signal) { + assert(_signal == SIGINT && "ERROR: Signal except SIGINT received by the SIGINT handler"); + + printf("hello there\n"); + running = 0; +} + +int main(void) { + // register the SIGINT handler + signal(SIGINT, signal_handler_sigint); + + FILE *out_file = fopen(OUT_FILE, "w"); + FILE *stat_file = fopen(STAT_FILE, "r"); + + uint64_t total_jiffies_active = 0; + uint64_t total_jiffies_idle = 0; + + size_t line_len = 1024; + char *line_buffer = (char*)malloc(line_len); + + while (running) { + struct timespec now; + struct timespec request; + struct timespec remain; + + request.tv_sec = 1; + request.tv_nsec = 0; + nanosleep(&request, &remain); + clock_gettime(CLOCK_REALTIME, &now); + + fflush(stat_file); + fseek(stat_file, 0, SEEK_SET); + const ssize_t read = getline(&line_buffer, &line_len, stat_file); + if (read == -1) { + printf("Failed to read the stat file!\n"); + exit(1); + } + + uint64_t user, user_nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice; + const int n_read = sscanf(line_buffer, "cpu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", &user, &user_nice, &system, &idle, &iowait, &irq, &softirq, &steal, &guest, &guest_nice); // NOLINT(*-err34-c) + if (n_read != 10) { + printf("Failed to read the stat file: Invalid format?\n"); + exit(1); + } + + const uint64_t current_total_jiffies_active = user + user_nice + system + irq + softirq + guest + guest_nice; + const uint64_t current_total_jiffies_idle = iowait + idle; + + const uint64_t delta_jiffies_active = current_total_jiffies_active - total_jiffies_active; + const uint64_t delta_jiffies_idle = current_total_jiffies_idle - total_jiffies_idle; + + const double utilization = (double)(delta_jiffies_active) / (double)(delta_jiffies_idle + delta_jiffies_active); + + total_jiffies_active = current_total_jiffies_active; + total_jiffies_idle = current_total_jiffies_idle; + + fseek(out_file, 0, SEEK_SET); + fprintf(out_file, "Custom CPU: %.02f", utilization * 100); + fflush(out_file); + } + + free(line_buffer); + + printf("Terminating...\n"); + return 0; +} \ No newline at end of file