From: Mathieu Desnoyers Date: Sat, 14 Aug 2010 15:20:45 +0000 (-0400) Subject: Fix dynamic update of marker data across same channel tracefiles X-Git-Tag: v0.12.34~3 X-Git-Url: http://git.liburcu.org/?p=lttv.git;a=commitdiff_plain;h=f972ab5e81be30df0ef5d690a55a6876c27b1d40 Fix dynamic update of marker data across same channel tracefiles Fixes garbled string output when the same channel / event are written by concurrent threads. This was caused by the fact that metadata information was shared across cpu tracefiles for a given channel. Signed-off-by: Mathieu Desnoyers --- diff --git a/ltt/marker.c b/ltt/marker.c index 07b5c08e..8e07b326 100644 --- a/ltt/marker.c +++ b/ltt/marker.c @@ -421,21 +421,16 @@ int marker_parse_format(const char *format, struct marker_info *info) return 0; } -int marker_format_event(LttTrace *trace, GQuark channel, GQuark name, - const char *format) +static +int marker_format_tf_event(LttTrace *trace, LttTracefile *tf, + GQuark channel, GQuark name, const char *format) { struct marker_info *info; struct marker_data *mdata; char *fquery; char *fcopy; - GArray *group; - - group = g_datalist_id_get_data(&trace->tracefiles, channel); - if (!group) - return -ENOENT; - g_assert(group->len > 0); - mdata = g_array_index (group, LttTracefile, 0).mdata; + mdata = tf->mdata; fquery = marker_get_format_from_name(mdata, name); if (fquery) { if (strcmp(fquery, format) != 0) @@ -460,23 +455,36 @@ int marker_format_event(LttTrace *trace, GQuark channel, GQuark name, return 0; } -int marker_id_event(LttTrace *trace, GQuark channel, GQuark name, guint16 id, - uint8_t int_size, uint8_t long_size, uint8_t pointer_size, - uint8_t size_t_size, uint8_t alignment) +int marker_format_event(LttTrace *trace, GQuark channel, GQuark name, + const char *format) { - struct marker_data *mdata; - struct marker_info *info, *head; - int found = 0; GArray *group; - - g_debug("Add channel %s event %s %hu\n", g_quark_to_string(channel), - g_quark_to_string(name), id); + int i, ret; + LttTracefile *tf; group = g_datalist_id_get_data(&trace->tracefiles, channel); if (!group) return -ENOENT; g_assert(group->len > 0); - mdata = g_array_index (group, LttTracefile, 0).mdata; + for (i = 0; i < group->len; i++) { + tf = &g_array_index (group, LttTracefile, i); + ret = marker_format_tf_event(trace, tf, channel, name, format); + if (ret) + g_error("Error in marker_format_event"); + } + return 0; +} + +int marker_id_tf_event(LttTrace *trace, LttTracefile *tf, + GQuark channel, GQuark name, guint16 id, + uint8_t int_size, uint8_t long_size, uint8_t pointer_size, + uint8_t size_t_size, uint8_t alignment) +{ + struct marker_data *mdata; + struct marker_info *info, *head; + int found = 0; + + mdata = tf->mdata; if (mdata->markers->len <= id) mdata->markers = g_array_set_size(mdata->markers, @@ -513,6 +521,31 @@ int marker_id_event(LttTrace *trace, GQuark channel, GQuark name, guint16 id, return 0; } +int marker_id_event(LttTrace *trace, GQuark channel, GQuark name, guint16 id, + uint8_t int_size, uint8_t long_size, uint8_t pointer_size, + uint8_t size_t_size, uint8_t alignment) +{ + GArray *group; + int i, ret; + LttTracefile *tf; + + g_debug("Add channel %s event %s %hu\n", g_quark_to_string(channel), + g_quark_to_string(name), id); + + group = g_datalist_id_get_data(&trace->tracefiles, channel); + if (!group) + return -ENOENT; + g_assert(group->len > 0); + for (i = 0; i < group->len; i++) { + tf = &g_array_index (group, LttTracefile, i); + ret = marker_id_tf_event(trace, tf, channel, name, id, int_size, long_size, + pointer_size, size_t_size, alignment); + if (ret) + g_error("Error in marker_id_event"); + } + return 0; +} + struct marker_data *allocate_marker_data(void) { struct marker_data *data; diff --git a/ltt/tracefile.c b/ltt/tracefile.c index 54da7470..2dbbbcf1 100644 --- a/ltt/tracefile.c +++ b/ltt/tracefile.c @@ -544,12 +544,12 @@ static void ltt_tracefile_group_destroy(gpointer data) unsigned int i; LttTracefile *tf; - if (group->len > 0) - destroy_marker_data(g_array_index (group, LttTracefile, 0).mdata); for(i=0; ilen; i++) { tf = &g_array_index (group, LttTracefile, i); - if(tf->cpu_online) + if(tf->cpu_online) { + destroy_marker_data(tf->mdata); ltt_tracefile_close(tf); + } } g_array_free(group, TRUE); } @@ -585,8 +585,7 @@ static int open_tracefiles(LttTrace *trace, gchar *root_path, gchar *relative_pa DIR *dir = opendir(root_path); struct dirent *entry; struct stat stat_buf; - int ret, i; - struct marker_data *mdata; + int ret; gchar path[PATH_MAX]; int path_len; @@ -596,6 +595,7 @@ static int open_tracefiles(LttTrace *trace, gchar *root_path, gchar *relative_pa gchar rel_path[PATH_MAX]; gchar *rel_path_ptr; LttTracefile tmp_tf; + struct marker_data **mdata; if(dir == NULL) { perror(root_path); @@ -658,7 +658,6 @@ static int open_tracefiles(LttTrace *trace, gchar *root_path, gchar *relative_pa g_debug("Tracefile name is %s and number is %u", g_quark_to_string(name), num); - mdata = NULL; tmp_tf.cpu_online = 1; tmp_tf.cpu_num = num; tmp_tf.name = name; @@ -673,9 +672,6 @@ static int open_tracefiles(LttTrace *trace, gchar *root_path, gchar *relative_pa group = g_array_sized_new (FALSE, TRUE, sizeof(LttTracefile), 10); g_datalist_id_set_data_full(&trace->tracefiles, name, group, ltt_tracefile_group_destroy); - mdata = allocate_marker_data(); - if (!mdata) - g_error("Error in allocating marker data"); } /* Add the per cpu tracefile to the named group */ @@ -683,15 +679,13 @@ static int open_tracefiles(LttTrace *trace, gchar *root_path, gchar *relative_pa if(num+1 > old_len) group = g_array_set_size(group, num+1); - g_assert(group->len > 0); - if (!mdata) - mdata = g_array_index (group, LttTracefile, 0).mdata; - g_array_index (group, LttTracefile, num) = tmp_tf; g_array_index (group, LttTracefile, num).event.tracefile = &g_array_index (group, LttTracefile, num); - for (i = 0; i < group->len; i++) - g_array_index (group, LttTracefile, i).mdata = mdata; + mdata = &g_array_index (group, LttTracefile, num).mdata; + *mdata = allocate_marker_data(); + if (!*mdata) + g_error("Error in allocating marker data"); } }