Commit 7cde4e48 authored by Mark Fasheh's avatar Mark Fasheh

- track allocation of objects

  - dump this information on ENOMEM or if the debug flag is passed in
Signed-off-by: 's avatarMark Fasheh <mfasheh@suse.de>
parent 6072d43c
......@@ -6,6 +6,57 @@
extern int verbose;
extern int debug;
/*
* Rudimentary tracking of object allocation. Use this within a c file
* to declare the tracking variable and the print function body.
*
* In addition, debug.h needs to declare an extern and function
* prototype (see below) and print_mem_stats() in util.c needs an
* update.
*/
#define declare_alloc_tracking(_type) \
extern long long num_##_type; \
static inline struct _type *malloc_##_type(void) \
{ \
struct _type *t = malloc(sizeof(struct _type)); \
if (t) \
num_##_type++; \
return t; \
} \
static inline struct _type *calloc_##_type(int n) \
{ \
struct _type *t = calloc(n, sizeof(struct _type)); \
if (t) \
num_##_type += n; \
return t; \
} \
static inline void free_##_type(struct _type *t) \
{ \
if (t) { \
num_##_type--; \
free(t); \
} \
} \
void show_allocs_##_type(void) \
{ \
long size = sizeof(struct _type); \
unsigned long long total = size * num_##_type; \
printf("struct " #_type " num: %llu sizeof: %lu total: %llu\n", \
num_##_type, size, total); \
}
#define declare_alloc_tracking_header(_type) \
long long num_##_type; \
void show_allocs_##_type(void);
declare_alloc_tracking_header(file_block);
declare_alloc_tracking_header(dupe_blocks_list);
declare_alloc_tracking_header(dupe_extents);
declare_alloc_tracking_header(extent);
declare_alloc_tracking_header(filerec);
/* Can be called anywhere we want to dump the above statistics */
void print_mem_stats(void);
#define dprintf(args...) if (debug) printf(args)
#define vprintf(args...) if (verbose) printf(args)
#define abort_lineno() do { \
......
......@@ -724,6 +724,7 @@ static void record_match(struct results_tree *res, unsigned char *digest,
if (ret) {
abort_on(ret != ENOMEM); /* Only error possible here. */
fprintf(stderr, "Out of memory while processing results\n");
print_mem_stats();
exit(ENOMEM);
}
......@@ -952,5 +953,8 @@ int main(int argc, char **argv)
print_dupes_table(&res);
out:
if (ret == ENOMEM || debug)
print_mem_stats();
return ret;
}
......@@ -26,6 +26,8 @@ struct list_head filerec_list;
struct rb_root filerec_by_inum = RB_ROOT;
unsigned long long num_filerecs = 0ULL;
declare_alloc_tracking(filerec);
void init_filerec(void)
{
INIT_LIST_HEAD(&filerec_list);
......@@ -75,12 +77,12 @@ static struct filerec *find_filerec(uint64_t inum)
static struct filerec *filerec_alloc_insert(const char *filename, uint64_t inum)
{
struct filerec *file = calloc(1, sizeof(*file));
struct filerec *file = calloc_filerec(1);
if (file) {
file->filename = strdup(filename);
if (!file->filename) {
free(file);
free_filerec(file);
return NULL;
}
......@@ -120,7 +122,7 @@ void filerec_free(struct filerec *file)
if (!RB_EMPTY_NODE(&file->inum_node))
rb_erase(&file->inum_node, &filerec_by_inum);
free(file);
free_filerec(file);
num_filerecs--;
}
}
......
......@@ -31,6 +31,9 @@
#include "hash-tree.h"
#include "debug.h"
declare_alloc_tracking(file_block);
declare_alloc_tracking(dupe_blocks_list);
static void insert_block_list(struct hash_tree *tree,
struct dupe_blocks_list *list)
{
......@@ -82,7 +85,7 @@ static struct dupe_blocks_list *find_block_list(struct hash_tree *tree,
int insert_hashed_block(struct hash_tree *tree, unsigned char *digest,
struct filerec *file, uint64_t loff)
{
struct file_block *e = malloc(sizeof(*e));
struct file_block *e = malloc_file_block();
struct dupe_blocks_list *d;
if (!e)
......@@ -90,9 +93,9 @@ int insert_hashed_block(struct hash_tree *tree, unsigned char *digest,
d = find_block_list(tree, digest);
if (d == NULL) {
d = calloc(1, sizeof(*d));
d = calloc_dupe_blocks_list(1);
if (!d) {
free(e);
free_file_block(e);
return ENOMEM;
}
......@@ -138,10 +141,10 @@ static void remove_hashed_block(struct hash_tree *tree,
rb_erase(&blocklist->dl_node, &tree->root);
tree->num_hashes--;
free(blocklist);
free_dupe_blocks_list(blocklist);
}
free(block);
free_file_block(block);
tree->num_blocks--;
}
......
......@@ -29,23 +29,19 @@
#include "filerec.h"
#include "results-tree.h"
#include "debug.h"
static struct extent *_alloc_extent(void)
{
struct extent *e = calloc(1, sizeof(*e));
INIT_LIST_HEAD(&e->e_list);
INIT_LIST_HEAD(&e->e_file_extents);
#include "debug.h"
return e;
}
declare_alloc_tracking(dupe_extents);
declare_alloc_tracking(extent);
static struct extent *alloc_extent(struct filerec *file, uint64_t loff)
{
struct extent *e = _alloc_extent();
struct extent *e = calloc_extent(1);
if (e) {
INIT_LIST_HEAD(&e->e_list);
INIT_LIST_HEAD(&e->e_file_extents);
e->e_file = file;
e->e_loff = loff;
}
......@@ -136,7 +132,7 @@ static void insert_extent_list_free(struct dupe_extents *dext,
struct extent **e)
{
if (insert_extent_list(dext, *e)) {
free(*e);
free_extent(*e);
*e = NULL;
}
}
......@@ -156,7 +152,7 @@ int insert_result(struct results_tree *res, unsigned char *digest,
dext = find_dupe_extents(res, digest, len);
if (!dext) {
dext = calloc(1, sizeof(*dext));
dext = calloc_dupe_extents(1);
if (!dext)
return ENOMEM;
......@@ -204,7 +200,7 @@ again:
list_del_init(&extent->e_list);
list_del_init(&extent->e_file_extents);
free(extent);
free_extent(extent);
if (p->de_num_dupes == 1) {
/* It doesn't make sense to have one extent in a dup
......@@ -217,7 +213,7 @@ again:
if (p->de_num_dupes == 0) {
rb_erase(&p->de_node, &res->root);
free(p);
free_dupe_extents(p);
res->num_dupes--;
}
}
......
......@@ -25,6 +25,7 @@
#include <ctype.h>
#include <inttypes.h>
#include "debug.h"
#include "util.h"
int human_readable = 0;
......@@ -115,3 +116,13 @@ int pretty_size_snprintf(uint64_t size, char *str, size_t str_bytes)
return snprintf(str, str_bytes, "%.1f%s", fraction,
size_strs[num_divs]);
}
void print_mem_stats(void)
{
printf("Duperemove memory usage statistics:\n");
show_allocs_file_block();
show_allocs_dupe_blocks_list();
show_allocs_dupe_extents();
show_allocs_extent();
show_allocs_filerec();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment