refactor(MP/daemon): use mutex and atomic operations in application and ipc
This commit is contained in:
@@ -3,7 +3,9 @@
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <stdatomic.h>
|
||||
|
||||
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;
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
#include "sysfs.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -7,17 +7,22 @@
|
||||
#include <pthread.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <stdatomic.h>
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user