OCC22329 Skipped extrema for a point and a circle at about 0 parameter
[occt.git] / src / NCollection / NCollection_IncAllocator.cxx
CommitLineData
7fd59977 1// File: NCollection_IncAllocator.cxx
2// Created: 12.04.02 21:16:26
3// Author: Alexander GRIGORIEV
4// Copyright: Open Cascade 2002
5
6#include <NCollection_IncAllocator.hxx>
7#include <Standard_OutOfMemory.hxx>
8#include <stdio.h>
9
10IMPLEMENT_STANDARD_HANDLE (NCollection_IncAllocator,NCollection_BaseAllocator)
11IMPLEMENT_STANDARD_RTTIEXT (NCollection_IncAllocator,NCollection_BaseAllocator)
12
13#define IMEM_SIZE(_size) ((((_size) - 1)/sizeof(aligned_t)) + 1)
14#define IMEM_FREE(p_bl) ((unsigned int)(p_bl->p_end_block - p_bl->p_free_space))
15#define IMEM_ALIGN(_addr) (sizeof(aligned_t)* IMEM_SIZE((unsigned long)(_addr)))
16
17#define MaxLookup 16
18
19//=======================================================================
20//function : NCollection_IncAllocator()
21//purpose : Constructor
22//=======================================================================
23
24NCollection_IncAllocator::NCollection_IncAllocator (const size_t theBlockSize)
25{
26#ifdef ALLOC_TRACK_USAGE
27 printf ("\n..NCollection_IncAllocator: Created (%x)\n",this);
28#endif
29 const size_t aSize = IMEM_SIZE(sizeof(IBlock)) +
30 IMEM_SIZE((theBlockSize > 2*sizeof(IBlock)) ? theBlockSize : 24600);
31 IBlock * const aBlock = (IBlock *) malloc (aSize * sizeof(aligned_t));
32 myFirstBlock = aBlock;
33 mySize = aSize;
34 if (aBlock == NULL)
35 Standard_OutOfMemory::Raise("NCollection_IncAllocator: out of memory");
36 aBlock -> p_free_space = (aligned_t *) IMEM_ALIGN (&aBlock[1]);
37 aBlock -> p_end_block = ((aligned_t *) aBlock) + aSize;
38 aBlock -> p_next = NULL;
39}
40
41//=======================================================================
42//function : ~NCollection_IncAllocator
43//purpose : Destructor
44//=======================================================================
45
46NCollection_IncAllocator::~NCollection_IncAllocator ()
47{
48 Clean();
49 free (myFirstBlock);
50}
51
52//=======================================================================
53//function : Allocate
54//purpose : allocate a memory
55//remark : returns NULL if allocation fails
56//=======================================================================
57
58void * NCollection_IncAllocator::Allocate (const size_t aSize)
59{
60 aligned_t * aResult = NULL;
61 const size_t cSize = aSize ? IMEM_SIZE(aSize) : 0;
62
63 if (cSize > mySize) {
64 /* If the requested size exceeds normal allocation size, allocate
65 a separate block and place it as the head of the list */
66 aResult = (aligned_t *) allocateNewBlock (cSize+1);
67 if (aResult)
68 myFirstBlock -> p_free_space = myFirstBlock -> p_end_block;
69 } else
70 if (cSize <= IMEM_FREE(myFirstBlock)) {
71 /* If the requested size fits into the free space in the 1st block */
72 aResult = myFirstBlock -> allocateInBlock (cSize);
73 } else {
74 /* Search for a block in the list with enough free space */
75 int aMaxLookup = MaxLookup; /* limit the number of blocks to query */
76 IBlock * aCurrentBlock = myFirstBlock -> p_next;
77 while (aCurrentBlock && aMaxLookup--) {
78 if (cSize <= IMEM_FREE(aCurrentBlock)) {
79 aResult = aCurrentBlock -> allocateInBlock (cSize);
80 break;
81 }
82 aCurrentBlock = aCurrentBlock -> p_next;
83 }
84 if (aResult == NULL) {
85 /* There is no available block with enough free space. Create a new
86 one and place it in the head of the list */
87 aResult = (aligned_t *) allocateNewBlock (mySize);
88 if (aResult)
89 myFirstBlock -> p_free_space = aResult + cSize;
90 }
91 }
92 return aResult;
93}
94
95//=======================================================================
96//function : Reallocate
97//purpose :
98//=======================================================================
99
100void * NCollection_IncAllocator::Reallocate (void * theAddress,
101 const size_t oldSize,
102 const size_t newSize)
103{
104// Check that the dummy parameters are OK
105 if (theAddress == NULL || oldSize == 0)
106 return Allocate (newSize);
107 const size_t cOldSize = IMEM_SIZE(oldSize);
108 const size_t cNewSize = newSize ? IMEM_SIZE(newSize) : 0;
109 aligned_t * anAddress = (aligned_t *) theAddress;
110
111// We check only the LAST allocation to do the real extension/contraction
112 if (anAddress + cOldSize == myFirstBlock -> p_free_space) {
113 myFirstBlock -> p_free_space = anAddress;
114// If the new size fits into the memory block => OK
115// This also includes any case of contraction
116 if (cNewSize <= IMEM_FREE(myFirstBlock)) {
117 myFirstBlock -> p_free_space += cNewSize;
118 return anAddress;
119 }
120 }
121// In case of contraction of non-terminating allocation, do nothing
122 else if (cOldSize >= cNewSize)
123 return anAddress;
124// Extension of non-terminated allocation if there is enough room in the
125// current memory block
126 if (cNewSize <= IMEM_FREE(myFirstBlock)) {
127 aligned_t * aResult = myFirstBlock -> allocateInBlock (cNewSize);
128 if (aResult)
129 for (unsigned i = 0; i < cOldSize; i++)
130 aResult[i] = anAddress[i];
131 return aResult;
132 }
133
134// This is either of the cases:
135// - extension of non-terminating allocation, or
136// - extension of terminating allocation when the new size is too big
137// In both cases create a new memory block, allocate memory and copy there
138// the reallocated memory.
139 aligned_t * aResult = (aligned_t *) allocateNewBlock (mySize);
140 if (aResult) {
141 myFirstBlock -> p_free_space = aResult + cNewSize;
142 for (unsigned i = 0; i < cOldSize; i++)
143 aResult[i] = anAddress[i];
144 }
145 return aResult;
146}
147
148//=======================================================================
149//function : Free
150//purpose :
151//=======================================================================
152
153void NCollection_IncAllocator::Free (void *)
154{}
155
156//=======================================================================
157//function : Clean
158//purpose :
159//=======================================================================
160
161void NCollection_IncAllocator::Clean ()
162{
163#ifdef ALLOC_TRACK_USAGE
164 printf ("\n..NCollection_IncAllocator: Memory size to clean:%8.1f kB (%x)\n",
165 double(GetMemSize())/1024, this);
166#endif
167 IBlock * aBlock = myFirstBlock;
168 if (aBlock) {
169 aBlock -> p_free_space = (aligned_t *) &aBlock[1];
170 aBlock = aBlock -> p_next;
171 while (aBlock) {
172 IBlock * aNext = aBlock -> p_next;
173 free (aBlock);
174 aBlock = aNext;
175 }
176 myFirstBlock -> p_next = NULL;
177 }
178}
179
180//=======================================================================
181//function : Reset
182//purpose :
183//=======================================================================
184
185void NCollection_IncAllocator::Reset (const Standard_Boolean doReleaseMem)
186{
187 if (doReleaseMem)
188 Clean();
189 else {
190 Standard_Integer aBlockCount(0);
191 IBlock * aBlock = myFirstBlock;
192 while (aBlock)
193 if (aBlockCount++ < MaxLookup) {
194 aBlock -> p_free_space = (aligned_t *) &aBlock[1];
195 if (aBlockCount < MaxLookup)
196 aBlock = aBlock -> p_next;
197 else {
198 IBlock * aNext = aBlock -> p_next;
199 aBlock -> p_next = NULL;
200 aBlock = aNext;
201 }
202 } else {
203 IBlock * aNext = aBlock -> p_next;
204 free (aBlock);
205 aBlock = aNext;
206 }
207 }
208}
209
210//=======================================================================
211//function : GetMemSize
212//purpose : diagnostic utility
213//=======================================================================
214
215size_t NCollection_IncAllocator::GetMemSize () const
216{
217 size_t aResult = 0;
218 IBlock * aBlock = myFirstBlock;
219 while (aBlock) {
220 aResult += (aBlock -> p_end_block - (aligned_t *) aBlock);
221 aBlock = aBlock -> p_next;
222 }
223 return aResult * sizeof (aligned_t);
224}
225
226//=======================================================================
227//function : allocateNewBlock
228//purpose :
229//=======================================================================
230
231void * NCollection_IncAllocator::allocateNewBlock (const size_t cSize)
232{
233 aligned_t * aResult = 0L;
234 const size_t aSz = cSize + IMEM_SIZE(sizeof(IBlock));
235 IBlock * aBlock = (IBlock *) malloc (aSz * sizeof(aligned_t));
236 if (aBlock) {
237 aBlock -> p_end_block = ((aligned_t *)aBlock) + aSz;
238 aBlock -> p_next = myFirstBlock;
239 myFirstBlock = aBlock;
240 aResult = (aligned_t *) IMEM_ALIGN(&aBlock[1]);
241 }
242 else
243 Standard_OutOfMemory::Raise("NCollection_IncAllocator: out of memory");
244 return aResult;
245}