a19d589f4fa83b312a75c4a753a497b45f19840f
[occt.git] / src / MMgt / MMgt_StackManager.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <MMgt_StackManager.ixx>
24 #include <Standard_ProgramError.hxx>
25
26 #ifdef HAVE_MALLOC_H
27 # include <malloc.h>
28 #endif
29
30 #ifdef TRACE
31 #define  SHALLOWDUMP ShallowDump(cout)
32 #else
33 #define  SHALLOWDUMP
34 #endif
35
36 static class _Element 
37 {
38  public:
39   _Element() {};
40
41   Standard_Address myNext;
42
43 } *anElement = new _Element;
44
45 //============================================================================
46
47 //============================================================================
48 MMgt_StackManager::MMgt_StackManager()
49 {
50   myFreeListSize = sizeof(_Element);
51   myFreeList = (Standard_Address)calloc((int)(myFreeListSize+1),
52                                         sizeof(myFreeList));
53 }
54
55 //============================================================================
56 void MMgt_StackManager::Destructor() 
57 {
58   SHALLOWDUMP;
59
60   Purge();
61   free((char*) myFreeList);
62   myFreeListSize = 0;
63
64   SHALLOWDUMP;
65 }
66
67 //============================================================================
68 void MMgt_StackManager::ShallowDump(Standard_OStream& s) const 
69 {
70   Standard_Address aFree;
71   Standard_Integer i, NbFree;
72   
73   s << "Begin class MMgt_StackManager\n" << endl
74     << "\t... Size:" << myFreeListSize << endl;
75
76   //==== A loop for Dumping all the storage in the Free List ===========
77   for(i=sizeof(Standard_Address); i<= myFreeListSize; i++){
78     aFree = ((Standard_Address *)myFreeList)[i];
79     
80     NbFree = 0;
81     //==== A loop for deallocating all the storage with the same size =======
82     while(aFree){
83       aFree = ((_Element *)aFree)->myNext;
84       NbFree++;
85     }
86     if(NbFree) s<< "\t... ["<< i<< "]: ("<< NbFree<< ") Free Block "<< endl;
87   }
88   s << "End class MMgt_StackManager" << endl;
89 }
90
91 //============================================================================
92 MMgt_StackManager MMgt_StackManager::ShallowCopy() const
93 {
94   Standard_ProgramError::Raise
95     ("Attempt to make a ShallowCopy of a 'MMgt_StackManager'");
96   return *this;
97 }
98
99 //============================================================================
100 Standard_Address MMgt_StackManager::Allocate(const Standard_Integer aSize)
101 {
102   Standard_Address aStack;
103
104   if(aSize <= myFreeListSize && ((void* *)myFreeList)[aSize] != NULL){
105
106     //==== There is the free storage in the Free List, so we use it ==========
107     aStack = ((Standard_Address *)myFreeList)[aSize];
108     ((Standard_Address *)myFreeList)[aSize] = ((_Element *)aStack)->myNext;
109
110     //==== The storage is set to 0 ===========================================
111     memset(aStack,0,(int)aSize);
112
113   } else {
114
115     //==== There is no storage to be used, so we allocated it from "heap" ====
116     aStack = (void *)calloc((int)aSize, sizeof(char));
117   }
118   
119   return aStack;
120 }
121
122 //============================================================================
123 void MMgt_StackManager::Free(Standard_Address& aStack, 
124                              const Standard_Integer aSize)
125 {
126    //==== Only the Storage large than a 'Element' can be used ================
127    if((unsigned int ) aSize > sizeof(_Element)){
128
129      if(aSize > myFreeListSize) {
130
131        //==== If there is no storage of this size in FreeList ================
132        myFreeList=(Standard_Address)realloc((char *)myFreeList,
133                                             (int)(aSize+1)*sizeof(myFreeList));
134
135        //==== Initialize to "NULL" the new case of FreeList =================
136        for(Standard_Integer i=myFreeListSize+1; i<=aSize; i++){
137          ((Standard_Address *)myFreeList)[i] = NULL;
138        }
139
140        myFreeListSize = aSize;
141      }
142
143      //==== Recycling the storage in the Free List ===========================
144      anElement->myNext = ((Standard_Address *)myFreeList)[aSize];
145
146      memcpy((char *)aStack, (char *)anElement, sizeof(_Element));
147      ((Standard_Address *)myFreeList)[aSize] = aStack;
148    } else {
149      //==== The littles storgas will be managed by system ====================
150      free((char *) aStack);
151    }
152
153    //==== Nullify ============================================================
154    aStack = NULL;
155 }
156
157 void MMgt_StackManager::Purge()
158 {
159   Standard_Address aFree;
160   Standard_Address aOther;
161   
162   Standard_Integer i;
163   
164   //==== A loop for deallocating all the storage in the Free List ===========
165   for(i=sizeof(Standard_Address); i<= myFreeListSize; i++){
166     aFree = ((Standard_Address *)myFreeList)[i];
167     
168     //==== A loop for deallocating all the storage with the same size =======
169     while(aFree){
170       aOther = aFree;
171       aFree = ((_Element *)aFree)->myNext;
172       free((char *)aOther); 
173     }
174     
175     ((Standard_Address *)myFreeList)[i] = NULL;
176   }
177 }
178