From 30f844370c997bdc3ae6fbb12470262759ff67b3 Mon Sep 17 00:00:00 2001 From: Adrien 'neox' Bourmault Date: Fri, 22 Nov 2024 17:07:22 +0100 Subject: [PATCH] src/{fsm,widget}/*, include/fsm.h: reworked logging memory management and encapsulated calls This commit fixes issues with memory management in the logging code of the FSM. It also optimizes operations by restricting char* pointers, allowing the compiler knowing that they do not overlap. Finally, it encapsulates calls to fsm_add_log in a macro that allows to automatically get file and function names. Signed-off-by: Adrien 'neox' Bourmault --- include/fsm.h | 41 ++++++++++++++++----------------- src/fsm/control.c | 12 +++++----- src/fsm/log/appendix.c | 13 +++++------ src/fsm/log/manager.c | 15 +++++------- src/fsm/log/oper.c | 35 ++++++++++++++++------------ src/main.c | 9 ++++---- src/widget/main_window/design.c | 8 +++---- src/widget/manager.c | 28 ++++++++-------------- 8 files changed, 75 insertions(+), 86 deletions(-) diff --git a/include/fsm.h b/include/fsm.h index 32cce70..b7e15fc 100644 --- a/include/fsm.h +++ b/include/fsm.h @@ -176,10 +176,10 @@ enum fsm_enum_log_source { //----------------------------------------------------------------------------- #define FILE_SOURCE_NAME_SIZE 40 -#define FUNCTION_SOURCE_NAME_SIZE 40 -#define STRING_VALUE_SIZE 60 -#define LOG_MAX_LENGTH 255 /**< arbitrary */ - +#define FUNCTION_SOURCE_NAME_SIZE 30 +#define STRING_VALUE_SIZE 50 +#define LOG_MAX_LENGTH \ + FILE_SOURCE_NAME_SIZE+FUNCTION_SOURCE_NAME_SIZE+STRING_VALUE_SIZE /** * A log unit must include the followings: @@ -190,9 +190,9 @@ struct fsm_log_unit_t { long yy_dd_mm; /**< * date of the event reported in the log */ long usec; /**< * with microseconds precision */ - char *file_source; /**< * emitter file */ - char *function_source; /**< * emitter function */ - char *string_value; /**< * any event descriptors */ + char *restrict file_source; /**< * emitter file */ + char *restrict function_source; /**< * emitter function */ + char *restrict string_value; /**< * any event descriptors */ struct fsm_log_unit_t *prev; /**< * chained list */ struct fsm_log_unit_t *next; /**< * chained list */ }; @@ -226,26 +226,25 @@ void fsm_clear_log (struct fsm_log_t *); void fsm_clear_log_unit(struct fsm_log_unit_t *); void fsm_add_log_event (struct fsm_log_t *gg_logs, - const char *file_source, - const char *function_source, - const char *string_value); + const char *restrict file_source, + const char *restrict function_source, + const char *restrict string_value); int fsm_get_log_length(struct fsm_log_t *); void fsm_seek_log (struct fsm_log_t *gg_logs, long usec, - char *file_source, - char *function_source, - char *string_value); -long fsm_remove_log (struct fsm_log_t *gg_logs, - char *file_source, - char *function_source, - char *string_value); + const char *restrict file_source, + const char *restrict function_source, + const char *restrict string_value); +long fsm_remove_log (struct fsm_log_t *); void fsm_add_log (int severity, - int source, - const char *file_source, - const char *function_source, - const char *string_value); + const char *restrict file_source, + const char *restrict function_source, + const char *restrict string_value); + +#define FSM_ADD_LOG(severity,string_value) \ + fsm_add_log(severity,__FILE__,__func__,string_value) void fsm_relay_init_log(); void fsm_relay_close_log(); diff --git a/src/fsm/control.c b/src/fsm/control.c index 204e055..a7fd189 100644 --- a/src/fsm/control.c +++ b/src/fsm/control.c @@ -144,12 +144,12 @@ void fsm_init() { fsm_relay_init_log(); - fsm_add_log (INFO, MAIN, "fsm/control", __func__, + FSM_ADD_LOG (INFO, "👋️ (☕️) Hi everybody ! Here is Gem-Graph."); - fsm_add_log (INFO, FSM, "fsm/control", __func__, "has began ✍️"); + FSM_ADD_LOG (INFO, "has began ✍️"); fsm_structures_init(); - fsm_add_log (INFO, FSM, "fsm/control", __func__, "has ended 😇️"); + FSM_ADD_LOG (INFO, "has ended 😇️"); } /** @@ -183,11 +183,11 @@ void fsm_init() */ void fsm_close() { - fsm_add_log (INFO, FSM, "fsm/control", __func__, "has began"); + FSM_ADD_LOG (INFO, "has began"); fsm_structures_close(); - fsm_add_log (INFO, FSM, "fsm/control", __func__, "has ended"); + FSM_ADD_LOG (INFO, "has ended"); - fsm_add_log (INFO, MAIN, "fsm/control", __func__, + FSM_ADD_LOG (INFO, "👋️😄️ That'all folks !"); fsm_relay_close_log(); /**< fsm_clear_log(() can't be called from here diff --git a/src/fsm/log/appendix.c b/src/fsm/log/appendix.c index 16ae2ed..de5e24b 100644 --- a/src/fsm/log/appendix.c +++ b/src/fsm/log/appendix.c @@ -46,10 +46,7 @@ * * @returns the removed event date microseconds */ -long fsm_remove_log (struct fsm_log_t *gg_logs, - char *file_source, - char *function_source, - char *string_value) +long fsm_remove_log (struct fsm_log_t *gg_logs) { // save latest log ref in tmp struct fsm_log_unit_t *tmp = gg_logs->latest; @@ -97,6 +94,8 @@ int fsm_get_log_length (struct fsm_log_t *gg_logs) /** * Seek for an event * + * XXX absolutely does not work as expected (does not seek anything in fact). + * * @since 2024-09 * * @param *gg_logs @@ -107,9 +106,9 @@ int fsm_get_log_length (struct fsm_log_t *gg_logs) */ void fsm_seek_log (struct fsm_log_t *gg_logs, long usec, - char *file_source, - char *function_source, - char *string_value) + const char *restrict file_source, + const char *restrict function_source, + const char *restrict string_value) { struct fsm_log_unit_t *a_unit = gg_logs->oldest; int nb = 0; diff --git a/src/fsm/log/manager.c b/src/fsm/log/manager.c index 17f0a89..850b407 100644 --- a/src/fsm/log/manager.c +++ b/src/fsm/log/manager.c @@ -93,16 +93,13 @@ static struct fsm_log_t gg_logs = { 0 }; * @see fsm_enum_log_source */ void fsm_add_log (int severity, - int source, - const char *file_source, - const char *function_source, - const char *string_value) + const char *restrict file_source, + const char *restrict function_source, + const char *restrict string_value) { - if - ( - severity < TRACE - // && source == RULE_CONDITION - ) + if (severity > TRACE) + return; + fsm_add_log_event (&gg_logs, file_source, function_source, string_value); } diff --git a/src/fsm/log/oper.c b/src/fsm/log/oper.c index 9ce7624..7b6a627 100644 --- a/src/fsm/log/oper.c +++ b/src/fsm/log/oper.c @@ -101,9 +101,8 @@ void fsm_clear_log_unit (struct fsm_log_unit_t *unit) /** * Adds a log unit (an event) to the log list. * - * new_unit = malloc (sizeof (fsm_log_unit_struct)); - * - * warn: is never free (as new log units are never removed) + * The `restrict` keyword tells the compiler that pointers do not overlap in + * memory, enabling optimizations like vectorization. * * @since 2024-09 * @@ -112,27 +111,29 @@ void fsm_clear_log_unit (struct fsm_log_unit_t *unit) * @param *function_source * @param *string_value */ -void fsm_add_log_event (struct fsm_log_t *gg_logs, - const char *file_source, - const char *function_source, - const char *string_value) +void fsm_add_log_event (struct fsm_log_t *restrict gg_logs, + const char *restrict file_source, + const char *restrict function_source, + const char *restrict string_value) { struct timeval tv; gettimeofday (&tv, NULL); struct fsm_log_unit_t *new_unit = g_malloc0 (sizeof(struct fsm_log_unit_t)); - if (! new_unit) exit (EXIT_FAILURE); + + if (new_unit == NULL) + g_error("Failed to allocate new_unit"); new_unit->yy_dd_mm = tv.tv_sec; new_unit->usec = tv.tv_usec; - new_unit->file_source = malloc(FILE_SOURCE_NAME_SIZE * sizeof(char)); - new_unit->function_source = malloc(FUNCTION_SOURCE_NAME_SIZE * sizeof(char)); - new_unit->string_value = malloc(STRING_VALUE_SIZE * sizeof(char)); + new_unit->file_source = g_malloc0 (1 + FILE_SOURCE_NAME_SIZE * sizeof(char)); + new_unit->function_source = g_malloc0 (1 + FUNCTION_SOURCE_NAME_SIZE * sizeof(char)); + new_unit->string_value = g_malloc0 (1 + STRING_VALUE_SIZE * sizeof(char)); - strncpy (new_unit->file_source, file_source, FILE_SOURCE_NAME_SIZE - 1); - strncpy (new_unit->function_source, function_source, FUNCTION_SOURCE_NAME_SIZE - 1); - strncpy (new_unit->string_value, string_value, STRING_VALUE_SIZE - 1); + strncpy (new_unit->file_source, file_source, FILE_SOURCE_NAME_SIZE); + strncpy (new_unit->function_source, function_source, FUNCTION_SOURCE_NAME_SIZE); + strncpy (new_unit->string_value, string_value, STRING_VALUE_SIZE); /** first time we log something (don't touch new_unit->prev) */ if (gg_logs->oldest == NULL) @@ -163,12 +164,16 @@ void fsm_publish_log (struct fsm_log_t *gg_logs) struct fsm_log_unit_t *a_unit = gg_logs->oldest; char *timestamp = g_malloc0 (LOG_MAX_LENGTH * sizeof(char)); int nb = 0; + + if (timestamp == NULL) + g_error("Failed to allocate timestamp"); + while (a_unit) { strftime(timestamp, LOG_MAX_LENGTH * sizeof(char), "%D %T", localtime(&a_unit->yy_dd_mm)); - g_message ("%s + %-6ld %6d %-28s %-32s %-60s", + g_message ("%s + %-6ld %6d %-40s %-30s %-50s", timestamp, a_unit->usec, nb, diff --git a/src/main.c b/src/main.c index 910d806..46e0359 100644 --- a/src/main.c +++ b/src/main.c @@ -65,14 +65,12 @@ int main (int argc, char **argv) fsm_init(); - fsm_add_log (INFO, MAIN, __func__, - "*app = gtk_application_new()", + FSM_ADD_LOG (INFO, "| 👉️ trigger app initialization"); app = gtk_application_new ("org.gem-graph", G_APPLICATION_DEFAULT_FLAGS); - fsm_add_log (INFO, MAIN, __func__, - "g signal connect (activate)", + FSM_ADD_LOG (INFO, "| 👉️ windows creation requested"); // g_signal_connect (app, "startup", G_CALLBACK (on_windows_startup), NULL); @@ -80,7 +78,8 @@ int main (int argc, char **argv) status = g_application_run (G_APPLICATION (app), argc, argv); g_object_unref (app); - fsm_add_log (INFO, MAIN, __func__, "g_object unref (app)", "| 👌️ bye bye app !"); + FSM_ADD_LOG (INFO, + "| 👌️ bye bye app !"); fsm_close(); diff --git a/src/widget/main_window/design.c b/src/widget/main_window/design.c index eb33319..a0f289b 100644 --- a/src/widget/main_window/design.c +++ b/src/widget/main_window/design.c @@ -41,7 +41,7 @@ */ void on_toggle_exec_edit (GtkWidget *toggled_button, gpointer user_data) { - fsm_add_log (INFO, BUTTON, "signal", __func__, + FSM_ADD_LOG (INFO, "flip status request + bell 😇️ gdk_display_beep()"); gdk_display_beep (gdk_display_get_default()); @@ -59,8 +59,7 @@ void widget_design_main_window (GtkWindow *main_window, GtkApplication *app) gpointer no_local_data = NULL; - fsm_add_log (INFO, HEADER_BAR_LEFT, "widget/main_window/design", - __func__, "start of design"); + FSM_ADD_LOG (INFO, "start of design"); char *title = "E coli (with permission from David S. Goodsell, 2009)"; gtk_header_bar_set_title_widget (GTK_HEADER_BAR (header_bar), @@ -83,6 +82,5 @@ void widget_design_main_window (GtkWindow *main_window, GtkApplication *app) // g_object_unref (e_coli); - fsm_add_log (INFO, HEADER_BAR_LEFT, "widget/main_window/design", - __func__, "end of design -> present"); + FSM_ADD_LOG (INFO, "end of design -> present"); } diff --git a/src/widget/manager.c b/src/widget/manager.c index 1288104..3ecf1f7 100644 --- a/src/widget/manager.c +++ b/src/widget/manager.c @@ -58,7 +58,7 @@ static GtkWindow *window; */ void on_app_activation (GtkApplication *app) { - fsm_add_log (INFO, WIDGETS, "widget/manager", __func__, "has began"); + FSM_ADD_LOG (INFO, "has began"); // on_windows_activation() is in: widget/manager NOT in: src/signal // g_application_activate (G_APPLICATION (app)); < how ? > in main is @@ -73,29 +73,23 @@ void on_app_activation (GtkApplication *app) //g_object_ref_sink(widget); // remove floating reference, and own this object ourselves //g_object_unref(widget); //gtk_widget_destroy(widget); - - window = GTK_WINDOW (gtk_application_window_new (app)); int window_int_id = gtk_application_window_get_id (GTK_APPLICATION_WINDOW (window)); - char window_char_id[40]; - sprintf(window_char_id, "%d", window_int_id); + char msg[STRING_VALUE_SIZE+1] = { 0 }; - g_signal_connect(window, "close-request", G_CALLBACK (on_window_close_request), (void *)(long long)window_int_id); + snprintf(msg, STRING_VALUE_SIZE, "window_get_id = %d", window_int_id); + FSM_ADD_LOG (INFO, msg); - int destination_string_size = 50 * sizeof(char); - char *temp = g_malloc0 (destination_string_size); - temp = strncat (temp, "window_get_id = ", destination_string_size); - temp = strncat (temp, window_char_id, destination_string_size); - fsm_add_log (INFO, WIDGETS, "widget/manager", __func__, temp); - free(temp); + // Handling window close and passing window id as argument + g_signal_connect(window, "close-request", + G_CALLBACK (on_window_close_request), + (void *)(long long)window_int_id); widget_design_main_window (window, app); gtk_window_present (GTK_WINDOW (window)); - // g_object_unref (main_window); TODO get the closing signal of the main window - // ------------------------------------------------------------------------ // For the breakdown between pages, see signal > switch_state_rules_data() @@ -117,15 +111,13 @@ void on_app_activation (GtkApplication *app) g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (act_b)); g_signal_connect (act_b, "activate", G_CALLBACK (action_b), app2);*/ - fsm_add_log (INFO, WIDGETS, "widget/manager", __func__, - "has ended 🧐️ | 👉️ a new session starts"); + FSM_ADD_LOG (INFO, "has ended 🧐️ | 👉️ a new session starts"); } gboolean on_window_close_request (GtkWindow *window, gpointer user_data) { - fsm_add_log (INFO, WIDGETS, "widget/manager", __func__, - "freeing all ressources !"); + FSM_ADD_LOG (INFO, "freeing all ressources !"); // free the only child gtk_window_set_child (window, NULL); // deleting the child from window