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