From 93c439abb8c7ef284d9284821c26f5842c311884 Mon Sep 17 00:00:00 2001 From: Klagarge Date: Sun, 7 Jun 2026 15:46:55 +0200 Subject: [PATCH] refactor(MP/daemon): use mutex and atomic operations in application and ipc --- src/06-mini-project/daemon/application/app.c | 21 ++++++++--- .../daemon/application/sysfs.c | 35 ++++++++++++++++--- src/06-mini-project/daemon/ipc/ipc_server.c | 14 ++++++-- 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/src/06-mini-project/daemon/application/app.c b/src/06-mini-project/daemon/application/app.c index 936d236..8c0c310 100644 --- a/src/06-mini-project/daemon/application/app.c +++ b/src/06-mini-project/daemon/application/app.c @@ -3,7 +3,9 @@ #include #include -#include +#include + +#include static LED* led; @@ -11,10 +13,11 @@ static LED* led; static pthread_t anim_thread_id; static pthread_mutex_t anim_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t anim_condition = PTHREAD_COND_INITIALIZER; // SHARED RESOURCES +static pthread_mutex_t app_lock = PTHREAD_MUTEX_INITIALIZER; /* The counter of pending animations */ static int pending_animations = 0; // SHARED RESOURCES -static int keep_running = 1; +static atomic_bool keep_running = true; void btn_set_led(LED* l) { if (l != NULL) { @@ -31,13 +34,19 @@ uint32_t get_period() { } void increase_period() { + pthread_mutex_lock(&app_lock); uint32_t current_period = sysfs_get_period(); set_period(current_period + GAP_PERIOD_MS); + pthread_mutex_unlock(&app_lock); } void decrease_period() { + pthread_mutex_lock(&app_lock); uint32_t current_period = sysfs_get_period(); - set_period(current_period - GAP_PERIOD_MS); + if (current_period > GAP_PERIOD_MS) { + set_period(current_period - GAP_PERIOD_MS); + } + pthread_mutex_unlock(&app_lock); } int get_mode() { @@ -49,8 +58,10 @@ void set_mode(int mode) { } void mode_toggle() { + pthread_mutex_lock(&app_lock); int current_mode = sysfs_get_mode(); set_mode(current_mode ^ 1); + pthread_mutex_unlock(&app_lock); } float get_temperature() { @@ -93,9 +104,9 @@ static void* animation_worker(void* arg) { /* Perform the visual task */ if (led != NULL) { LED_on(led); - usleep(150000); + usleep(20000); LED_off(led); - usleep(100000); /* Small delay between consecutive pulses */ + usleep(50000); /* Small delay between consecutive pulses */ } } return NULL; diff --git a/src/06-mini-project/daemon/application/sysfs.c b/src/06-mini-project/daemon/application/sysfs.c index 90346ae..bee89c6 100644 --- a/src/06-mini-project/daemon/application/sysfs.c +++ b/src/06-mini-project/daemon/application/sysfs.c @@ -1,13 +1,16 @@ #include "sysfs.h" #include #include -#include +#include +static pthread_mutex_t sysfs_lock = PTHREAD_MUTEX_INITIALIZER; float sysfs_get_temperature() { + pthread_mutex_lock(&sysfs_lock); FILE *f = fopen(PATH_TEMPERATURE, "r"); if (f == NULL) { + pthread_mutex_unlock(&sysfs_lock); return 0.0f; /* Return 0.0 if the kernel module is not loaded */ } @@ -19,48 +22,70 @@ float sysfs_get_temperature() { */ if (fscanf(f, "%f", &temp) == 1) { fclose(f); + pthread_mutex_unlock(&sysfs_lock); return temp; } fclose(f); + pthread_mutex_unlock(&sysfs_lock); return 0.0f; } uint32_t sysfs_get_mode() { + pthread_mutex_lock(&sysfs_lock); FILE *f = fopen(PATH_MODE, "r"); - if (f == NULL) return 0; + if (f == NULL) { + pthread_mutex_unlock(&sysfs_lock); + return 0; + } uint32_t mode = 0; fscanf(f, "%u", &mode); fclose(f); + pthread_mutex_unlock(&sysfs_lock); return mode; } void sysfs_set_mode(uint32_t mode) { + pthread_mutex_lock(&sysfs_lock); FILE *f = fopen(PATH_MODE, "w"); - if (f == NULL) return; + if (f == NULL) { + pthread_mutex_unlock(&sysfs_lock); + return; + } /* Write the integer as an ASCII string */ fprintf(f, "%u\n", mode); fclose(f); + pthread_mutex_unlock(&sysfs_lock); } uint32_t sysfs_get_period() { + pthread_mutex_lock(&sysfs_lock); FILE *f = fopen(PATH_PERIOD_ST, "r"); - if (f == NULL) return 0; + if (f == NULL) { + pthread_mutex_unlock(&sysfs_lock); + return 0; + } uint32_t period = 0; fscanf(f, "%u", &period); fclose(f); + pthread_mutex_unlock(&sysfs_lock); return period; } void sysfs_set_period(uint32_t period) { + pthread_mutex_lock(&sysfs_lock); FILE *f = fopen(PATH_PERIOD_SET, "w"); - if (f == NULL) return; + if (f == NULL) { + pthread_mutex_unlock(&sysfs_lock); + return; + } fprintf(f, "%u\n", period); fclose(f); + pthread_mutex_unlock(&sysfs_lock); } diff --git a/src/06-mini-project/daemon/ipc/ipc_server.c b/src/06-mini-project/daemon/ipc/ipc_server.c index 7c6b762..ba3ad5f 100644 --- a/src/06-mini-project/daemon/ipc/ipc_server.c +++ b/src/06-mini-project/daemon/ipc/ipc_server.c @@ -7,17 +7,22 @@ #include #include #include +#include + +#include /* Global variables for the IPC module */ static int server_fd = -1; static pthread_t ipc_thread; static struct ipc_callbacks_t current_cbs = {0}; -static int is_running = 0; +static pthread_mutex_t cb_mutex = PTHREAD_MUTEX_INITIALIZER; +static atomic_bool is_running = false; /** * process_message() - Route the received IPC message to the correct callback. */ static void process_message(ipc_msg_t *msg) { + pthread_mutex_lock(&cb_mutex); switch (msg->command) { case CMD_SET_MODE: if (current_cbs.on_set_mode) { @@ -47,6 +52,7 @@ static void process_message(ipc_msg_t *msg) { printf("[IPC] Received unknown command: %d\n", msg->command); break; } + pthread_mutex_unlock(&cb_mutex); } /** @@ -92,9 +98,11 @@ int start_ipc_server(struct ipc_callbacks_t *cbs) { } /* Save the provided callbacks */ + pthread_mutex_lock(&cb_mutex); if (cbs) { current_cbs = *cbs; } + pthread_mutex_unlock(&cb_mutex); /* Create local socket */ server_fd = socket(AF_UNIX, SOCK_DGRAM, 0); @@ -139,7 +147,7 @@ int stop_ipc_server(void) { printf("[IPC] Stopping server...\n"); /* Signal thread to stop */ - is_running = 0; + atomic_store(&is_running, false); /* Unblock the recvfrom() by shutting down the socket */ if (server_fd != -1) { @@ -155,7 +163,9 @@ int stop_ipc_server(void) { unlink(SOCKET_PATH); /* Clear callbacks */ + pthread_mutex_lock(&cb_mutex); memset(¤t_cbs, 0, sizeof(struct ipc_callbacks_t)); + pthread_mutex_unlock(&cb_mutex); return 0; }