X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=ltt%2Fbranches%2Fpoly%2Fltt%2Fmarker.c;h=9da520eb1d1cdb013ff94bc281460e7915c0f208;hb=37e04c8b7ef67f18b24835bbc01ece0de0be5a72;hp=f1053d8ccdb850346eb587071110d97d3cd38bc8;hpb=03dab2c12579a972e206610262ea870dd37e1a5a;p=lttv.git diff --git a/ltt/branches/poly/ltt/marker.c b/ltt/branches/poly/ltt/marker.c index f1053d8c..9da520eb 100644 --- a/ltt/branches/poly/ltt/marker.c +++ b/ltt/branches/poly/ltt/marker.c @@ -1,10 +1,27 @@ -/* - * Marker support code. +/* This file is part of the Linux Trace Toolkit viewer + * Copyright (C) 2007 Mathieu Desnoyers + * + * Complete rewrite from the original version made by XangXiu Yang. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License Version 2.1 as published by the Free Software Foundation. * - * Mathieu Desnoyers, August 2007 - * License: LGPL. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -63,7 +80,7 @@ static inline const char *parse_trace_type(struct marker_info *info, *trace_type = LTT_TYPE_STRING; goto parse_end; case 'p': - *trace_type = LTT_TYPE_UNSIGNED_INT; + *trace_type = LTT_TYPE_POINTER; *trace_size = info->pointer_size; goto parse_end; case 'd': @@ -167,7 +184,7 @@ static inline const char *parse_c_type(struct marker_info *info, *c_type = LTT_TYPE_STRING; goto parse_end; case 'p': - *c_type = LTT_TYPE_UNSIGNED_INT; + *c_type = LTT_TYPE_POINTER; *c_size = info->pointer_size; goto parse_end; case 'd': @@ -233,6 +250,7 @@ static inline long add_type(struct marker_info *info, switch (trace_type) { case LTT_TYPE_SIGNED_INT: case LTT_TYPE_UNSIGNED_INT: + case LTT_TYPE_POINTER: field->size = trace_size; field->alignment = trace_size; field->attributes = attributes; @@ -267,15 +285,22 @@ long marker_update_fields_offsets(struct marker_info *info, const char *data) unsigned int i; long offset = 0; - for (i = 0; i < info->fields->len; i++) { + /* Find the last field with a static offset, then update from there. */ + for (i = info->fields->len - 1; i >= 0; i--) { field = &g_array_index(info->fields, struct marker_field, i); + if (field->static_offset) { + offset = field->offset; + break; + } + } - if (field->static_offset) - continue; + for (; i < info->fields->len; i++) { + field = &g_array_index(info->fields, struct marker_field, i); switch (field->type) { case LTT_TYPE_SIGNED_INT: case LTT_TYPE_UNSIGNED_INT: + case LTT_TYPE_POINTER: field->offset = offset + ltt_align(offset, field->alignment, info->alignment); offset = field->offset + field->size; @@ -346,7 +371,7 @@ static void format_parse(const char *fmt, struct marker_info *info) } break; case ' ': - if (name_end && name_begin) { + if (!name_end && name_begin) { name_end = fmt; if (name) g_free(name); @@ -356,7 +381,7 @@ static void format_parse(const char *fmt, struct marker_info *info) } break; /* Skip white spaces */ default: - if (!name) { + if (!name_begin) { name_begin = fmt; name_end = NULL; } @@ -380,17 +405,25 @@ int marker_parse_format(const char *format, struct marker_info *info) int marker_format_event(LttTrace *trace, GQuark name, const char *format) { struct marker_info *info; + char *fquery; + char *fcopy; - info = g_hash_table_lookup(trace->markers_hash, (gconstpointer)name); - if (!info) - g_error("Got marker format \"%s\", but marker name \"%s\" has no ID yet. " - "Kernel issue.", - format, name); + fquery = marker_get_format_from_name(trace, name); + if (fquery) { + if (strcmp(fquery, format) != 0) + g_error("Marker format mismatch \"%s\" vs \"%s\" for marker %s. " + "Kernel issue.", fquery, format, g_quark_to_string(name)); + else + return 0; /* Already exists. Nothing to do. */ + } + fcopy = g_new(char, strlen(format)+1); + strcpy(fcopy, format); + g_hash_table_insert(trace->markers_format_hash, (gpointer)name, + (gpointer)fcopy); + + info = marker_get_info_from_name(trace, name); for (; info != NULL; info = info->next) { - if (info->format) - g_free(info->format); - info->format = g_new(char, strlen(format)+1); - strcpy(info->format, format); + info->format = fcopy; if (marker_parse_format(format, info)) g_error("Error parsing marker format \"%s\" for marker \"%s\"", format, g_quark_to_string(name)); @@ -405,8 +438,9 @@ int marker_id_event(LttTrace *trace, GQuark name, guint16 id, struct marker_info *info, *head; int found = 0; - if (trace->markers->len < id) - trace->markers = g_array_set_size(trace->markers, id+1); + if (trace->markers->len <= id) + trace->markers = g_array_set_size(trace->markers, + max(trace->markers->len * 2, id + 1)); info = &g_array_index(trace->markers, struct marker_info, id); info->name = name; info->int_size = int_size; @@ -414,17 +448,24 @@ int marker_id_event(LttTrace *trace, GQuark name, guint16 id, info->pointer_size = pointer_size; info->size_t_size = size_t_size; info->alignment = alignment; + info->fields = NULL; info->next = NULL; - head = g_hash_table_lookup(trace->markers_hash, (gconstpointer)name); + info->format = marker_get_format_from_name(trace, name); + if (info->format && marker_parse_format(info->format, info)) + g_error("Error parsing marker format \"%s\" for marker \"%s\"", + info->format, g_quark_to_string(name)); + head = marker_get_info_from_name(trace, name); if (!head) - g_hash_table_insert(trace->markers_hash, (gpointer)name, info); + g_hash_table_insert(trace->markers_hash, (gpointer)name, + (gpointer)(gulong)id); else { struct marker_info *iter; for (iter = head; iter != NULL; iter = iter->next) if (iter->name == name) found = 1; if (!found) { - g_hash_table_replace(trace->markers_hash, (gpointer)name, info); + g_hash_table_replace(trace->markers_hash, (gpointer)name, + (gpointer)(gulong)id); info->next = head; } } @@ -439,6 +480,10 @@ int allocate_marker_data(LttTrace *trace) if (!trace->markers) return -ENOMEM; trace->markers_hash = g_hash_table_new(g_direct_hash, g_direct_equal); + if (!trace->markers_hash) + return -ENOMEM; + trace->markers_format_hash = g_hash_table_new_full(g_direct_hash, + g_direct_equal, NULL, g_free); if (!trace->markers_hash) return -ENOMEM; return 0; @@ -451,11 +496,10 @@ void destroy_marker_data(LttTrace *trace) for (i=0; imarkers->len; i++) { info = &g_array_index(trace->markers, struct marker_info, i); - if (info->format) - g_free(info->format); if (info->fields) g_array_free(info->fields, TRUE); } g_array_free(trace->markers, TRUE); g_hash_table_destroy(trace->markers_hash); + g_hash_table_destroy(trace->markers_format_hash); }