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. ---*/
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; \
}
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 */
// 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,
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 );
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;
};