statistics can be saved/loaded to/from file in each trace directory
authoryangxx <yangxx@04897980-b3bd-0310-b5e0-8ef037075253>
Fri, 19 Dec 2003 21:21:46 +0000 (21:21 +0000)
committeryangxx <yangxx@04897980-b3bd-0310-b5e0-8ef037075253>
Fri, 19 Dec 2003 21:21:46 +0000 (21:21 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@346 04897980-b3bd-0310-b5e0-8ef037075253

ltt/branches/poly/include/lttv/stats.h
ltt/branches/poly/ltt/tracefile.c
ltt/branches/poly/lttv/modules/guiEvents.c
ltt/branches/poly/lttv/modules/guiStatistic/guiStatistic.c
ltt/branches/poly/lttv/stats.c

index 87130b0f21b005a86fc699cd225d3cd9e6b2549c..e732856a1f9d8cc9eccacdb574d83f35a1b6f4f2 100644 (file)
@@ -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.. */
index d752962acc61b1864b030e767a4315cf7e5663d7..0af8976a170b4f6537f5139d63c4bb5e33950b67 100644 (file)
@@ -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;
index 078314dd013bdf2d598c92005b2b2f600ba16721..3cba5411512a2361aacdf3643acd0cd0e08b3a04 100644 (file)
@@ -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;
index 432efe3d3695c5d12e049535a8673b6e579da0d7..cbc16f2cfa737b6532e92c55f5c77fee24be0284 100644 (file)
@@ -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);
     }
   }
 
index eaa2041ceb5485cf969581f14161584d5578d971..4265853d83bab764b3ff032d674f7ff65db7156c 100644 (file)
@@ -1,9 +1,12 @@
 
+#include <stdio.h>
 #include <lttv/stats.h>
 #include <ltt/facility.h>
 #include <ltt/trace.h>
 #include <ltt/event.h>
 
+#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;i<nb_attr;i++){
+    flag = 1;
+    type = lttv_attribute_get(attr, i, &name, &value);
+    switch(type) {
+      case LTTV_INT:
+        sprintf(type_value, "%d\0", *value.v_int);
+        break;
+      case LTTV_UINT:
+        sprintf(type_value, "%u\0", *value.v_uint);
+        break;
+      case LTTV_LONG:
+        sprintf(type_value, "%ld\0", *value.v_long);
+        break;
+      case LTTV_ULONG:
+        sprintf(type_value, "%lu\0", *value.v_ulong);
+        break;
+      case LTTV_FLOAT:
+        sprintf(type_value, "%f\0", (double)*value.v_float);
+        break;
+      case LTTV_DOUBLE:
+        sprintf(type_value, "%f\0", *value.v_double);
+        break;
+      case LTTV_TIME:
+        sprintf(type_value, "%10u.%09u\0", value.v_time->tv_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<VALUE type=\"%d\" name=\"%s\">",indent,type,g_quark_to_string(name));
+    fprintf(fp,"%s",type_value);
+    fprintf(fp,"</VALUE> \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, "<NODE name=\"%s\"> \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<NODE name=\"%s\"> \n",indent[0],g_quark_to_string(name)); //process NODE   
+      lttv_stats_save_attribute(process_tree,indent[1], fp);
+      fprintf(fp,"%s<NODE name=\"%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<NODE name=\"%s\"> \n",indent[2],g_quark_to_string(name)); //cpu NODE
+       lttv_stats_save_attribute(cpu_tree,indent[3], fp);
+       fprintf(fp,"%s<NODE name=\"%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<NODE name=\"%s\"> \n",indent[4],g_quark_to_string(name)); //mode NODE
+         lttv_stats_save_attribute(mode_tree,indent[5], fp);
+         fprintf(fp,"%s<NODE name=\"%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<NODE name=\"%s\"> \n",indent[6],g_quark_to_string(name)); //sub_mode NODE
+           lttv_stats_save_attribute(submode_tree,indent[7], fp);
+           fprintf(fp,"%s<NODE name=\"%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</NODE> \n",indent[7]); //event_types NODE
+           fprintf(fp,"%s</NODE> \n",indent[6]); //sub_mode NODE
+          }
+         fprintf(fp,"%s</NODE> \n",indent[5]); //sub_modes NODE
+         fprintf(fp,"%s</NODE> \n",indent[4]); //mode NODE
+        }
+       fprintf(fp,"%s</NODE> \n",indent[3]); //mode_type NODE
+       fprintf(fp,"%s</NODE> \n",indent[2]); //cpu NODE
+      }
+      fprintf(fp,"%s</NODE> \n",indent[1]); //cpus NODE
+      fprintf(fp,"%s</NODE> \n", indent[0]); //process NODE
+    }
+    fprintf(fp, "</NODE>\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;len<text_len;len++){
+    if(isspace(*pos)){
+      pos++;
+      continue;
+    }
+    break;
+  }
+  if(strlen(pos) == 0)return;
+
+  len = parser->attribute->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;
+}
This page took 0.031724 seconds and 4 git commands to generate.