From 9f797243e1537f470b67cd27ff2030bfd2d89bcb Mon Sep 17 00:00:00 2001 From: yangxx Date: Fri, 19 Dec 2003 21:21:46 +0000 Subject: [PATCH] statistics can be saved/loaded to/from file in each trace directory git-svn-id: http://ltt.polymtl.ca/svn@346 04897980-b3bd-0310-b5e0-8ef037075253 --- ltt/branches/poly/include/lttv/stats.h | 4 + ltt/branches/poly/ltt/tracefile.c | 36 +- ltt/branches/poly/lttv/modules/guiEvents.c | 26 +- .../lttv/modules/guiStatistic/guiStatistic.c | 6 + ltt/branches/poly/lttv/stats.c | 355 ++++++++++++++++++ 5 files changed, 412 insertions(+), 15 deletions(-) diff --git a/ltt/branches/poly/include/lttv/stats.h b/ltt/branches/poly/include/lttv/stats.h index 87130b0f..e732856a 100644 --- a/ltt/branches/poly/include/lttv/stats.h +++ b/ltt/branches/poly/include/lttv/stats.h @@ -132,6 +132,10 @@ gboolean lttv_stats_add_event_hooks(LttvTracesetStats *self); gboolean lttv_stats_remove_event_hooks(LttvTracesetStats *self); +void lttv_stats_save_statistics(LttvTracesetStats *self); + +gboolean lttv_stats_load_statistics(LttvTracesetStats *self); + /* The LttvTracesetStats, LttvTraceStats and LttvTracefileStats types inherit from the corresponding State objects defined in state.h.. */ diff --git a/ltt/branches/poly/ltt/tracefile.c b/ltt/branches/poly/ltt/tracefile.c index d752962a..0af8976a 100644 --- a/ltt/branches/poly/ltt/tracefile.c +++ b/ltt/branches/poly/ltt/tracefile.c @@ -367,6 +367,27 @@ void getCpuFileInfo(LttTrace *t, char* cpu) *are released as well. ****************************************************************************/ +void get_absolute_pathname(const char *pathname, char * abs_pathname) +{ + char * ptr, *ptr1; + size_t size = DIR_NAME_SIZE; + abs_pathname[0] = '\0'; + if(!getcwd(abs_pathname, size)){ + g_warning("Can not get current working directory\n"); + strcat(abs_pathname, pathname); + return; + } + strcat(abs_pathname,"/"); + + ptr = (char*)pathname; + ptr1 = ptr + 1; + while(*ptr == '.' && *ptr1 == '.'){ + ptr += 3; + ptr1 = ptr + 1; + } + strcat(abs_pathname,ptr); +} + LttTrace *ltt_trace_open(const char *pathname) { LttTrace * t; @@ -376,30 +397,33 @@ LttTrace *ltt_trace_open(const char *pathname) char control[DIR_NAME_SIZE]; char cpu[DIR_NAME_SIZE]; char tmp[DIR_NAME_SIZE]; + char abs_path[DIR_NAME_SIZE]; gboolean has_slash = FALSE; + get_absolute_pathname(pathname, abs_path); + //establish the pathname to different directories - if(pathname[strlen(pathname)-1] == '/')has_slash = TRUE; - strcpy(eventdefs,pathname); + if(abs_path[strlen(abs_path)-1] == '/')has_slash = TRUE; + strcpy(eventdefs,abs_path); if(!has_slash)strcat(eventdefs,"/"); strcat(eventdefs,"eventdefs/"); - strcpy(info,pathname); + strcpy(info,abs_path); if(!has_slash)strcat(info,"/"); strcat(info,"info/"); - strcpy(control,pathname); + strcpy(control,abs_path); if(!has_slash)strcat(control,"/"); strcat(control,"control/"); - strcpy(cpu,pathname); + strcpy(cpu,abs_path); if(!has_slash)strcat(cpu,"/"); strcat(cpu,"cpu/"); //new trace t = g_new(LttTrace, 1); sys_description = g_new(LttSystemDescription, 1); - t->pathname = g_strdup(pathname); + t->pathname = g_strdup(abs_path); t->facility_number = 0; t->control_tracefile_number = 0; t->per_cpu_tracefile_number = 0; diff --git a/ltt/branches/poly/lttv/modules/guiEvents.c b/ltt/branches/poly/lttv/modules/guiEvents.c index 078314dd..3cba5411 100644 --- a/ltt/branches/poly/lttv/modules/guiEvents.c +++ b/ltt/branches/poly/lttv/modules/guiEvents.c @@ -65,8 +65,10 @@ typedef struct _RawTraceData{ LttEventPosition *ep; } RawTraceData; -#define RESERVE_BIG_SIZE 1000 -#define RESERVE_SMALL_SIZE 100 +#define RESERVE_BIG_SIZE 1000 +#define RESERVE_SMALL_SIZE 100 +#define RESERVE_SMALL_SIZE_SQUARE RESERVE_SMALL_SIZE*RESERVE_SMALL_SIZE +#define RESERVE_SMALL_SIZE_CUBE RESERVE_SMALL_SIZE*RESERVE_SMALL_SIZE_SQUARE typedef enum _ScrollDirection{ SCROLL_STEP_UP, @@ -876,7 +878,7 @@ void get_test_data(double time_value, guint list_height, ltt_tracefile_seek_position(tf, raw_data->ep); ev = ltt_tracefile_read(tf); start = ltt_event_time(ev); - maxNum = G_MAXULONG; + maxNum = RESERVE_SMALL_SIZE_CUBE; }else{ if(block_num > 1){ ltt_event_position_set(raw_data->ep, block_num-1, 1); @@ -887,7 +889,7 @@ void get_test_data(double time_value, guint list_height, start.tv_sec = 0; start.tv_nsec = 0; } - maxNum = G_MAXULONG; + maxNum = RESERVE_SMALL_SIZE_CUBE; } }else{ if(block_num > count){ @@ -899,7 +901,7 @@ void get_test_data(double time_value, guint list_height, start.tv_sec = 0; start.tv_nsec = 0; } - maxNum = G_MAXULONG; + maxNum = RESERVE_SMALL_SIZE_CUBE; } event_viewer_data->current_event_index = event_viewer_data->start_event_index; @@ -933,7 +935,9 @@ void get_test_data(double time_value, guint list_height, end.tv_nsec = G_MAXULONG; get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE, &size); if(size == 0){ - get_events(event_viewer_data, start, end, G_MAXULONG, &size); + get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_SQUARE,&size); + if(size == 0) + get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_CUBE,&size); } }else size = 1; if(size > 0) event_number = event_viewer_data->start_event_index + 1; @@ -952,7 +956,9 @@ void get_test_data(double time_value, guint list_height, end.tv_nsec = G_MAXULONG; get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE,&size); if(size == 0){ - get_events(event_viewer_data, start, end, G_MAXULONG,&size); + get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_SQUARE,&size); + if(size == 0) + get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_CUBE,&size); } } if(list_height <= event_viewer_data->number_of_events - 1 - event_viewer_data->end_event_index) @@ -985,14 +991,16 @@ void get_test_data(double time_value, guint list_height, ltt_tracefile_seek_position(tf, raw_data->ep); ev = ltt_tracefile_read(tf); start = ltt_event_time(ev); - maxNum = G_MAXULONG; + maxNum = RESERVE_SMALL_SIZE_CUBE; event_viewer_data->current_event_index = 0; get_events(event_viewer_data, start, end, maxNum, &size); event_viewer_data->start_event_index = event_viewer_data->current_event_index; } event_number = event_viewer_data->raw_trace_data_queue->length - list_height; }else if(size == 0){ - get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE*RESERVE_SMALL_SIZE,&size); + get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_SQUARE,&size); + if(size == 0) + get_events(event_viewer_data, start, end, RESERVE_SMALL_SIZE_CUBE,&size); event_number = 0; }else{ event_number = 0; diff --git a/ltt/branches/poly/lttv/modules/guiStatistic/guiStatistic.c b/ltt/branches/poly/lttv/modules/guiStatistic/guiStatistic.c index 432efe3d..cbc16f2c 100644 --- a/ltt/branches/poly/lttv/modules/guiStatistic/guiStatistic.c +++ b/ltt/branches/poly/lttv/modules/guiStatistic/guiStatistic.c @@ -312,6 +312,11 @@ gui_statistic(MainWindow *parent_window, LttvTracesetSelector * s, char* key) G_OBJECT(statistic_viewer_data->hpaned_v), TRACESET_TIME_SPAN, &statistic_viewer_data->time_span); + + if(statistic_viewer_data->calculate_stats){ + if(lttv_stats_load_statistics(statistic_viewer_data->stats)) + statistic_viewer_data->calculate_stats = FALSE; + } if(statistic_viewer_data->calculate_stats == FALSE){ statistic_viewer_data->size = 1; @@ -559,6 +564,7 @@ gboolean statistic_show_viewer(void * hook_data, void * call_data) show_traceset_stats(statistic_viewer_data); if(statistic_viewer_data->calculate_stats){ statistic_remove_context_hooks(statistic_viewer_data,tsc); + lttv_stats_save_statistics((LttvTracesetStats*)tsc); } } diff --git a/ltt/branches/poly/lttv/stats.c b/ltt/branches/poly/lttv/stats.c index eaa2041c..4265853d 100644 --- a/ltt/branches/poly/lttv/stats.c +++ b/ltt/branches/poly/lttv/stats.c @@ -1,9 +1,12 @@ +#include #include #include #include #include +#define BUF_SIZE 256 + GQuark LTTV_STATS_PROCESS_UNKNOWN, LTTV_STATS_PROCESSES, @@ -823,3 +826,355 @@ void lttv_stats_destroy() { } +void lttv_stats_save_attribute(LttvAttribute *attr, char *indent, FILE * fp) +{ + LttvAttributeType type; + LttvAttributeValue value; + LttvAttributeName name; + char type_value[BUF_SIZE]; + int i, nb_attr, flag; + + nb_attr = lttv_attribute_get_number(attr); + for(i=0;itv_sec, + value.v_time->tv_nsec); + break; + case LTTV_POINTER: + sprintf(type_value, "POINTER\0"); + break; + case LTTV_STRING: + sprintf(type_value, "%s\0", *value.v_string); + break; + default: + flag = 0; + break; + } + if(flag == 0) continue; + fprintf(fp,"%s",indent,type,g_quark_to_string(name)); + fprintf(fp,"%s",type_value); + fprintf(fp," \n"); + } + +} + +void lttv_stats_save_statistics(LttvTracesetStats *self) +{ + LttvTracesetStats *tscs = self; + LttvTraceStats *tcs; + LttvTraceset *traceset = tscs->parent.parent.ts; + LttvAttributeType type; + LttvAttributeValue value; + LttvAttributeName name; + + char filename[BUF_SIZE]; + FILE * fp; + char indent[10][24]= {" ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + }; + + + int i, j, k, l, m, n, nb_trace, nb_process, nb_cpu, nb_mode_type, nb_submode; + + LttvAttribute *main_tree, *processes_tree, *process_tree, *cpus_tree, + *cpu_tree, *mode_tree, *mode_types_tree, *submodes_tree, + *submode_tree, *event_types_tree; + + nb_trace = lttv_traceset_number(traceset); + + for(i = 0 ; i < nb_trace ; i++) { + tcs = (LttvTraceStats *)(tscs->parent.parent.traces[i]); + + filename[0] = '\0'; + strcat(filename,ltt_trace_name(tcs->parent.parent.t)); + strcat(filename,"/statistics.xml"); + fp = fopen(filename,"w"); + if(!fp){ + g_warning("can not open the file %s for saving statistics\n", filename); + exit(1); + } + + main_tree = tcs->stats; + processes_tree = lttv_attribute_find_subdir(main_tree, LTTV_STATS_PROCESSES); + nb_process = lttv_attribute_get_number(processes_tree); + + fprintf(fp, " \n",g_quark_to_string(LTTV_STATS_PROCESSES)); //root NODE + + for(j = 0 ; j < nb_process ; j++) { + type = lttv_attribute_get(processes_tree, j, &name, &value); + process_tree = LTTV_ATTRIBUTE(*(value.v_gobject)); + + fprintf(fp,"%s \n",indent[0],g_quark_to_string(name)); //process NODE + lttv_stats_save_attribute(process_tree,indent[1], fp); + fprintf(fp,"%s \n", indent[1],g_quark_to_string(LTTV_STATS_CPU)); //cpus NODE + + cpus_tree = lttv_attribute_find_subdir(process_tree, LTTV_STATS_CPU); + nb_cpu = lttv_attribute_get_number(cpus_tree); + + for(k = 0 ; k < nb_cpu ; k++) { + type = lttv_attribute_get(cpus_tree, k, &name, &value); + cpu_tree = LTTV_ATTRIBUTE(*(value.v_gobject)); + + fprintf(fp,"%s \n",indent[2],g_quark_to_string(name)); //cpu NODE + lttv_stats_save_attribute(cpu_tree,indent[3], fp); + fprintf(fp,"%s \n",indent[3],g_quark_to_string(LTTV_STATS_MODE_TYPES)); //mode_types NODE + + mode_types_tree = lttv_attribute_find_subdir(cpu_tree,LTTV_STATS_MODE_TYPES); + nb_mode_type = lttv_attribute_get_number(mode_types_tree); + + for(l = 0 ; l < nb_mode_type ; l++) { + type = lttv_attribute_get(mode_types_tree, l, &name, &value); + mode_tree = LTTV_ATTRIBUTE(*(value.v_gobject)); + + fprintf(fp,"%s \n",indent[4],g_quark_to_string(name)); //mode NODE + lttv_stats_save_attribute(mode_tree,indent[5], fp); + fprintf(fp,"%s \n",indent[5],g_quark_to_string(LTTV_STATS_SUBMODES)); //sub_modes NODE + + submodes_tree = lttv_attribute_find_subdir(mode_tree,LTTV_STATS_SUBMODES); + nb_submode = lttv_attribute_get_number(submodes_tree); + + for(m = 0 ; m < nb_submode ; m++) { + type = lttv_attribute_get(submodes_tree, m, &name, &value); + submode_tree = LTTV_ATTRIBUTE(*(value.v_gobject)); + fprintf(fp,"%s \n",indent[6],g_quark_to_string(name)); //sub_mode NODE + lttv_stats_save_attribute(submode_tree,indent[7], fp); + fprintf(fp,"%s \n",indent[7],g_quark_to_string(LTTV_STATS_EVENT_TYPES)); //event_types NODE + + event_types_tree = lttv_attribute_find_subdir(submode_tree, LTTV_STATS_EVENT_TYPES); + lttv_stats_save_attribute(event_types_tree,indent[8], fp); + + fprintf(fp,"%s \n",indent[7]); //event_types NODE + fprintf(fp,"%s \n",indent[6]); //sub_mode NODE + } + fprintf(fp,"%s \n",indent[5]); //sub_modes NODE + fprintf(fp,"%s \n",indent[4]); //mode NODE + } + fprintf(fp,"%s \n",indent[3]); //mode_type NODE + fprintf(fp,"%s \n",indent[2]); //cpu NODE + } + fprintf(fp,"%s \n",indent[1]); //cpus NODE + fprintf(fp,"%s \n", indent[0]); //process NODE + } + fprintf(fp, "\n"); //root NODE + fclose(fp); + } +} + + +/* Functions to parse statistic.xml file (using glib xml parser) */ + +typedef struct _ParserStruct{ + GPtrArray * attribute; + LttvAttributeType type; + LttvAttributeName name; +} ParserStruct; + +static void stats_parser_start_element (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + ParserStruct * parser = (ParserStruct *)user_data; + int len; + LttvAttributeType type; + LttvAttributeName name; + LttvAttribute * parent_att, *new_att; + + len = parser->attribute->len; + parent_att = (LttvAttribute *)g_ptr_array_index (parser->attribute, len-1); + + if(strcmp("NODE", element_name) == 0){ + type = LTTV_GOBJECT; + name = g_quark_from_string(attribute_values[0]); + new_att = lttv_attribute_find_subdir(parent_att,name); + g_ptr_array_add(parser->attribute, (gpointer)new_att); + }else if(strcmp("VALUE", element_name) == 0){ + parser->type = (LttvAttributeType) atoi(attribute_values[0]); + parser->name = g_quark_from_string(attribute_values[1]); + }else{ + g_warning("This is not statistics.xml file\n"); + exit(1); + } +} + +static void stats_parser_end_element (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + ParserStruct * parser = (ParserStruct *)user_data; + int len; + LttvAttribute * parent_att; + + len = parser->attribute->len; + parent_att = (LttvAttribute *)g_ptr_array_index (parser->attribute, len-1); + + if(strcmp("NODE", element_name) == 0){ + g_ptr_array_remove_index(parser->attribute, len-1); + }else if(strcmp("VALUE", element_name) == 0){ + }else{ + g_warning("This is not statistics.xml file\n"); + exit(1); + } + +} + +static void stats_parser_characters (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error) +{ + ParserStruct * parser = (ParserStruct *)user_data; + LttvAttributeValue value; + int len; + LttvAttribute * parent_att; + char *pos; + + pos = (char*)text; + for(len=0;lenattribute->len; + parent_att = (LttvAttribute *)g_ptr_array_index (parser->attribute, len-1); + if(!lttv_attribute_find(parent_att,parser->name, parser->type, &value)){ + g_warning("can not find value\n"); + exit(1); + } + + switch(parser->type) { + case LTTV_INT: + *value.v_int = atoi(text); + break; + case LTTV_UINT: + *value.v_uint = (unsigned)atoi(text); + break; + case LTTV_LONG: + *value.v_long = atol(text); + break; + case LTTV_ULONG: + *value.v_ulong = (unsigned long)atol(text); + break; + case LTTV_FLOAT: + *value.v_float = atof(text); + break; + case LTTV_DOUBLE: + *value.v_float = atof(text); + break; + case LTTV_TIME: + pos = strrchr(text,'.'); + if(pos){ + *pos = '\0'; + pos++; + value.v_time->tv_sec = atol(text); + value.v_time->tv_nsec = atol(pos); + }else{ + g_warning("The time value format is wrong\n"); + exit(1); + } + break; + case LTTV_POINTER: + break; + case LTTV_STRING: + *value.v_string = g_strdup(text); + break; + default: + break; + } + +} + +gboolean lttv_stats_load_statistics(LttvTracesetStats *self) +{ + FILE * fp; + char buf[BUF_SIZE]; + LttvTracesetStats *tscs = self; + LttvTraceStats *tcs; + LttvTraceset *traceset = tscs->parent.parent.ts; + char filename[BUF_SIZE]; + + GMarkupParseContext * context; + GError * error; + GMarkupParser markup_parser = + { + stats_parser_start_element, + stats_parser_end_element, + stats_parser_characters, + NULL, /* passthrough */ + NULL /* error */ + }; + + int i, nb_trace; + LttvAttribute *main_tree; + ParserStruct a_parser_struct; + a_parser_struct.attribute = g_ptr_array_new(); + + nb_trace = lttv_traceset_number(traceset); + + for(i = 0 ; i < nb_trace ; i++) { + tcs = (LttvTraceStats *)(tscs->parent.parent.traces[i]); + + filename[0] = '\0'; + strcat(filename,ltt_trace_name(tcs->parent.parent.t)); + strcat(filename,"/statistics.xml"); + fp = fopen(filename,"r"); + if(!fp){ + g_warning("can not open the file %s for reading statistics\n", filename); + return FALSE; + } + + main_tree = tcs->stats; + g_ptr_array_add(a_parser_struct.attribute,(gpointer)main_tree); + + context = g_markup_parse_context_new(&markup_parser, 0, (gpointer)&a_parser_struct, NULL); + + while(fgets(buf,BUF_SIZE, fp) != NULL){ + if(!g_markup_parse_context_parse(context, buf, BUF_SIZE, &error)){ + g_warning("Can not parse xml file: \n%s\n", error->message); + exit(1); + } + } + fclose(fp); + } + + sum_stats(NULL, (void *)self); + + return TRUE; +} -- 2.34.1