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