3e9c2093c9e852d4fef4b437aef293f40209bcf4
[occt.git] / src / NCollection / NCollection_BaseAllocator.cxx
1 // File:        NCollection_BaseAllocator.cxx
2 // Created:     Fri Apr 12 12:53:28 2002
3 // Author:      Alexander KARTOMIN (akm)
4 //              <a-kartomin@opencascade.com>
5 // Purpose:     Implementation of the BaseAllocator class
6
7 #include <NCollection_BaseAllocator.hxx>
8 #include <NCollection_DataMap.hxx>
9 #include <NCollection_List.hxx>
10 #include <Standard_Mutex.hxx>
11
12 IMPLEMENT_STANDARD_HANDLE(NCollection_BaseAllocator,MMgt_TShared)
13 IMPLEMENT_STANDARD_RTTIEXT(NCollection_BaseAllocator,MMgt_TShared)
14
15 //=======================================================================
16 //function : Allocate
17 //purpose  : Standard allocation
18 //=======================================================================
19
20 void* NCollection_BaseAllocator::Allocate(const size_t size)
21
22   return Standard::Allocate(size);
23 }
24
25 //=======================================================================
26 //function : Free
27 //purpose  : Standard deallocation
28 //=======================================================================
29
30 void  NCollection_BaseAllocator::Free(void *anAddress)
31
32   if (anAddress) Standard::Free((Standard_Address&)anAddress); 
33 }
34
35 //=======================================================================
36 //function : CommonBaseAllocator
37 //purpose  : Creates the only one BaseAllocator
38 //=======================================================================
39
40 const Handle(NCollection_BaseAllocator)& 
41        NCollection_BaseAllocator::CommonBaseAllocator(void)
42
43   static Handle(NCollection_BaseAllocator) pAllocator = 
44     new NCollection_BaseAllocator;
45   return pAllocator;
46 }
47
48 // global variable to ensure that allocator will be created during loading the library
49 static Handle(NCollection_BaseAllocator) theAllocInit = 
50   NCollection_BaseAllocator::CommonBaseAllocator();
51
52 //=======================================================================
53 //function : StandardCallBack
54 //purpose  : Callback function to register alloc/free calls
55 //=======================================================================
56
57 struct StorageInfo
58 {
59   Standard_Size roundSize;
60   int nbAlloc;
61   int nbFree;
62   StorageInfo()
63     : roundSize(0), nbAlloc(0), nbFree(0) {}
64   StorageInfo(Standard_Size theSize)
65     : roundSize(theSize), nbAlloc(0), nbFree(0) {}
66 };
67
68 static NCollection_DataMap<Standard_Size, StorageInfo> StorageMap;
69
70 void NCollection_BaseAllocator::StandardCallBack
71                     (const Standard_Boolean theIsAlloc,
72                      const Standard_Address /*theStorage*/,
73                      const Standard_Size theRoundSize,
74                      const Standard_Size /*theSize*/)
75 {
76   static int aLock = 0;
77   if (aLock)
78     return;
79   aLock = 1;
80   if (!StorageMap.IsBound(theRoundSize))
81   {
82     StorageInfo aEmpty(theRoundSize);
83     StorageMap.Bind(theRoundSize, aEmpty);
84   }
85   StorageInfo& aInfo = StorageMap(theRoundSize);
86   if (theIsAlloc)
87     aInfo.nbAlloc++;
88   else
89     aInfo.nbFree++;
90   aLock = 0;
91 }
92
93 //=======================================================================
94 //function : PrintMemUsageStatistics
95 //purpose  : Prints memory usage statistics cumulated by StandardCallBack
96 //=======================================================================
97
98 void NCollection_BaseAllocator::PrintMemUsageStatistics()
99 {
100   // sort by roundsize
101   NCollection_List<StorageInfo> aColl;
102   NCollection_List<StorageInfo>::Iterator itLst;
103   NCollection_DataMap<Standard_Size, StorageInfo>::Iterator itMap(StorageMap);
104   for (; itMap.More(); itMap.Next())
105   {
106     for (itLst.Init(aColl); itLst.More(); itLst.Next())
107       if (itMap.Value().roundSize < itLst.Value().roundSize)
108         break;
109     if (itLst.More())
110       aColl.InsertBefore(itMap.Value(), itLst);
111     else
112       aColl.Append(itMap.Value());
113   }
114   Standard_Size aTotAlloc = 0;
115   Standard_Size aTotLeft = 0;
116   // print
117   printf("%12s %12s %12s %12s %12s\n",
118          "BlockSize", "NbAllocated", "NbLeft", "Allocated", "Left");
119   for (itLst.Init(aColl); itLst.More(); itLst.Next())
120   {
121     const StorageInfo& aInfo = itLst.Value();
122     Standard_Integer nbLeft = aInfo.nbAlloc - aInfo.nbFree;
123     Standard_Size aSizeAlloc = aInfo.nbAlloc * aInfo.roundSize;
124     Standard_Size aSizeLeft = nbLeft * aInfo.roundSize;
125     printf("%12d %12d %12d %12d %12d\n", aInfo.roundSize,
126            aInfo.nbAlloc, nbLeft, aSizeAlloc, aSizeLeft);
127     aTotAlloc += aSizeAlloc;
128     aTotLeft += aSizeLeft;
129   }
130   printf("%12s %12s %12s %12d %12d\n", "Total:", "", "",
131          aTotAlloc, aTotLeft);
132   fflush(stdout);
133 }