Author: njn
Date: 2007-10-09 07:49:05 +0100 (Tue, 09 Oct 2007)
New Revision: 6969

Log:
- Added --detailed-freq and --max-snapshots options.
- Increased max --depth value from 50 to 200.
- Adding some sanity checking on numeric command line options.

Modified:
   branches/MASSIF2/massif/ms_main.c
   branches/MASSIF2/massif/tests/Makefile.am


Modified: branches/MASSIF2/massif/ms_main.c
===================================================================
--- branches/MASSIF2/massif/ms_main.c   2007-10-09 03:11:48 UTC (rev 6968)
+++ branches/MASSIF2/massif/ms_main.c   2007-10-09 06:49:05 UTC (rev 6969)
@@ -44,9 +44,6 @@
 // - do a graph-drawing test
 // - write a good basic test that shows how the tool works, suitable for
 //   documentation
-// - make everything configurable, eg. min/max number of snapshots (which
-//   also determine culling proportion), frequency of detailed snapshots,
-//   etc.
 //
 // Misc:
 // - with --heap=no, --heap-admin still counts.  should it?
@@ -326,7 +323,7 @@
 //--- Command line args                                    ---//
 //------------------------------------------------------------//
 
-#define MAX_DEPTH       50
+#define MAX_DEPTH       200
 
 typedef enum { TimeMS, TimeB } TimeUnit;
 
@@ -339,12 +336,14 @@
    }
 }
 
-static Bool clo_heap        = True;
-static UInt clo_heap_admin  = 8;
-static Bool clo_stacks      = True;
-static UInt clo_depth       = 8;       // XXX: too low?
-static UInt clo_threshold   = 100;     // 100 == 1%
-static UInt clo_time_unit   = TimeMS;
+static Bool clo_heap          = True;
+static UInt clo_heap_admin    = 8;
+static Bool clo_stacks        = True;
+static UInt clo_depth         = 8;       // XXX: too low?
+static UInt clo_threshold     = 100;     // 100 == 1%
+static UInt clo_time_unit     = TimeMS;
+static UInt clo_detailed_freq = 10;
+static UInt clo_max_snapshots = 100;
 
 static XArray* args_for_massif;
 
@@ -353,15 +352,16 @@
    // Remember the arg for later use.
    VG_(addToXA)(args_for_massif, &arg);
 
-        VG_BOOL_CLO(arg, "--heap",       clo_heap)
-   else VG_BOOL_CLO(arg, "--stacks",     clo_stacks)
+        VG_BOOL_CLO(arg, "--heap",   clo_heap)
+   else VG_BOOL_CLO(arg, "--stacks", clo_stacks)
 
-   // XXX: currently allows negative heap admin sizes!  Abort if negative.
-   else VG_NUM_CLO (arg, "--heap-admin", clo_heap_admin)
-   else VG_BNUM_CLO(arg, "--depth",      clo_depth, 1, MAX_DEPTH)
+   else VG_NUM_CLO(arg, "--heap-admin", clo_heap_admin)
+   else VG_NUM_CLO(arg, "--depth",      clo_depth)
 
    // XXX: use a fractional number, so no division by 100
-   else VG_NUM_CLO(arg, "--threshold",   clo_threshold)
+   else VG_NUM_CLO(arg, "--threshold",     clo_threshold)
+   else VG_NUM_CLO(arg, "--detailed-freq", clo_detailed_freq)
+   else VG_NUM_CLO(arg, "--max-snapshots", clo_max_snapshots)
 
    else if (VG_CLO_STREQ(arg, "--time-unit=ms")) clo_time_unit = TimeMS;
    else if (VG_CLO_STREQ(arg, "--time-unit=B"))  clo_time_unit = TimeB;
@@ -389,6 +389,8 @@
 "                               total size, <n>=0 shows all nodes) [100]\n"
 "    --time-unit=ms|B          time unit, milliseconds or bytes\n"
 "                               alloc'd/dealloc'd on the heap [ms]\n"
+"    --detailed-freq=<N>       every Nth snapshot should be detailed [10]\n"
+"    --max-snapshots=<N>       maximum number of snapshots recorded [100]\n"
    );
    VG_(replacement_malloc_print_usage)();
 }
@@ -652,7 +654,7 @@
 // Nb: it's possible to end up with an empty trace, eg. if 'main' is marked
 // as an alloc-fn.  This is ok.
 static
-Int get_IPs( ThreadId tid, Bool is_custom_alloc, Addr ips[], Int max_ips)
+Int get_IPs( ThreadId tid, Bool is_custom_alloc, Addr ips[])
 {
    Int n_ips, i, n_alloc_fns_removed = 0;
    Int overestimate;
@@ -756,12 +758,12 @@
 // Gets an XCon and puts it in the tree.  Returns the XCon's bottom-XPt.
 static XPt* get_XCon( ThreadId tid, Bool is_custom_alloc )
 {
-   static Addr ips[MAX_IPS];     // Static to minimise stack size.
+   Addr ips[MAX_IPS];
    Int i;
    XPt* xpt = alloc_xpt;
 
    // After this call, the IPs we want are in ips[0]..ips[n_ips-1].
-   Int n_ips = get_IPs(tid, is_custom_alloc, ips, MAX_IPS);
+   Int n_ips = get_IPs(tid, is_custom_alloc, ips);
 
    // Now do the search/insertion of the XCon. 'L' is the loop counter,
    // being the index into ips[].
@@ -822,11 +824,6 @@
 // limit again, we again cull and then take them even more slowly, and so
 // on.
 
-// XXX: if the program is really short, we may get no detailed snapshots...
-// that's bad, do something about it.
-#define MAX_N_SNAPSHOTS        100  // Keep it even, for simplicity
-#define DETAILED_SNAPSHOT_FREQ  10  // Every Nth snapshot will be detailed
-
 // Time is measured either in ms or bytes, depending on the --time-unit
 // option.  It's a Long because it can exceed 32-bits reasonably easily, and
 // because we need to allow negative values to represent unset times.
@@ -853,8 +850,8 @@
    }                       // otherwise NULL
    Snapshot;
 
-static UInt     next_snapshot_i = 0;   // Index of where next snapshot will go.
-static Snapshot snapshots[MAX_N_SNAPSHOTS];
+static UInt      next_snapshot_i = 0;  // Index of where next snapshot will go.
+static Snapshot* snapshots;            // Array of snapshots.
 
 static Bool is_snapshot_in_use(Snapshot* snapshot)
 {
@@ -898,7 +895,7 @@
    for (i = 0; i < next_snapshot_i; i++) {
       tl_assert( is_snapshot_in_use( & snapshots[i] ));
    }
-   for (    ; i < MAX_N_SNAPSHOTS; i++) {
+   for (    ; i < clo_max_snapshots; i++) {
       tl_assert(!is_snapshot_in_use( & snapshots[i] ));
    }
 }
@@ -974,14 +971,14 @@
    // Sets j to the index of the first not-yet-removed snapshot at or after i
    #define FIND_SNAPSHOT(i, j) \
       for (j = i; \
-           j < MAX_N_SNAPSHOTS && !is_snapshot_in_use(&snapshots[j]); \
+           j < clo_max_snapshots && !is_snapshot_in_use(&snapshots[j]); \
            j++) { }
 
    VERB(1, "Culling...");
 
    // First we remove enough snapshots by clearing them in-place.  Once
    // that's done, we can slide the remaining ones down.
-   for (i = 0; i < MAX_N_SNAPSHOTS/2; i++) {
+   for (i = 0; i < clo_max_snapshots/2; i++) {
       // Find the snapshot representing the smallest timespan.  The timespan
       // for snapshot n = d(N-1,N)+d(N,N+1), where d(A,B) is the time between
       // snapshot A and B.  We don't consider the first and last snapshots for
@@ -996,7 +993,7 @@
       FIND_SNAPSHOT(j+1, jn);
       min_timespan = 0x7fffffffffffffffLL;
       min_j        = -1;
-      while (jn < MAX_N_SNAPSHOTS) {
+      while (jn < clo_max_snapshots) {
          Time timespan = snapshots[jn].time - snapshots[jp].time;
          tl_assert(timespan >= 0);
          // Nb: We never cull the peak snapshot.
@@ -1027,7 +1024,7 @@
    // i.  Then slide everything down.
    for (i = 0;  is_snapshot_in_use( &snapshots[i] ); i++) { }
    for (j = i; !is_snapshot_in_use( &snapshots[j] ); j++) { }
-   for (  ; j < MAX_N_SNAPSHOTS; j++) {
+   for (  ; j < clo_max_snapshots; j++) {
       if (is_snapshot_in_use( &snapshots[j] )) {
          snapshots[i++] = snapshots[j];
          clear_snapshot(&snapshots[j]);
@@ -1075,7 +1072,7 @@
    // Print remaining snapshots, if necessary.
    if (VG_(clo_verbosity) > 1) {
       VERB(1, "Finished culling (%3d of %3d deleted)",
-         n_deleted, MAX_N_SNAPSHOTS);
+         n_deleted, clo_max_snapshots);
       for (i = 0; i < next_snapshot_i; i++) {
          VERB_snapshot(1, "  post-cull", i);
       }
@@ -1170,7 +1167,7 @@
    static Time min_time_interval = 0;
    // Zero allows startup snapshot.
    static Time earliest_possible_time_of_next_snapshot = 0;
-   static Int n_snapshots_until_next_detailed = DETAILED_SNAPSHOT_FREQ - 1;
+   static Int n_snapshots_since_last_detailed = 0;
 
    Snapshot* snapshot;
    Bool      is_detailed;
@@ -1184,7 +1181,7 @@
          n_skipped_snapshots_since_last_snapshot++;
          return;
       }
-      is_detailed = (0 == n_snapshots_until_next_detailed);
+      is_detailed = (clo_detailed_freq-1 == n_snapshots_since_last_detailed);
       break;
 
     case Peak: {
@@ -1212,9 +1209,9 @@
 
    // Record if it was detailed.
    if (is_detailed) {
-      n_snapshots_until_next_detailed = DETAILED_SNAPSHOT_FREQ - 1;
+      n_snapshots_since_last_detailed = 0;
    } else {
-      n_snapshots_until_next_detailed--;
+      n_snapshots_since_last_detailed++;
    }
 
    // Update peak data, if it's a Peak snapshot.
@@ -1248,7 +1245,7 @@
 
    // Cull the entries, if our snapshot table is full.
    next_snapshot_i++;
-   if (MAX_N_SNAPSHOTS == next_snapshot_i) {
+   if (clo_max_snapshots == next_snapshot_i) {
       min_time_interval = cull_snapshots();
    }
 
@@ -1875,10 +1872,34 @@
 
 static void ms_post_clo_init(void)
 {
-   Int i = 1;
+   Int i;
    Word alloc_fn_word;
 
+   // Check options.
+   if (clo_heap_admin < 0 || clo_heap_admin > 1024) {
+      VG_(message)(Vg_UserMsg, "--heap-admin must be between 0 and 1024");
+      VG_(err_bad_option)("--heap-admin");
+   }
+   if (clo_depth < 1 || clo_depth > MAX_DEPTH) {
+      VG_(message)(Vg_UserMsg, "--depth must be between 1 and %d", MAX_DEPTH);
+      VG_(err_bad_option)("--depth");
+   }
+   if (clo_threshold < 0 || clo_threshold > 10000) {
+      VG_(message)(Vg_UserMsg, "--threshold must be between 0 and 10000");
+      VG_(err_bad_option)("--threshold");
+   }
+   if (clo_detailed_freq < 1 || clo_detailed_freq > 10000) {
+      VG_(message)(Vg_UserMsg, "--detailed-freq must be between 1 and 10000");
+      VG_(err_bad_option)("--detailed-freq");
+   }
+   if (clo_max_snapshots < 10 || clo_max_snapshots > 1000) {
+      VG_(message)(Vg_UserMsg, "--max-snapshots must be between 10 and 1000");
+      VG_(err_bad_option)("--max-snapshots");
+   }
+
+   // Print alloc-fns, if necessary.
    if (VG_(clo_verbosity) > 1) {
+      i = 1;
       VERB(1, "alloc-fns:");
       VG_(OSetWord_ResetIter)(alloc_fns);
       while ( VG_(OSetWord_Next)(alloc_fns, &alloc_fn_word) ) {
@@ -1887,19 +1908,24 @@
       }
    }
 
+   // Events to track.
    if (clo_stacks) {
-      // Events to track.
       VG_(track_new_mem_stack)        ( new_mem_stack        );
       VG_(track_die_mem_stack)        ( die_mem_stack        );
       VG_(track_new_mem_stack_signal) ( new_mem_stack_signal );
       VG_(track_die_mem_stack_signal) ( die_mem_stack_signal );
    }
+
+   // Initialise snapshot array, and sanity-check it.
+   snapshots = VG_(malloc)(sizeof(Snapshot) * clo_max_snapshots);
+   for (i = 0; i < clo_max_snapshots; i++) {
+      clear_snapshot( & snapshots[i] );
+   }
+   sanity_check_snapshots_array();
 }
 
 static void ms_pre_clo_init(void)
 {
-   Int i;
-
    VG_(details_name)            ("Massif");
    VG_(details_version)         (NULL);
    VG_(details_description)     ("a space profiler");
@@ -1936,12 +1962,6 @@
    // Dummy node at top of the context structure.
    alloc_xpt = new_XPt(/*ip*/0, /*parent*/NULL);
 
-   // Initialise snapshot array, and sanity check it.
-   for (i = 0; i < MAX_N_SNAPSHOTS; i++) {
-      clear_snapshot( & snapshots[i] );
-   }
-   sanity_check_snapshots_array();
-
    // Initialise alloc_fns.
    init_alloc_fns();
 

Modified: branches/MASSIF2/massif/tests/Makefile.am
===================================================================
--- branches/MASSIF2/massif/tests/Makefile.am   2007-10-09 03:11:48 UTC (rev 
6968)
+++ branches/MASSIF2/massif/tests/Makefile.am   2007-10-09 06:49:05 UTC (rev 
6969)
@@ -20,6 +20,7 @@
        long-time.post.exp long-time.stderr.exp long-time.vgtest \
        null.post.exp null.stderr.exp null.vgtest \
        one.post.exp one.stderr.exp one.vgtest \
+       params.post.exp params.stderr.exp params.vgtest \
        peak.post.exp peak.stderr.exp peak.vgtest \
        realloc.post.exp realloc.stderr.exp realloc.vgtest \
        thresholds_0_0.post.exp   thresholds_0_0.stderr.exp   
thresholds_0_0.vgtest \


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Valgrind-developers mailing list
Valgrind-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/valgrind-developers

Reply via email to