Partial implementation of mallinfo().  It still puts zero in all
the fields, but all the plumbing is now there so that m_mallocfree.c
can fill them in.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@4441 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_mallocfree.c b/coregrind/m_mallocfree.c
index e21ed62..ae73919 100644
--- a/coregrind/m_mallocfree.c
+++ b/coregrind/m_mallocfree.c
@@ -1204,6 +1204,14 @@
    return get_pszB(a, b);
 }
 
+// We cannot return the whole struct as the library function does,
+// because this is called by a client request.  So instead we use
+// a pointer to do call by reference.
+void VG_(mallinfo) ( ThreadId tid, struct vg_mallinfo* mi )
+{
+   // Should do better than this...
+   VG_(memset)(mi, 0x0, sizeof(struct vg_mallinfo));
+}
 
 /*------------------------------------------------------------*/
 /*--- Services layered on top of malloc/free.              ---*/
diff --git a/coregrind/m_replacemalloc/vg_replace_malloc.c b/coregrind/m_replacemalloc/vg_replace_malloc.c
index df5603e..a86b063 100644
--- a/coregrind/m_replacemalloc/vg_replace_malloc.c
+++ b/coregrind/m_replacemalloc/vg_replace_malloc.c
@@ -429,36 +429,18 @@
 PANIC(m_libc_dot_so_dot_6, malloc_get_state);
 PANIC(m_libc_dot_so_dot_6, malloc_set_state);
 
-
-/* Yet another ugly hack.  Cannot include <malloc.h> because we
-   implement functions implemented there with different signatures.
-   This struct definition MUST match the system one. */
-
-/* SVID2/XPG mallinfo structure */
-struct mallinfo {
-   int arena;    /* total space allocated from system */
-   int ordblks;  /* number of non-inuse chunks */
-   int smblks;   /* unused -- always zero */
-   int hblks;    /* number of mmapped regions */
-   int hblkhd;   /* total space in mmapped regions */
-   int usmblks;  /* unused -- always zero */
-   int fsmblks;  /* unused -- always zero */
-   int uordblks; /* total allocated space */
-   int fordblks; /* total non-inuse space */
-   int keepcost; /* top-most, releasable (via malloc_trim) space */
-};
-
+// mi must be static;  if it is auto then Memcheck thinks it is
+// uninitialised when used by the caller of this function, because Memcheck
+// doesn't know that the call to mallinfo fills in mi.
 #define MALLINFO(soname, fnname) \
    \
-   struct mallinfo VG_REPLACE_FUNCTION(soname, fnname) ( void ); \
-   struct mallinfo VG_REPLACE_FUNCTION(soname, fnname) ( void )  \
+   struct vg_mallinfo VG_REPLACE_FUNCTION(soname, fnname) ( void ); \
+   struct vg_mallinfo VG_REPLACE_FUNCTION(soname, fnname) ( void )  \
    { \
-      /* Should really try to return something a bit more meaningful */ \
-      UInt            i; \
-      struct mallinfo mi; \
-      UChar*          pmi = (UChar*)(&mi); \
-      for (i = 0; i < sizeof(mi); i++) \
-         pmi[i] = 0; \
+      static struct vg_mallinfo mi; \
+      MALLOC_TRACE("mallinfo()"); \
+      if (!init_done) init(); \
+      (void)VALGRIND_NON_SIMD_CALL1( info.mallinfo, &mi ); \
       return mi; \
    }
 
diff --git a/coregrind/m_scheduler/scheduler.c b/coregrind/m_scheduler/scheduler.c
index 4b05036..a941685 100644
--- a/coregrind/m_scheduler/scheduler.c
+++ b/coregrind/m_scheduler/scheduler.c
@@ -1027,6 +1027,7 @@
 	 info->tl___builtin_vec_delete = VG_(tdict).tool___builtin_vec_delete;
 
 	 info->arena_payload_szB       = VG_(arena_payload_szB);
+	 info->mallinfo                = VG_(mallinfo);
 	 info->clo_trace_malloc        = VG_(clo_trace_malloc);
 
          SET_CLREQ_RETVAL( tid, 0 );     /* return value is meaningless */
diff --git a/coregrind/pub_core_mallocfree.h b/coregrind/pub_core_mallocfree.h
index 94dcbc6..5167042 100644
--- a/coregrind/pub_core_mallocfree.h
+++ b/coregrind/pub_core_mallocfree.h
@@ -68,6 +68,21 @@
 // greater than 8.
 #define VG_MIN_MALLOC_SZB        8
 
+/* This struct definition MUST match the system one. */
+/* SVID2/XPG mallinfo structure */
+struct vg_mallinfo {
+   int arena;    /* total space allocated from system */
+   int ordblks;  /* number of non-inuse chunks */
+   int smblks;   /* unused -- always zero */
+   int hblks;    /* number of mmapped regions */
+   int hblkhd;   /* total space in mmapped regions */
+   int usmblks;  /* unused -- always zero */
+   int fsmblks;  /* unused -- always zero */
+   int uordblks; /* total allocated space */
+   int fordblks; /* total non-inuse space */
+   int keepcost; /* top-most, releasable (via malloc_trim) space */
+};
+
 extern void* VG_(arena_malloc)  ( ArenaId arena, SizeT nbytes );
 extern void  VG_(arena_free)    ( ArenaId arena, void* ptr );
 extern void* VG_(arena_calloc)  ( ArenaId arena, 
@@ -83,6 +98,8 @@
 
 extern SizeT VG_(arena_payload_szB) ( ThreadId tid, ArenaId aid, void* p );
 
+extern void  VG_(mallinfo) ( ThreadId tid, struct vg_mallinfo* mi );
+
 extern void  VG_(sanity_check_malloc_all) ( void );
 
 extern void  VG_(print_all_arena_stats) ( void );
diff --git a/coregrind/pub_core_replacemalloc.h b/coregrind/pub_core_replacemalloc.h
index e50de51..7f27ce0 100644
--- a/coregrind/pub_core_replacemalloc.h
+++ b/coregrind/pub_core_replacemalloc.h
@@ -51,6 +51,7 @@
    void* (*tl_realloc)             (ThreadId tid, void* p, SizeT size);
 
    SizeT (*arena_payload_szB)      (ThreadId tid, ArenaId aid, void* payload);
+   void  (*mallinfo)               (ThreadId tid, struct vg_mallinfo* mi);
    Bool	clo_trace_malloc;
 };