forked from RangeNetworks/CommonLibs
-
Notifications
You must be signed in to change notification settings - Fork 1
/
MemoryLeak.h
119 lines (107 loc) · 3.16 KB
/
MemoryLeak.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
/*
* Copyright 2011, 2014 Range Networks, Inc.
* All Rights Reserved.
*
* This software is distributed under multiple licenses;
* see the COPYING file in the main directory for licensing
* information for this specific distribution.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
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.
*/
#ifndef _MEMORYLEAK_
#define _MEMORYLEAK_ 1
#include <map>
#include "ScalarTypes.h"
#include "Logger.h"
namespace Utils {
struct MemStats {
// Enumerates the classes that are checked.
// Redundancies are ok, for example, we check BitVector and also
// several descendants of BitVector.
enum MemoryNames {
mZeroIsUnused,
mVector,
mVectorData,
mBitVector,
mByteVector,
mByteVectorData,
mRLCRawBlock,
mRLCUplinkDataBlock,
mRLCMessage,
mRLCMsgPacketDownlinkDummyControlBlock, // Redundant with RLCMessage
mTBF,
mLlcEngine,
mSgsnDownlinkMsg,
mRachInfo,
mPdpPdu,
mFECDispatchInfo,
mL3Frame,
msignalVector,
mSoftVector,
mScramblingCode,
mURlcDownSdu,
mURlcPdu,
mSipBase,
mSipDialog,
mSipMessage,
mSipTransaction,
mMMContext,
mMMUser,
mTranEntry,
mMachineBase,
// Must be last:
mMax,
};
int mMemTotal[mMax]; // In elements, not bytes.
int mMemNow[mMax];
const char *mMemName[mMax];
MemStats();
void memChkNew(MemoryNames memIndex, const char *id);
void memChkDel(MemoryNames memIndex, const char *id);
void text(std::ostream &os);
// We would prefer to use an unordered_map, but that requires special compile switches.
// What a super great language.
typedef std::map<std::string,Int_z> MemMapType;
MemMapType mMemMap;
};
extern struct MemStats gMemStats;
extern int gMemLeakDebug;
// This is a memory leak detector.
// Use by putting RN_MEMCHKNEW and RN_MEMCHKDEL in class constructors/destructors,
// or use the DEFINE_MEMORY_LEAK_DETECTOR class and add the defined class
// as an ancestor to the class to be memory leak checked.
struct MemLabel {
std::string mccKey;
virtual ~MemLabel() {
Int_z &tmp = Utils::gMemStats.mMemMap[mccKey]; tmp = tmp - 1;
}
};
#if RN_DISABLE_MEMORY_LEAK_TEST
#define RN_MEMCHKNEW(type)
#define RN_MEMCHKDEL(type)
#define RN_MEMLOG(type,ptr)
#define DEFINE_MEMORY_LEAK_DETECTOR_CLASS(subClass,checkerClass) \
struct checkerClass {};
#else
#define RN_MEMCHKNEW(type) { Utils::gMemStats.memChkNew(Utils::MemStats::m##type,#type); }
#define RN_MEMCHKDEL(type) { Utils::gMemStats.memChkDel(Utils::MemStats::m##type,#type); }
#define RN_MEMLOG(type,ptr) { \
static std::string key = format("%s_%s:%d",#type,__FILE__,__LINE__); \
(ptr)->/* MemCheck##type:: */ mccKey = key; \
Utils::gMemStats.mMemMap[key]++; \
}
// TODO: The above assumes that checkclass is MemCheck ## subClass
#define DEFINE_MEMORY_LEAK_DETECTOR_CLASS(subClass,checkerClass) \
struct checkerClass : public virtual Utils::MemLabel { \
checkerClass() { RN_MEMCHKNEW(subClass); } \
virtual ~checkerClass() { \
RN_MEMCHKDEL(subClass); \
} \
};
#endif
} // namespace Utils
#endif