summaryrefslogtreecommitdiff
path: root/inc/Standard_MMgrOpt.hxx
blob: b3c2e8254edd8b2cac445c035a4bd13bef92a4b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// File:	Standard_MMgrOpt.hxx
// Created:	Tue Mar 15 12:05:43 2005
// Author:	Peter KURNEV
//		<pkv@irinox>


#ifndef _Standard_MMgrOpt_HeaderFile
#define _Standard_MMgrOpt_HeaderFile

#ifndef _Standard_Address_HeaderFile
#include <Standard_Address.hxx>
#endif
#ifndef _Standard_Integer_HeaderFile
#include <Standard_Integer.hxx>
#endif
#ifndef _Standard_Boolean_HeaderFile
#include <Standard_Boolean.hxx>
#endif
#ifndef _Standard_Macro_HeaderFile
#include <Standard_Macro.hxx>
#endif
#ifndef _Standard_MMgrRoot_HeaderFile
#include <Standard_MMgrRoot.hxx>
#endif
#ifndef _Standard_Mutex_HeaderFile
#include <Standard_Mutex.hxx>
#endif
#include <Standard_Size.hxx>

/**
* @brief Open CASCADE memory manager optimized for speed.
*
* The behaviour is different for memory blocks of different sizes,
* according to specified options provided to constructor:
*
* - Small blocks with size less than or equal to aCellSize are allocated 
*   in big pools of memory. The parameter aNbPages specifies size of 
*   these pools in pages (operating system-dependent). 
*   When freed, small block is not returned to the system but added
*   into free blocks list and reused when block of the same size is 
*   requested.
* 
* - Medium size blocks with size less than aThreshold are allocated 
*   using malloc() or calloc() function but not returned to the system
*   when method Free() is called; instead they are put into free list
*   and reused when block of the same size is requested.
*   Blocks of medium size stored in free lists can be released to the 
*   system (by free()) by calling method Purge().
*
* - Large blocks with size greater than or equal to aThreshold are allocated 
*   and freed directly: either using malloc()/calloc() and free(), or using 
*   memory mapped files (if option aMMap is True)
*   
* Thus the optimization of memory allocation/deallocation is reached 
* for small and medium size blocks using free lists method; 
* note that space allocated for small blocks cannot be (currently) released
* to the system while space for medium size blocks can be released by method Purge().
*
* Note that destructor of that class frees all free lists and memory pools 
* allocated for small blocks.
* 
* Note that size of memory blocks allocated by this memory manager is always 
* rounded up to 16 bytes. In addition, 8 bytes are added at the beginning 
* of the memory block to hold auxiliary information (size of the block when
* in use, or pointer to the next free block when in free list).
* This the expense of speed optimization. At the same time, allocating small 
* blocks is usually less costly than directly by malloc since allocation is made
* once (when allocating a pool) and overheads induced by malloc are minimized.
*/

class Standard_MMgrOpt : public Standard_MMgrRoot
{
 public:
  
  //! Constructor. If aClear is True, the allocated emmory will be 
  //! nullified. For description of other parameters, see description 
  //! of the class above.
  Standard_EXPORT Standard_MMgrOpt
                        (const Standard_Boolean aClear      = Standard_True,
                         const Standard_Boolean aMMap       = Standard_True,
                         const Standard_Size    aCellSize   = 200,
                         const Standard_Integer aNbPages    = 10000,
                         const Standard_Size    aThreshold  = 40000,
                         const Standard_Boolean isReentrant = Standard_False);

  //! Frees all free lists and pools allocated for small blocks 
  Standard_EXPORT virtual ~Standard_MMgrOpt();
  
  //! Allocate aSize bytes; see class description above
  Standard_EXPORT virtual Standard_Address Allocate(const Standard_Size aSize);
  
  //! Reallocate previously allocated aPtr to a new size; aPtr is nullified
  Standard_EXPORT virtual Standard_Address Reallocate(Standard_Address& aPtr, 
                                                      const Standard_Size aSize);
  
  //! Free previously allocated block; aPtr is nullified.
  //! Note that block can not all blocks are released to the OS by this 
  //! method (see class description)
  Standard_EXPORT virtual void Free(Standard_Address& aPtr);
  
  //! Release medium-sized blocks of memory in free lists to the system.
  //! Returns number of actually freed blocks
  Standard_EXPORT virtual Standard_Integer Purge(Standard_Boolean isDestroyed);

  //! Set reentrant mode on or off.
  //! Note: This method may be called only when no any other thread can 
  //!       access this object simultaneously
  Standard_EXPORT virtual void SetReentrant(Standard_Boolean isReentrant);

  //! Declaration of a type pointer to the callback function that
  //! should accept the following arguments: <br>
  //! theIsAlloc - true if the data is allocated, false if it is freed; <br>
  //! theStorage - address of the allocated/freed block <br>
  //! theRoundSize - the real rounded size of the block <br>
  //! theSize - the size of the block that was requested by application
  //!           (this value is correct only if theIsAlloc is true)
  typedef void (*TPCallBackFunc)(const Standard_Boolean theIsAlloc,
                                 const Standard_Address theStorage,
                                 const Standard_Size theRoundSize,
                                 const Standard_Size theSize);

  //! Set the callback function. You may pass 0 there to turn off the callback.
  //! The callback function, if set, will be automatically called from within
  //! Allocate and Free methods.
  Standard_EXPORT static void SetCallBackFunction(TPCallBackFunc pFunc);

protected:
 
  //! Internal - initialization of buffers
  Standard_EXPORT void Initialize();

  //! Internal - allocation of memory using either malloc or memory mapped files.
  //! The size of the actually allocated block may be greater than requested one
  //! when memory mapping is used, since it is aligned to page size 
  Standard_Size* AllocMemory (Standard_Size &aSize);
  
  //! Internal - deallocation of memory taken by AllocMemory
  void FreeMemory (Standard_Address aPtr, const Standard_Size aSize);
  
  //! Internal - free memory pools allocated for small size blocks
  void FreePools();

 protected:
  Standard_Boolean myClear;         //!< option to clear allocated memory
  
  Standard_Size    myFreeListMax;   //!< last allocated index in the free blocks list
  Standard_Size ** myFreeList;      //!< free blocks list 

  Standard_Size    myCellSize;      //!< small blocks size
  Standard_Integer myNbPages;       //!< size (pages) for small block memory pools
  Standard_Size    myPageSize;      //!< system-dependent memory page size
  Standard_Size *  myAllocList;     //!< list of memory pools for small blocks
  Standard_Size *  myNextAddr;      //!< next free address in the active memory pool
  Standard_Size *  myEndBlock;      //!< end of the active memory pool
  
  Standard_Integer myMMap;          //!< non-null if using memory mapped files for allocation of large blocks
  Standard_Size    myThreshold;     //!< large block size  
  
  Standard_Mutex   myMutex;         //!< Mutex to protect free lists data
  Standard_Mutex   myMutexPools;    //!< Mutex to protect small block pools data
  Standard_Boolean myReentrant;     //!< Use mutex to provide correct reentrant behaviour
};

#endif