various: log memory events

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I6a6a69643b6d00277bb9bcfeb4cd01dc78d7cd3d
This commit is contained in:
raf 2025-09-30 20:11:06 +03:00
commit bc77b887ad
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
7 changed files with 280 additions and 47 deletions

View file

@ -9,8 +9,8 @@
#include "../include/chroma.h"
// Global logging level
static int log_level = 0; // 0=ERROR, 1=WARN, 2=INFO, 3=DEBUG
// Global logging level (using CHROMA_LOG_* constants)
static int log_level = CHROMA_LOG_WARN; // Default to WARN and ERROR only
// Initialize chroma state
int chroma_init(chroma_state_t *state) {
@ -32,6 +32,8 @@ int chroma_init(chroma_state_t *state) {
state->initialized = true;
chroma_log("INFO", "Chroma state initialized");
chroma_log_resource_allocation("chroma_state", sizeof(chroma_state_t),
"main application state");
return CHROMA_OK;
}
@ -43,6 +45,7 @@ void chroma_cleanup(chroma_state_t *state) {
}
chroma_log("INFO", "Cleaning up chroma state");
chroma_log_memory_stats("pre-cleanup");
// Stop the main loop
state->running = false;
@ -60,6 +63,8 @@ void chroma_cleanup(chroma_state_t *state) {
chroma_config_free(&state->config);
state->initialized = false;
chroma_log_resource_deallocation("chroma_state", sizeof(chroma_state_t),
"main application state");
chroma_log("INFO", "Chroma cleanup complete");
}
@ -116,6 +121,7 @@ static int assign_wallpaper_to_output(chroma_state_t *state,
chroma_log("INFO", "Assigned wallpaper to output %u (%s): %s", output->id,
output->name ? output->name : "unknown", image_path);
chroma_log_memory_stats("post-wallpaper-assignment");
return CHROMA_OK;
}
@ -173,20 +179,20 @@ static int process_wayland_events(chroma_state_t *state) {
return CHROMA_ERROR_WAYLAND;
}
/* Dispatch pending events */
// Dispatch pending events
if (wl_display_dispatch_pending(state->display) == -1) {
chroma_log("ERROR", "Failed to dispatch pending Wayland events: %s",
strerror(errno));
return CHROMA_ERROR_WAYLAND;
}
/* Read events from the server */
// Read events from the server
if (wl_display_read_events(state->display) == -1) {
chroma_log("ERROR", "Failed to read Wayland events: %s", strerror(errno));
return CHROMA_ERROR_WAYLAND;
}
/* Dispatch the read events */
// Dispatch the read events
if (wl_display_dispatch_pending(state->display) == -1) {
chroma_log("ERROR", "Failed to dispatch read Wayland events: %s",
strerror(errno));
@ -203,6 +209,7 @@ int chroma_run(chroma_state_t *state) {
}
chroma_log("INFO", "Starting main event loop");
chroma_log_memory_stats("main-loop-start");
state->running = true;
// Initial wallpaper assignment
@ -247,7 +254,7 @@ int chroma_run(chroma_state_t *state) {
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
timeout.tv_sec = 1; // 1 second timeout
timeout.tv_sec = 1; // 1s timeout
timeout.tv_usec = 0;
int select_result = select(fd + 1, &readfds, NULL, NULL, &timeout);
@ -307,24 +314,41 @@ const char *chroma_error_string(chroma_error_t error) {
}
}
// Logging function
// Convert log level string to numeric level
static int log_level_from_string(const char *level) {
if (strcmp(level, "ERROR") == 0)
return CHROMA_LOG_ERROR;
if (strcmp(level, "WARN") == 0)
return CHROMA_LOG_WARN;
if (strcmp(level, "INFO") == 0)
return CHROMA_LOG_INFO;
if (strcmp(level, "DEBUG") == 0)
return CHROMA_LOG_DEBUG;
if (strcmp(level, "TRACE") == 0)
return CHROMA_LOG_TRACE;
return CHROMA_LOG_ERROR; // default to ERROR for unknown levels
}
// Logging function with level filtering
void chroma_log(const char *level, const char *format, ...) {
int msg_level = log_level_from_string(level);
if (msg_level > log_level) {
return;
}
va_list args;
char timestamp[32];
struct timeval tv;
struct tm *tm_info;
// Get current time
gettimeofday(&tv, NULL);
tm_info = localtime(&tv.tv_sec);
// Format timestamp
snprintf(timestamp, sizeof(timestamp), "%04d-%02d-%02d %02d:%02d:%02d.%03d",
tm_info->tm_year + 1900, tm_info->tm_mon + 1, tm_info->tm_mday,
tm_info->tm_hour, tm_info->tm_min, tm_info->tm_sec,
(int)(tv.tv_usec / 1000));
// Print log message
printf("[%s] %s: ", timestamp, level);
va_start(args, format);
@ -445,3 +469,75 @@ void chroma_get_stats(chroma_state_t *state, int *active_outputs,
if (loaded_images)
*loaded_images = loaded;
}
// Get current memory usage from /proc/self/status
// FIXME: some users may choose to confine /proc, we need a cleaner
// way of getting this data in the future
size_t chroma_get_memory_usage(void) {
FILE *file = fopen("/proc/self/status", "r");
if (!file) {
return 0;
}
size_t vm_rss = 0;
char line[256];
while (fgets(line, sizeof(line), file)) {
if (strncmp(line, "VmRSS:", 6) == 0) {
// Parse VmRSS line: "VmRSS: 1234 kB"
char *ptr = line + 6;
while (*ptr == ' ' || *ptr == '\t')
ptr++; // Skip whitespace
vm_rss = (size_t)strtoul(ptr, NULL, 10) * 1024; // Convert kB to bytes
break;
}
}
fclose(file);
return vm_rss;
}
// Log memory statistics with context
void chroma_log_memory_stats(const char *context) {
size_t memory_usage = chroma_get_memory_usage();
char mem_str[64];
chroma_format_memory_size(memory_usage, mem_str, sizeof(mem_str));
chroma_log("INFO", "Memory usage [%s]: %s", context, mem_str);
}
// Log resource allocation
void chroma_log_resource_allocation(const char *resource_type, size_t size,
const char *description) {
if (size > 0) {
char size_str[64];
chroma_format_memory_size(size, size_str, sizeof(size_str));
chroma_log("DEBUG", "Allocated %s: %s (%s)", resource_type, size_str,
description);
} else {
chroma_log("DEBUG", "Allocated %s: %s", resource_type, description);
}
// Log memory stats after significant allocations (>1MB)
if (size > 1024 * 1024) {
chroma_log_memory_stats("post-allocation");
}
}
// Log resource deallocation
void chroma_log_resource_deallocation(const char *resource_type, size_t size,
const char *description) {
if (size > 0) {
char size_str[64];
chroma_format_memory_size(size, size_str, sizeof(size_str));
chroma_log("DEBUG", "Deallocated %s: %s (%s)", resource_type, size_str,
description);
} else {
chroma_log("DEBUG", "Deallocated %s: %s", resource_type, description);
}
// Log memory stats after significant deallocations (>1MB)
if (size > 1024 * 1024) {
chroma_log_memory_stats("post-deallocation");
}
}