0023033: Standard_MMgrOpt::Reallocate behavior must be similar to "realloc"
[occt.git] / src / Standard / Standard_MMgrOpt.hxx
1 // Created on: 2005-03-15
2 // Created by: Peter KURNEV
3 // Copyright (c) 2005-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20
21
22 #ifndef _Standard_MMgrOpt_HeaderFile
23 #define _Standard_MMgrOpt_HeaderFile
24
25 #ifndef _Standard_Address_HeaderFile
26 #include <Standard_Address.hxx>
27 #endif
28 #ifndef _Standard_Integer_HeaderFile
29 #include <Standard_Integer.hxx>
30 #endif
31 #ifndef _Standard_Boolean_HeaderFile
32 #include <Standard_Boolean.hxx>
33 #endif
34 #ifndef _Standard_Macro_HeaderFile
35 #include <Standard_Macro.hxx>
36 #endif
37 #ifndef _Standard_MMgrRoot_HeaderFile
38 #include <Standard_MMgrRoot.hxx>
39 #endif
40 #ifndef _Standard_Mutex_HeaderFile
41 #include <Standard_Mutex.hxx>
42 #endif
43 #include <Standard_Size.hxx>
44
45 /**
46 * @brief Open CASCADE memory manager optimized for speed.
47 *
48 * The behaviour is different for memory blocks of different sizes,
49 * according to specified options provided to constructor:
50 *
51 * - Small blocks with size less than or equal to aCellSize are allocated 
52 *   in big pools of memory. The parameter aNbPages specifies size of 
53 *   these pools in pages (operating system-dependent). 
54 *   When freed, small block is not returned to the system but added
55 *   into free blocks list and reused when block of the same size is 
56 *   requested.
57
58 * - Medium size blocks with size less than aThreshold are allocated 
59 *   using malloc() or calloc() function but not returned to the system
60 *   when method Free() is called; instead they are put into free list
61 *   and reused when block of the same size is requested.
62 *   Blocks of medium size stored in free lists can be released to the 
63 *   system (by free()) by calling method Purge().
64 *
65 * - Large blocks with size greater than or equal to aThreshold are allocated 
66 *   and freed directly: either using malloc()/calloc() and free(), or using 
67 *   memory mapped files (if option aMMap is True)
68 *   
69 * Thus the optimization of memory allocation/deallocation is reached 
70 * for small and medium size blocks using free lists method; 
71 * note that space allocated for small blocks cannot be (currently) released
72 * to the system while space for medium size blocks can be released by method Purge().
73 *
74 * Note that destructor of that class frees all free lists and memory pools 
75 * allocated for small blocks.
76
77 * Note that size of memory blocks allocated by this memory manager is always 
78 * rounded up to 16 bytes. In addition, 8 bytes are added at the beginning 
79 * of the memory block to hold auxiliary information (size of the block when
80 * in use, or pointer to the next free block when in free list).
81 * This the expense of speed optimization. At the same time, allocating small 
82 * blocks is usually less costly than directly by malloc since allocation is made
83 * once (when allocating a pool) and overheads induced by malloc are minimized.
84 */
85
86 class Standard_MMgrOpt : public Standard_MMgrRoot
87 {
88  public:
89   
90   //! Constructor. If aClear is True, the allocated emmory will be 
91   //! nullified. For description of other parameters, see description 
92   //! of the class above.
93   Standard_EXPORT Standard_MMgrOpt
94                         (const Standard_Boolean aClear      = Standard_True,
95                          const Standard_Boolean aMMap       = Standard_True,
96                          const Standard_Size    aCellSize   = 200,
97                          const Standard_Integer aNbPages    = 10000,
98                          const Standard_Size    aThreshold  = 40000,
99                          const Standard_Boolean isReentrant = Standard_False);
100
101   //! Frees all free lists and pools allocated for small blocks 
102   Standard_EXPORT virtual ~Standard_MMgrOpt();
103   
104   //! Allocate aSize bytes; see class description above
105   Standard_EXPORT virtual Standard_Address Allocate(const Standard_Size aSize);
106   
107   //! Reallocate previously allocated aPtr to a new size; aPtr is nullified.
108   //! In case that aPtr is null, the function behaves exactly as Allocate.
109   Standard_EXPORT virtual Standard_Address Reallocate(Standard_Address& aPtr, 
110                                                       const Standard_Size aSize);
111   
112   //! Free previously allocated block; aPtr is nullified.
113   //! Note that block can not all blocks are released to the OS by this 
114   //! method (see class description)
115   Standard_EXPORT virtual void Free(Standard_Address& aPtr);
116   
117   //! Release medium-sized blocks of memory in free lists to the system.
118   //! Returns number of actually freed blocks
119   Standard_EXPORT virtual Standard_Integer Purge(Standard_Boolean isDestroyed);
120
121   //! Set reentrant mode on or off.
122   //! Note: This method may be called only when no any other thread can 
123   //!       access this object simultaneously
124   Standard_EXPORT virtual void SetReentrant(Standard_Boolean isReentrant);
125
126   //! Declaration of a type pointer to the callback function that
127   //! should accept the following arguments: <br>
128   //! theIsAlloc - true if the data is allocated, false if it is freed; <br>
129   //! theStorage - address of the allocated/freed block <br>
130   //! theRoundSize - the real rounded size of the block <br>
131   //! theSize - the size of the block that was requested by application
132   //!           (this value is correct only if theIsAlloc is true)
133   typedef void (*TPCallBackFunc)(const Standard_Boolean theIsAlloc,
134                                  const Standard_Address theStorage,
135                                  const Standard_Size theRoundSize,
136                                  const Standard_Size theSize);
137
138   //! Set the callback function. You may pass 0 there to turn off the callback.
139   //! The callback function, if set, will be automatically called from within
140   //! Allocate and Free methods.
141   Standard_EXPORT static void SetCallBackFunction(TPCallBackFunc pFunc);
142
143 protected:
144  
145   //! Internal - initialization of buffers
146   Standard_EXPORT void Initialize();
147
148   //! Internal - allocation of memory using either malloc or memory mapped files.
149   //! The size of the actually allocated block may be greater than requested one
150   //! when memory mapping is used, since it is aligned to page size 
151   Standard_Size* AllocMemory (Standard_Size &aSize);
152   
153   //! Internal - deallocation of memory taken by AllocMemory
154   void FreeMemory (Standard_Address aPtr, const Standard_Size aSize);
155   
156   //! Internal - free memory pools allocated for small size blocks
157   void FreePools();
158
159  protected:
160   Standard_Boolean myClear;         //!< option to clear allocated memory
161   
162   Standard_Size    myFreeListMax;   //!< last allocated index in the free blocks list
163   Standard_Size ** myFreeList;      //!< free blocks list 
164
165   Standard_Size    myCellSize;      //!< small blocks size
166   Standard_Integer myNbPages;       //!< size (pages) for small block memory pools
167   Standard_Size    myPageSize;      //!< system-dependent memory page size
168   Standard_Size *  myAllocList;     //!< list of memory pools for small blocks
169   Standard_Size *  myNextAddr;      //!< next free address in the active memory pool
170   Standard_Size *  myEndBlock;      //!< end of the active memory pool
171   
172   Standard_Integer myMMap;          //!< non-null if using memory mapped files for allocation of large blocks
173   Standard_Size    myThreshold;     //!< large block size  
174   
175   Standard_Mutex   myMutex;         //!< Mutex to protect free lists data
176   Standard_Mutex   myMutexPools;    //!< Mutex to protect small block pools data
177   Standard_Boolean myReentrant;     //!< Use mutex to provide correct reentrant behaviour
178 };
179
180 #endif