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 <neox@a-lec.org>
This commit is contained in:
parent
502fc8939f
commit
30f844370c
8 changed files with 75 additions and 86 deletions
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue