Something I realised recently:  in C, iterators are much better than
higher-order functions for traversing data structures.  The higher-order
approach is too clumsy due to the lack of polymorphism and closures;  you
have to use void* too much and it is more verbose than it should be.

Hence, I replaced all the uses of HT_first_match() and
HT_apply_to_all_nodes() with equivalent uses of the hashtable iterator.
Also replaced higher-order traversal functions for Memcheck's freed-list
and the thread stacks with iterators.  That last change changes the
core/tool interface, so I've increased the version number.







git-svn-id: svn://svn.valgrind.org/valgrind/trunk@4415 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/massif/ms_main.c b/massif/ms_main.c
index 7a278ca..e0ebe0a 100644
--- a/massif/ms_main.c
+++ b/massif/ms_main.c
@@ -835,13 +835,6 @@
 static Census censi[MAX_N_CENSI];
 static UInt   curr_census = 0;
 
-// Must return False so that all stacks are traversed
-static Bool count_stack_size( Addr stack_min, Addr stack_max, void *cp )
-{
-   *(UInt *)cp  += (stack_max - stack_min);
-   return False;
-}
-
 static UInt get_xtree_size(XPt* xpt, UInt ix)
 {
    UInt i;
@@ -1065,9 +1058,13 @@
 
    // Stack(s) ---------------------------------------------------------
    if (clo_stacks) {
+      ThreadId tid;
+      Addr     stack_min, stack_max;
       census->stacks_space = sigstacks_space;
-      // slightly abusing this function
-      VG_(first_matching_thread_stack)( count_stack_size, &census->stacks_space );
+      VG_(thread_stack_reset_iter)();
+      while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) {
+         census->stacks_space += (stack_max - stack_min);
+      }
    }
 
    // Finish, update interval if necessary -----------------------------