b311480e |
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 | |
7fd59977 |
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 | //============================================================================ |
37 | //==== There are two declaration of classes just for protections ============= |
38 | //============================================================================ |
39 | |
40 | class _BaseElement { |
41 | public: |
42 | virtual void M1() =0; |
43 | virtual void M2() =0; |
44 | virtual void M3() =0; |
45 | virtual void M4() =0; |
46 | virtual void M5() =0; |
47 | virtual void M6() =0; |
48 | virtual void M7() =0; |
49 | virtual void M8() =0; |
50 | virtual void M9() =0; |
51 | virtual void M10()=0; |
52 | }; |
53 | |
54 | static class _Element: public _BaseElement |
55 | { |
56 | public: |
57 | _Element() {}; |
58 | void Msg() |
59 | {Standard_ProgramError::Raise("Attempt to access to a 'deleted' object");} |
60 | void M1() {Msg();} |
61 | void M2() {Msg();} |
62 | void M3() {Msg();} |
63 | void M4() {Msg();} |
64 | void M5() {Msg();} |
65 | void M6() {Msg();} |
66 | void M7() {Msg();} |
67 | void M8() {Msg();} |
68 | void M9() {Msg();} |
69 | void M10(){Msg();} |
70 | |
71 | Standard_Address myNext; |
72 | |
73 | } *anElement = new _Element; |
74 | |
75 | //============================================================================ |
76 | |
77 | //============================================================================ |
78 | MMgt_StackManager::MMgt_StackManager() |
79 | { |
80 | myFreeListSize = sizeof(_Element); |
81 | myFreeList = (Standard_Address)calloc((int)(myFreeListSize+1), |
82 | sizeof(myFreeList)); |
83 | } |
84 | |
85 | //============================================================================ |
86 | void MMgt_StackManager::Destructor() |
87 | { |
88 | SHALLOWDUMP; |
89 | |
90 | Purge(); |
91 | free((char*) myFreeList); |
92 | myFreeListSize = 0; |
93 | |
94 | SHALLOWDUMP; |
95 | } |
96 | |
97 | //============================================================================ |
98 | void MMgt_StackManager::ShallowDump(Standard_OStream& s) const |
99 | { |
100 | Standard_Address aFree; |
101 | Standard_Integer i, NbFree; |
102 | |
103 | s << "Begin class MMgt_StackManager\n" << endl |
104 | << "\t... Size:" << myFreeListSize << endl; |
105 | |
106 | //==== A loop for Dumping all the storage in the Free List =========== |
107 | for(i=sizeof(Standard_Address); i<= myFreeListSize; i++){ |
108 | aFree = ((Standard_Address *)myFreeList)[i]; |
109 | |
110 | NbFree = 0; |
111 | //==== A loop for deallocating all the storage with the same size ======= |
112 | while(aFree){ |
113 | aFree = ((_Element *)aFree)->myNext; |
114 | NbFree++; |
115 | } |
116 | if(NbFree) s<< "\t... ["<< i<< "]: ("<< NbFree<< ") Free Block "<< endl; |
117 | } |
118 | s << "End class MMgt_StackManager" << endl; |
119 | } |
120 | |
121 | //============================================================================ |
122 | MMgt_StackManager MMgt_StackManager::ShallowCopy() const |
123 | { |
124 | Standard_ProgramError::Raise |
125 | ("Attempt to make a ShallowCopy of a 'MMgt_StackManager'"); |
126 | return *this; |
127 | } |
128 | |
129 | //============================================================================ |
130 | Standard_Address MMgt_StackManager::Allocate(const Standard_Integer aSize) |
131 | { |
132 | Standard_Address aStack; |
133 | |
134 | if(aSize <= myFreeListSize && ((void* *)myFreeList)[aSize] != NULL){ |
135 | |
136 | //==== There is the free storage in the Free List, so we use it ========== |
137 | aStack = ((Standard_Address *)myFreeList)[aSize]; |
138 | ((Standard_Address *)myFreeList)[aSize] = ((_Element *)aStack)->myNext; |
139 | |
140 | //==== The storage is set to 0 =========================================== |
141 | memset(aStack,0,(int)aSize); |
142 | |
143 | } else { |
144 | |
145 | //==== There is no storage to be used, so we allocated it from "heap" ==== |
146 | aStack = (void *)calloc((int)aSize, sizeof(char)); |
147 | } |
148 | |
149 | return aStack; |
150 | } |
151 | |
152 | //============================================================================ |
153 | void MMgt_StackManager::Free(Standard_Address& aStack, |
154 | const Standard_Integer aSize) |
155 | { |
156 | //==== Only the Storage large than a 'Element' can be used ================ |
157 | if((unsigned int ) aSize > sizeof(_Element)){ |
158 | |
159 | if(aSize > myFreeListSize) { |
160 | |
161 | //==== If there is no storage of this size in FreeList ================ |
162 | myFreeList=(Standard_Address)realloc((char *)myFreeList, |
163 | (int)(aSize+1)*sizeof(myFreeList)); |
164 | |
165 | //==== Initialize to "NULL" the new case of FreeList ================= |
166 | for(Standard_Integer i=myFreeListSize+1; i<=aSize; i++){ |
167 | ((Standard_Address *)myFreeList)[i] = NULL; |
168 | } |
169 | |
170 | myFreeListSize = aSize; |
171 | } |
172 | |
173 | //==== Recycling the storage in the Free List =========================== |
174 | anElement->myNext = ((Standard_Address *)myFreeList)[aSize]; |
175 | |
176 | memcpy((char *)aStack, (char *)anElement, sizeof(_Element)); |
177 | ((Standard_Address *)myFreeList)[aSize] = aStack; |
178 | } else { |
179 | //==== The littles storgas will be managed by system ==================== |
180 | free((char *) aStack); |
181 | } |
182 | |
183 | //==== Nullify ============================================================ |
184 | aStack = NULL; |
185 | } |
186 | |
187 | void MMgt_StackManager::Purge() |
188 | { |
189 | Standard_Address aFree; |
190 | Standard_Address aOther; |
191 | |
192 | Standard_Integer i; |
193 | |
194 | //==== A loop for deallocating all the storage in the Free List =========== |
195 | for(i=sizeof(Standard_Address); i<= myFreeListSize; i++){ |
196 | aFree = ((Standard_Address *)myFreeList)[i]; |
197 | |
198 | //==== A loop for deallocating all the storage with the same size ======= |
199 | while(aFree){ |
200 | aOther = aFree; |
201 | aFree = ((_Element *)aFree)->myNext; |
202 | free((char *)aOther); |
203 | } |
204 | |
205 | ((Standard_Address *)myFreeList)[i] = NULL; |
206 | } |
207 | } |
208 | |