Skip to content

Commit

Permalink
- track allocation of objects
Browse files Browse the repository at this point in the history
  - dump this information on ENOMEM or if the debug flag is passed in

Signed-off-by: Mark Fasheh <mfasheh@suse.de>
  • Loading branch information
Mark Fasheh committed Sep 4, 2014
1 parent 6072d43 commit 7cde4e4
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 22 deletions.
51 changes: 51 additions & 0 deletions debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 { \
Expand Down
4 changes: 4 additions & 0 deletions duperemove.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -952,5 +953,8 @@ int main(int argc, char **argv)
print_dupes_table(&res);

out:
if (ret == ENOMEM || debug)
print_mem_stats();

return ret;
}
8 changes: 5 additions & 3 deletions filerec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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--;
}
}
Expand Down
13 changes: 8 additions & 5 deletions hash-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -82,17 +85,17 @@ 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)
return ENOMEM;

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;
}

Expand Down Expand Up @@ -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--;
}

Expand Down
24 changes: 10 additions & 14 deletions results-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
}
Expand All @@ -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;

Expand Down Expand Up @@ -204,7 +200,7 @@ static void remove_extent(struct results_tree *res, struct extent *extent)

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
Expand All @@ -217,7 +213,7 @@ static void remove_extent(struct results_tree *res, struct extent *extent)

if (p->de_num_dupes == 0) {
rb_erase(&p->de_node, &res->root);
free(p);
free_dupe_extents(p);
res->num_dupes--;
}
}
Expand Down
11 changes: 11 additions & 0 deletions util.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <ctype.h>
#include <inttypes.h>

#include "debug.h"
#include "util.h"

int human_readable = 0;
Expand Down Expand Up @@ -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();
}

0 comments on commit 7cde4e4

Please sign in to comment.