-
Notifications
You must be signed in to change notification settings - Fork 82
/
memstats.h
132 lines (123 loc) · 3.72 KB
/
memstats.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* memstats.h
*
* Copyright (C) 2016 SUSE. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
*/
#ifndef __MEMSTATS_H__
#define __MEMSTATS_H__
#include "glib.h"
/*
* Rudimentary tracking of object allocation. Use this within a c file
* to declare the tracking variable and the print function body.
*
* In addition, memstats.h needs to declare an extern and function
* prototype (see below) and print_mem_stats() in memstats.c needs an
* update.
*/
#ifdef DEBUG_BUILD
#define LOCK_MEMSTATS
#endif
static inline void increment_counters(unsigned long long *num_type,
unsigned long long *max_type,
unsigned long long count, GMutex *mutex [[maybe_unused]])
{
#ifdef LOCK_MEMSTATS
g_mutex_lock(mutex);
#endif
(*num_type) += count;
if ((*num_type) > (*max_type))
(*max_type) = *num_type;
#ifdef LOCK_MEMSTATS
g_mutex_unlock(mutex);
#endif
}
static inline void decrement_counters(unsigned long long *num_type,
GMutex *mutex [[maybe_unused]])
{
#ifdef LOCK_MEMSTATS
g_mutex_lock(mutex);
#endif
(*num_type)--;
#ifdef LOCK_MEMSTATS
g_mutex_unlock(mutex);
#endif
}
#define declare_alloc_tracking(_type) \
static GMutex alloc_##_type##_mutex; \
unsigned long long num_##_type = 0; \
unsigned long long max_##_type = 0; \
static inline struct _type *malloc_##_type(void) \
{ \
struct _type *t = malloc(sizeof(struct _type)); \
if (t) \
increment_counters(&num_##_type, &max_##_type, 1ULL, \
&alloc_##_type##_mutex); \
return t; \
} \
static inline struct _type *calloc_##_type(int n) \
{ \
struct _type *t = calloc(n, sizeof(struct _type)); \
if (t) \
increment_counters(&num_##_type, &max_##_type, n, \
&alloc_##_type##_mutex); \
return t; \
} \
static inline void free_##_type(struct _type *t) \
{ \
if (t) { \
decrement_counters(&num_##_type, &alloc_##_type##_mutex); \
free(t); \
} \
} \
void show_allocs_##_type(void) \
{ \
long size = sizeof(struct _type); \
unsigned long long total = size * num_##_type; \
unsigned long long max_total = size * max_##_type; \
printf("struct " #_type " num: %llu sizeof: %lu total: %llu " \
"max: %llu max total: %llu\n", \
num_##_type, size, total, max_##_type, max_total); \
}
#define declare_alloc_tracking_header(_type) \
extern unsigned long long num_##_type; \
extern unsigned long long max_##_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);
declare_alloc_tracking_header(filerec_token);
declare_alloc_tracking_header(file_hash_head);
declare_alloc_tracking_header(find_dupes_cmp);
/* Can be called anywhere we want to dump the above statistics */
void print_mem_stats(void);
static inline void *malloc_count(size_t size, unsigned long long *num_type,
unsigned long long *max_type)
{
void *obj = malloc(size);
if (obj) {
(*num_type)++;
if (num_type > max_type)
*max_type = *num_type;
}
return obj;
}
static inline void *calloc_count(size_t size, unsigned long long *num_type)
{
void *obj = malloc(size);
if (obj)
(*num_type)++;
return obj;
}
#endif /* __MEMSTATS_H__ */