Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2005-03-15 |
2 | // Created by: Peter KURNEV | |
3 | // Copyright (c) 1998-1999 Matra Datavision | |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS | |
5 | // | |
6 | // The content of this file is subject to the Open CASCADE Technology Public | |
7 | // License Version 6.5 (the "License"). You may not use the content of this file | |
8 | // except in compliance with the License. Please obtain a copy of the License | |
9 | // at http://www.opencascade.org and read it completely before using this file. | |
10 | // | |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its | |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. | |
13 | // | |
14 | // The Original Code and all software distributed under the License is | |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the | |
16 | // Initial Developer hereby disclaims all such warranties, including without | |
17 | // limitation, any warranties of merchantability, fitness for a particular | |
18 | // purpose or non-infringement. Please see the License for the specific terms | |
19 | // and conditions governing the rights and limitations under the License. | |
20 | ||
7fd59977 | 21 | |
22 | ||
23 | #include <Standard.ixx> | |
24 | ||
25 | #include <stdlib.h> | |
26 | ||
27 | #include <Standard_MMgrOpt.hxx> | |
28 | #include <Standard_MMgrRaw.hxx> | |
29 | #include <Standard_MMgrTBBalloc.hxx> | |
30 | ||
af09dbff | 31 | #if(defined(_WIN32) || defined(__WIN32__)) |
91322f44 | 32 | #include <windows.h> |
33 | #include <malloc.h> | |
34 | #include <locale.h> | |
af09dbff | 35 | #endif |
36 | ||
a0d8a9fc RL |
37 | #ifndef OCCT_MMGT_OPT_DEFAULT |
38 | #define OCCT_MMGT_OPT_DEFAULT 0 | |
39 | #endif | |
40 | ||
7fd59977 | 41 | //======================================================================= |
42 | //class : Standard_MMgrFactory | |
43 | //purpose : Container for pointer to memory manager; | |
44 | // used to construct appropriate memory manager according | |
45 | // to environment settings, and to ensure destruction upon exit | |
46 | //======================================================================= | |
47 | ||
48 | class Standard_MMgrFactory { | |
49 | public: | |
50 | Standard_MMgrFactory(); | |
51 | ~Standard_MMgrFactory(); | |
52 | public: | |
53 | Standard_MMgrRoot* myFMMgr; | |
54 | }; | |
55 | ||
56 | //======================================================================= | |
57 | //function : Standard_MMgrFactory | |
58 | //purpose : Check environment variables and create appropriate memory manager | |
59 | //======================================================================= | |
60 | ||
af09dbff | 61 | Standard_MMgrFactory::Standard_MMgrFactory() |
62 | : myFMMgr (NULL) | |
7fd59977 | 63 | { |
91322f44 | 64 | /*#if defined(_MSC_VER) && (_MSC_VER > 1400) |
65 | // Turn ON thread-safe C locale globally to avoid side effects by setlocale() calls between threads. | |
66 | // After this call all following _configthreadlocale() will be ignored assuming | |
67 | // Notice that this is MSVCRT feature - on POSIX systems xlocale API (uselocale instead of setlocale) | |
68 | // should be used explicitly to ensure thread-safety! | |
69 | ||
70 | // This is not well documented call because _ENABLE_PER_THREAD_LOCALE_GLOBAL flag is defined but not implemented for some reason. | |
71 | // -1 will set global locale flag to force _ENABLE_PER_THREAD_LOCALE_GLOBAL + _ENABLE_PER_THREAD_LOCALE_NEW behaviour | |
72 | // although there NO way to turn it off again and following calls will have no effect (locale will be changed only for current thread). | |
73 | _configthreadlocale (-1); | |
74 | #endif*/ | |
75 | ||
af09dbff | 76 | char* aVar; |
302f96fb | 77 | aVar = getenv ("MMGT_OPT"); |
78 | Standard_Integer anAllocId = (aVar ? atoi (aVar): OCCT_MMGT_OPT_DEFAULT); | |
79 | aVar = getenv ("MMGT_CLEAR"); | |
80 | Standard_Boolean toClear = (aVar ? (atoi (aVar) != 0) : Standard_True); | |
af09dbff | 81 | |
af09dbff | 82 | // on Windows (actual for XP and 2000) activate low fragmentation heap |
83 | // for CRT heap in order to get best performance. | |
84 | // Environment variable MMGT_LFH can be used to switch off this action (if set to 0) | |
85 | #if defined(_MSC_VER) | |
86 | aVar = getenv ("MMGT_LFH"); | |
87 | if ( aVar == NULL || atoi (aVar) != 0 ) | |
88 | { | |
89 | ULONG aHeapInfo = 2; | |
90 | HANDLE aCRTHeap = (HANDLE)_get_heap_handle(); | |
91 | HeapSetInformation (aCRTHeap, HeapCompatibilityInformation, &aHeapInfo, sizeof(aHeapInfo)); | |
7fd59977 | 92 | } |
af09dbff | 93 | #endif |
94 | ||
af09dbff | 95 | switch (anAllocId) |
96 | { | |
97 | case 1: // OCCT optimized memory allocator | |
98 | { | |
302f96fb | 99 | aVar = getenv ("MMGT_MMAP"); |
100 | Standard_Boolean bMMap = (aVar ? (atoi (aVar) != 0) : Standard_True); | |
101 | aVar = getenv ("MMGT_CELLSIZE"); | |
102 | Standard_Integer aCellSize = (aVar ? atoi (aVar) : 200); | |
103 | aVar = getenv ("MMGT_NBPAGES"); | |
104 | Standard_Integer aNbPages = (aVar ? atoi (aVar) : 1000); | |
105 | aVar = getenv ("MMGT_THRESHOLD"); | |
106 | Standard_Integer aThreshold = (aVar ? atoi (aVar) : 40000); | |
bd0c22ce | 107 | myFMMgr = new Standard_MMgrOpt (toClear, bMMap, aCellSize, aNbPages, aThreshold); |
af09dbff | 108 | break; |
109 | } | |
110 | case 2: // TBB memory allocator | |
111 | myFMMgr = new Standard_MMgrTBBalloc (toClear); | |
112 | break; | |
113 | case 0: | |
114 | default: // system default memory allocator | |
115 | myFMMgr = new Standard_MMgrRaw (toClear); | |
116 | } | |
7fd59977 | 117 | } |
118 | ||
119 | //======================================================================= | |
120 | //function : ~Standard_MMgrFactory | |
121 | //purpose : | |
122 | //======================================================================= | |
123 | ||
124 | Standard_MMgrFactory::~Standard_MMgrFactory() | |
125 | { | |
207e57e4 | 126 | if ( myFMMgr ) { |
7fd59977 | 127 | myFMMgr->Purge(Standard_True); |
128 | // delete myFMMgr; | |
129 | // myFMMgr = 0; | |
130 | } | |
131 | } | |
132 | ||
133 | //======================================================================= | |
134 | // function: GetMMgr | |
135 | // | |
136 | // This static function has a purpose to wrap static holder for memory | |
137 | // manager instance. | |
138 | // | |
139 | // Wrapping holder inside a function is needed to ensure that it will | |
140 | // be initialized not later than the first call to memory manager (that | |
141 | // would be impossible to guarantee if holder was static variable on | |
142 | // global or file scope, because memory manager may be called from | |
143 | // constructors of other static objects). | |
144 | // | |
145 | // Note that at the same time we could not guarantee that the holder | |
146 | // object is destroyed after last call to memory manager, since that | |
147 | // last call may be from static Handle() object which has been initialized | |
148 | // dynamically during program execution rather than in its constructor. | |
149 | // | |
150 | // Therefore holder currently does not call destructor of the memory manager | |
151 | // but only its method Purge() with Standard_True. | |
152 | // | |
153 | // To free the memory completely, we probably could use compiler-specific | |
154 | // pragmas (such as '#pragma fini' on SUN Solaris and '#pragma init_seg' on | |
155 | // WNT MSVC++) to put destructing function in code segment that is called | |
156 | // after destructors of other (even static) objects. However, this is not | |
157 | // done by the moment since it is compiler-dependent and there is no guarantee | |
158 | // thatsome other object calling memory manager is not placed also in that segment... | |
159 | // | |
160 | // Note that C runtime function atexit() could not help in this problem | |
161 | // since its behaviour is the same as for destructors of static objects | |
162 | // (see ISO 14882:1998 "Programming languages -- C++" 3.6.3) | |
163 | // | |
164 | // The correct approach to deal with the problem would be to have memory manager | |
165 | // to properly control its memory allocation and caching free blocks so | |
166 | // as to release all memory as soon as it is returned to it, and probably | |
167 | // even delete itself if all memory it manages has been released and | |
168 | // last call to method Purge() was with True. | |
169 | // | |
170 | // Note that one possible method to control memory allocations could | |
171 | // be counting calls to Allocate() and Free()... | |
172 | // | |
173 | //======================================================================= | |
174 | ||
175 | static Standard_MMgrRoot* GetMMgr() | |
176 | { | |
177 | static Standard_MMgrFactory aFactory; | |
178 | return aFactory.myFMMgr; | |
179 | } | |
180 | ||
181 | //======================================================================= | |
182 | //function : Allocate | |
183 | //purpose : | |
184 | //======================================================================= | |
185 | ||
186 | Standard_Address Standard::Allocate(const Standard_Size size) | |
187 | { | |
188 | return GetMMgr()->Allocate(size); | |
189 | } | |
190 | ||
191 | //======================================================================= | |
192 | //function : Free | |
193 | //purpose : | |
194 | //======================================================================= | |
195 | ||
196 | void Standard::Free(Standard_Address& aStorage) | |
197 | { | |
198 | GetMMgr()->Free(aStorage); | |
199 | } | |
200 | ||
201 | //======================================================================= | |
202 | //function : Reallocate | |
203 | //purpose : | |
204 | //======================================================================= | |
205 | ||
206 | Standard_Address Standard::Reallocate(Standard_Address& aStorage, | |
207 | const Standard_Size newSize) | |
208 | { | |
209 | return GetMMgr()->Reallocate(aStorage, newSize); | |
210 | } | |
211 | ||
212 | //======================================================================= | |
213 | //function : Purge | |
214 | //purpose : | |
215 | //======================================================================= | |
216 | ||
217 | Standard_Integer Standard::Purge() | |
218 | { | |
219 | return GetMMgr()->Purge(); | |
220 | } |