blob: 49485342ccd932d53b254538f39a1948af0e5062 [file] [log] [blame]
kurtis.heimerl5a872472013-05-31 21:47:25 +00001/*
2* Copyright 2011 Range Networks, Inc.
3* All Rights Reserved.
4*
5* This software is distributed under multiple licenses;
6* see the COPYING file in the main directory for licensing
7* information for this specific distribuion.
8*
9* This use of this software may be subject to additional restrictions.
10* See the LEGAL file in the main directory for details.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15*/
16#ifndef _MEMORYLEAK_
17#define _MEMORYLEAK_ 1
18#include <map>
19#include "ScalarTypes.h"
20#include "Logger.h"
21
22namespace Utils {
23
24struct MemStats {
25 // Enumerates the classes that are checked.
26 // Redundancies are ok, for example, we check BitVector and also
27 // several descendants of BitVector.
28 enum MemoryNames {
29 mZeroIsUnused,
30 mVector,
31 mVectorData,
32 mBitVector,
33 mByteVector,
34 mByteVectorData,
35 mRLCRawBlock,
36 mRLCUplinkDataBlock,
37 mRLCMessage,
38 mRLCMsgPacketDownlinkDummyControlBlock, // Redundant with RLCMessage
39 mTBF,
40 mLlcEngine,
41 mSgsnDownlinkMsg,
42 mRachInfo,
43 mPdpPdu,
44 mFECDispatchInfo,
45 mL3Frame,
46 msignalVector,
47 mSoftVector,
48 mScramblingCode,
49 mURlcDownSdu,
50 mURlcPdu,
51 // Must be last:
52 mMax,
53 };
54 int mMemTotal[mMax]; // In elements, not bytes.
55 int mMemNow[mMax];
56 const char *mMemName[mMax];
57 MemStats();
58 void memChkNew(MemoryNames memIndex, const char *id);
59 void memChkDel(MemoryNames memIndex, const char *id);
60 void text(std::ostream &os);
61 // We would prefer to use an unordered_map, but that requires special compile switches.
62 // What a super great language.
63 typedef std::map<std::string,Int_z> MemMapType;
64 MemMapType mMemMap;
65};
66extern struct MemStats gMemStats;
67extern int gMemLeakDebug;
68
69// This is a memory leak detector.
70// Use by putting RN_MEMCHKNEW and RN_MEMCHKDEL in class constructors/destructors,
71// or use the DEFINE_MEMORY_LEAK_DETECTOR class and add the defined class
72// as an ancestor to the class to be memory leak checked.
73
74struct MemLabel {
75 std::string mccKey;
76 virtual ~MemLabel() {
77 Int_z &tmp = Utils::gMemStats.mMemMap[mccKey]; tmp = tmp - 1;
78 }
79};
80
81#if RN_DISABLE_MEMORY_LEAK_TEST
82#define RN_MEMCHKNEW(type)
83#define RN_MEMCHKDEL(type)
84#define RN_MEMLOG(type,ptr)
85#define DEFINE_MEMORY_LEAK_DETECTOR_CLASS(subClass,checkerClass) \
86 struct checkerClass {};
87#else
88
89#define RN_MEMCHKNEW(type) { Utils::gMemStats.memChkNew(Utils::MemStats::m##type,#type); }
90#define RN_MEMCHKDEL(type) { Utils::gMemStats.memChkDel(Utils::MemStats::m##type,#type); }
91
92#define RN_MEMLOG(type,ptr) { \
93 static std::string key = format("%s_%s:%d",#type,__FILE__,__LINE__); \
94 (ptr)->/* MemCheck##type:: */ mccKey = key; \
95 Utils::gMemStats.mMemMap[key]++; \
96 }
97
98// TODO: The above assumes that checkclass is MemCheck ## subClass
99#define DEFINE_MEMORY_LEAK_DETECTOR_CLASS(subClass,checkerClass) \
100 struct checkerClass : public virtual Utils::MemLabel { \
101 checkerClass() { RN_MEMCHKNEW(subClass); } \
102 virtual ~checkerClass() { \
103 RN_MEMCHKDEL(subClass); \
104 } \
105 };
106
107#endif
108
109} // namespace Utils
110
111#endif