1
0

refactor(MP/daemon): use mutex and atomic operations in application and ipc

This commit is contained in:
2026-06-07 15:46:55 +02:00
parent e46d3bb4b2
commit 93c439abb8
3 changed files with 58 additions and 12 deletions

View File

@@ -3,7 +3,9 @@
#include <pthread.h> #include <pthread.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdbool.h>
#include <stdatomic.h>
static LED* led; static LED* led;
@@ -11,10 +13,11 @@ static LED* led;
static pthread_t anim_thread_id; static pthread_t anim_thread_id;
static pthread_mutex_t anim_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t anim_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t anim_condition = PTHREAD_COND_INITIALIZER; // SHARED RESOURCES 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 */ /* The counter of pending animations */
static int pending_animations = 0; // SHARED RESOURCES static int pending_animations = 0; // SHARED RESOURCES
static int keep_running = 1; static atomic_bool keep_running = true;
void btn_set_led(LED* l) { void btn_set_led(LED* l) {
if (l != NULL) { if (l != NULL) {
@@ -31,13 +34,19 @@ uint32_t get_period() {
} }
void increase_period() { void increase_period() {
pthread_mutex_lock(&app_lock);
uint32_t current_period = sysfs_get_period(); uint32_t current_period = sysfs_get_period();
set_period(current_period + GAP_PERIOD_MS); set_period(current_period + GAP_PERIOD_MS);
pthread_mutex_unlock(&app_lock);
} }
void decrease_period() { void decrease_period() {
pthread_mutex_lock(&app_lock);
uint32_t current_period = sysfs_get_period(); 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() { int get_mode() {
@@ -49,8 +58,10 @@ void set_mode(int mode) {
} }
void mode_toggle() { void mode_toggle() {
pthread_mutex_lock(&app_lock);
int current_mode = sysfs_get_mode(); int current_mode = sysfs_get_mode();
set_mode(current_mode ^ 1); set_mode(current_mode ^ 1);
pthread_mutex_unlock(&app_lock);
} }
float get_temperature() { float get_temperature() {
@@ -93,9 +104,9 @@ static void* animation_worker(void* arg) {
/* Perform the visual task */ /* Perform the visual task */
if (led != NULL) { if (led != NULL) {
LED_on(led); LED_on(led);
usleep(150000); usleep(20000);
LED_off(led); LED_off(led);
usleep(100000); /* Small delay between consecutive pulses */ usleep(50000); /* Small delay between consecutive pulses */
} }
} }
return NULL; return NULL;

View File

@@ -1,13 +1,16 @@
#include "sysfs.h" #include "sysfs.h"
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
static pthread_mutex_t sysfs_lock = PTHREAD_MUTEX_INITIALIZER;
float sysfs_get_temperature() { float sysfs_get_temperature() {
pthread_mutex_lock(&sysfs_lock);
FILE *f = fopen(PATH_TEMPERATURE, "r"); FILE *f = fopen(PATH_TEMPERATURE, "r");
if (f == NULL) { if (f == NULL) {
pthread_mutex_unlock(&sysfs_lock);
return 0.0f; /* Return 0.0 if the kernel module is not loaded */ 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) { if (fscanf(f, "%f", &temp) == 1) {
fclose(f); fclose(f);
pthread_mutex_unlock(&sysfs_lock);
return temp; return temp;
} }
fclose(f); fclose(f);
pthread_mutex_unlock(&sysfs_lock);
return 0.0f; return 0.0f;
} }
uint32_t sysfs_get_mode() { uint32_t sysfs_get_mode() {
pthread_mutex_lock(&sysfs_lock);
FILE *f = fopen(PATH_MODE, "r"); 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; uint32_t mode = 0;
fscanf(f, "%u", &mode); fscanf(f, "%u", &mode);
fclose(f); fclose(f);
pthread_mutex_unlock(&sysfs_lock);
return mode; return mode;
} }
void sysfs_set_mode(uint32_t mode) { void sysfs_set_mode(uint32_t mode) {
pthread_mutex_lock(&sysfs_lock);
FILE *f = fopen(PATH_MODE, "w"); 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 */ /* Write the integer as an ASCII string */
fprintf(f, "%u\n", mode); fprintf(f, "%u\n", mode);
fclose(f); fclose(f);
pthread_mutex_unlock(&sysfs_lock);
} }
uint32_t sysfs_get_period() { uint32_t sysfs_get_period() {
pthread_mutex_lock(&sysfs_lock);
FILE *f = fopen(PATH_PERIOD_ST, "r"); 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; uint32_t period = 0;
fscanf(f, "%u", &period); fscanf(f, "%u", &period);
fclose(f); fclose(f);
pthread_mutex_unlock(&sysfs_lock);
return period; return period;
} }
void sysfs_set_period(uint32_t period) { void sysfs_set_period(uint32_t period) {
pthread_mutex_lock(&sysfs_lock);
FILE *f = fopen(PATH_PERIOD_SET, "w"); 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); fprintf(f, "%u\n", period);
fclose(f); fclose(f);
pthread_mutex_unlock(&sysfs_lock);
} }

View File

@@ -7,17 +7,22 @@
#include <pthread.h> #include <pthread.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <stdbool.h>
#include <stdatomic.h>
/* Global variables for the IPC module */ /* Global variables for the IPC module */
static int server_fd = -1; static int server_fd = -1;
static pthread_t ipc_thread; static pthread_t ipc_thread;
static struct ipc_callbacks_t current_cbs = {0}; 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. * process_message() - Route the received IPC message to the correct callback.
*/ */
static void process_message(ipc_msg_t *msg) { static void process_message(ipc_msg_t *msg) {
pthread_mutex_lock(&cb_mutex);
switch (msg->command) { switch (msg->command) {
case CMD_SET_MODE: case CMD_SET_MODE:
if (current_cbs.on_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); printf("[IPC] Received unknown command: %d\n", msg->command);
break; break;
} }
pthread_mutex_unlock(&cb_mutex);
} }
/** /**
@@ -92,9 +98,11 @@ int start_ipc_server(struct ipc_callbacks_t *cbs) {
} }
/* Save the provided callbacks */ /* Save the provided callbacks */
pthread_mutex_lock(&cb_mutex);
if (cbs) { if (cbs) {
current_cbs = *cbs; current_cbs = *cbs;
} }
pthread_mutex_unlock(&cb_mutex);
/* Create local socket */ /* Create local socket */
server_fd = socket(AF_UNIX, SOCK_DGRAM, 0); server_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
@@ -139,7 +147,7 @@ int stop_ipc_server(void) {
printf("[IPC] Stopping server...\n"); printf("[IPC] Stopping server...\n");
/* Signal thread to stop */ /* Signal thread to stop */
is_running = 0; atomic_store(&is_running, false);
/* Unblock the recvfrom() by shutting down the socket */ /* Unblock the recvfrom() by shutting down the socket */
if (server_fd != -1) { if (server_fd != -1) {
@@ -155,7 +163,9 @@ int stop_ipc_server(void) {
unlink(SOCKET_PATH); unlink(SOCKET_PATH);
/* Clear callbacks */ /* Clear callbacks */
pthread_mutex_lock(&cb_mutex);
memset(&current_cbs, 0, sizeof(struct ipc_callbacks_t)); memset(&current_cbs, 0, sizeof(struct ipc_callbacks_t));
pthread_mutex_unlock(&cb_mutex);
return 0; return 0;
} }