MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
mynewmem.cc
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/libraries/libmbutil/mynewmem.cc,v 1.28 2017/01/12 14:44:05 masarati Exp $ */
2 /*
3  * MBDyn (C) is a multibody analysis code.
4  * http://www.mbdyn.org
5  *
6  * Copyright (C) 1996-2017
7  *
8  * Pierangelo Masarati <masarati@aero.polimi.it>
9  * Paolo Mantegazza <mantegazza@aero.polimi.it>
10  *
11  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
12  * via La Masa, 34 - 20156 Milano, Italy
13  * http://www.aero.polimi.it
14  *
15  * Changing this copyright notice is forbidden.
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation (version 2 of the License).
20  *
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */
31 
32 /*****************************************************************************
33 
34  Allocazione dinamica di memoria controllata con ASSERT e Memory Manager
35 
36  Scritto da
37  Pierangelo Masarati
38  il 05/04/1997
39 
40  *****************************************************************************/
41 
42 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
43 
44 #ifdef DEBUG
45 
46 #include <string.h>
47 #include <iostream>
48 #include <iomanip>
49 
50 #include "myassert.h"
51 #include "mynewmem.h"
52 
53 
54 /* Funzioni usate anche senza memory manager */
55 void
56 _Safenew(const char *file, int line, int flag)
57 {
58  std::cout.flush();
59  if (flag == 0) {
60  std::cerr << std::endl
61  << "SAFENEW fault: NULL return pointer in file "
62  << file << " at line " << line << std::endl;
63  } else if (flag == 1) {
64  std::cerr << std::endl
65  << "SAFENEWARR fault: NULL return pointer in file "
66  << file << " at line " << line << std::endl;
67  }
68 }
69 
70 
71 void
72 _Safenewfill(void *pv, size_t size, char fill)
73 {
74  ASSERT(pv);
75  ASSERT(size);
76 
77  char* pb = (char*)pv;
78  while (size--) {
79  *pb++ = fill;
80  }
81 }
82 
83 #ifdef DEBUG_MEMMANAGER
84 
85 clMemMan defaultMemoryManager("Default");
86 
87 /* Funzioni proprie private del memory manager */
88 clMemMan::stList *
89 clMemMan::pstFindElem(const void* pvToFind) const
90 {
91  ASSERT(pvToFind);
92 
93  stList *pstL = pstRoot;
94  ASSERT(pstL);
95 
96  while (pstL->pstNext && (pstL->pstNext->stMB.pv <= pvToFind)) {
97  pstL = pstL->pstNext;
98  if (pstL->stMB.pv == pvToFind) {
99  if (pstL->stMB.eSt == ALLOCATED) {
100  return pstL;
101  }
102  }
103  }
104  CERR << std::endl << "clMemMan " << sName << " error: pointer "
105  << (void*)pvToFind << " not found in pstFindElem()" << std::endl;
106  return NULL;
107 }
108 
109 clMemMan::stList *
110 clMemMan::pstFindPrev(const void *pvToFindPrev) const
111 {
112  ASSERT(pvToFindPrev);
113 
114  stList *pstL = pstRoot;
115  stList *pstN = NULL;
116  ASSERT(pstL);
117 
118  while (pstL->pstNext && (pstL->pstNext->stMB.pv <= pvToFindPrev)) {
119  pstN = pstL->pstNext;
120  if (pstN->stMB.pv == pvToFindPrev) {
121  if (pstN->stMB.eSt == ALLOCATED) {
122  return pstL;
123  }
124  }
125  pstL = pstN;
126  }
127 
128  CERR << std::endl << "clMemMan " << sName << " error: pointer "
129  << (void*)pvToFindPrev << " not found in pstFindPrev()"
130  << std::endl;
131  return NULL;
132 }
133 
134 /* enum eRemoveMode { RELEASE, DELBUTKEEPLOG, DELBUTNOTRELEASE }; */
135 void
136 clMemMan::_remove(const void *pvToRemove, clMemMan::eRemoveMode eMode, flag fArr, flag fFill)
137 {
138  ASSERT(pvToRemove);
139 
140  stList *pstL = pstFindPrev(pvToRemove);
141  ASSERT(pstL);
142 
143  if (!pstL) {
144  CERR << std::endl << "clMemMan " << sName << " warning: pointer "
145  << (void*)pvToRemove;
146  if (fArr) {
147  std::cerr << " to array";
148  }
149  std::cerr << " not found in _remove()" << std::endl;
150  throw clMemMan::ErrNotFound();
151  }
152 
153  stList *pstN = pstL->pstNext;
154  ASSERT(pstN);
155 
156  if (fFill) {
157  ASSERT(fArr && pstN->stMB.fArr);
158  _Safenewfill(pstN->stMB.pv, pstN->stMB.size, cDebugFree);
159  }
160 
161  switch (eMode) {
162  case RELEASE:
163  /* caso di cancellazione totale */
164  pstL->pstNext = pstN->pstNext;
165  delete pstN;
166  break;
167 
168  case DELBUTKEEPLOG:
169  /* Cancellazione della memoria mantenendo il registro */
170  pstN->stMB.eSt = FREED;
171  break;
172 
173  case DELBUTNOTRELEASE:
174  /* Eliminazione del riferimento senza cancellazione memoria */
175  pstN->stMB.eSt = FREEDBUTNOTRELEASED;
176  break;
177  }
178 }
179 
180 /* Funzioni proprie pubbliche del memory manager */
181 clMemMan::clMemMan(char *sNameIn)
182 : pstRoot(NULL), sName(NULL)
183 {
184  if (sNameIn) {
185  sName = new char[strlen(sNameIn)+1];
186  strcpy(sName, sNameIn);
187  }
188 
189  pstRoot = new stList(stMemBlock());
190 }
191 
192 clMemMan::~clMemMan(void)
193 {
194  stList* pstL = pstRoot;
195  stList* pstP = NULL;
196  ASSERT(pstL);
197 
198  while (pstL) {
199  pstP = pstL;
200  pstL = pstL->pstNext;
201  delete pstP;
202  }
203 
204  if (sName) {
205  delete[] sName;
206  }
207 }
208 
209 flag
210 clMemMan::fIsBlock(const void *pvBlock, size_t sizeBlock) const
211 {
212  ASSERT(pvBlock);
213  ASSERT(sizeBlock);
214 
215  stList *pstL = pstFindElem(pvBlock);
216  ASSERT(pstL);
217 
218  if (pstL && (pstL->stMB.size == sizeBlock)) {
219  ASSERT(pstL->stMB.eSt != UNKNOWN);
220  if (pstL->stMB.eSt == ALLOCATED) {
221  return 1;
222  }
223  }
224 
225  return 0;
226 }
227 
228 flag
229 clMemMan::fIsPointerToBlock(const void *pvBlock) const
230 {
231  ASSERT(pvBlock);
232 
233  stList *pstL = pstFindElem(pvBlock);
234  ASSERT(pstL);
235 
236  if (pstL) {
237  ASSERT(pstL->stMB.eSt != UNKNOWN);
238  if (pstL->stMB.eSt == ALLOCATED) {
239  return 1;
240  }
241  }
242 
243  return 0;
244 }
245 
246 flag
247 clMemMan::fIsValid(const void *pvValid, size_t sizeValid) const
248 {
249  ASSERT(pvValid);
250  ASSERT(sizeValid);
251 
252  stList *pstL = pstRoot;
253  ASSERT(pstL);
254 
255  while (pstL->pstNext) {
256  pstL = pstL->pstNext;
257  flag fCond1 = (pstL->stMB.pv <= pvValid);
258  flag fCond2 = (((void*)pstL->stMB.pv+pstL->stMB.size)
259  >= ((void*)pvValid+sizeValid));
260 
261  if (fCond1 && fCond2) {
262  ASSERT(pstL->stMB.eSt != UNKNOWN);
263  if (pstL->stMB.eSt == ALLOCATED) {
264  return 1;
265  }
266  }
267  }
268 
269  return 0;
270 }
271 
272 size_t
273 clMemMan::sizeOfBlock(const void* pvSizeOf) const
274 {
275  ASSERT(pvSizeOf);
276  stList *pstL = pstFindElem(pvSizeOf);
277  ASSERT(pstL);
278 
279  if (pstL) {
280  return pstL->stMB.size;
281  }
282 
283  return 0;
284 }
285 
286 
287 flag
288 clMemMan::fIsArray(const void *pvIsArray) const
289 {
290  ASSERT(pvIsArray);
291  stList *pstL = pstFindElem(pvIsArray);
292  ASSERT(pstL);
293 
294  if (pstL) {
295  return pstL->stMB.fArr;
296  }
297  return 0;
298 }
299 
300 eStatus
301 clMemMan::eBlockStatus(const void *pvBStatus) const
302 {
303  ASSERT(pvBStatus);
304  stList *pstL = pstFindElem(pvBStatus);
305  ASSERT(pstL);
306 
307  if (pstL) {
308  return pstL->stMB.eSt;
309  }
310  return UNKNOWN;
311 }
312 
313 void
314 clMemMan::ClearRefs(void)
315 {
316  stList *pstL = pstRoot;
317  ASSERT(pstL);
318 
319  while(pstL->pstNext) {
320  pstL = pstL->pstNext;
321  pstL->stMB.fRef = 0;
322  }
323 }
324 
325 void
326 clMemMan::PutRef(const void *pvRef)
327 {
328  ASSERT(pvRef);
329 
330  stList *pstL = pstFindElem(pvRef);
331  ASSERT(pstL);
332 
333  if (pstL) {
334  pstL->stMB.fRef = 1;
335  }
336 }
337 
338 flag
339 clMemMan::fIsRefd(const void *pvIsRefd) const
340 {
341  ASSERT(pvIsRefd);
342 
343  stList *pstL = pstFindElem(pvIsRefd);
344  ASSERT(pstL);
345 
346  if (pstL && (pstL->stMB.eSt == ALLOCATED) && (pstL->stMB.fRef == 1)) {
347  return 1;
348  }
349 
350  return 0;
351 }
352 
353 /* enum eStatus { UNKNOWN, ALLOCATED, FREED, FREEDBUTNOTRELEASED }; */
354 std::ostream&
355 clMemMan::DumpRef(std::ostream& rout) const
356 {
357  rout << "Memory Manager 1.0";
358  if (sName) {
359  rout << ": " << sName;
360  }
361  rout << std::endl;
362 
363  rout << "Ref'd blocks:" << std::endl;
364 
365  stList *pstL = pstRoot;
366  ASSERT(pstL);
367 
368  int iCount = 0;
369  while (pstL->pstNext) {
370  pstL = pstL->pstNext;
371  ASSERT(pstL->stMB.eSt != UNKNOWN);
372 
373  iCount++;
374  if (pstL->stMB.fRef) {
375  rout << "Block " << setw(4) << iCount << ':' << std::endl
376  << "pointer " << pstL->stMB.pv
377  << ", size " << pstL->stMB.size
378  << ", status: ";
379 
380  if (pstL->stMB.eSt == ALLOCATED) {
381  rout << "ALLOCATED" << std::endl;
382  } else if (pstL->stMB.eSt == FREED) {
383  rout << "FREED" << std::endl;
384  } else if (pstL->stMB.eSt == FREEDBUTNOTRELEASED) {
385  rout << "FREEDBUTNOTRELEASED" << std::endl;
386  }
387  }
388  }
389 
390  rout << "Unref'd blocks:" << std::endl;
391 
392  pstL = pstRoot;
393  iCount = 0;
394  while (pstL->pstNext) {
395  pstL = pstL->pstNext;
396  ASSERT(pstL->stMB.eSt != UNKNOWN);
397 
398  iCount++;
399  if (!pstL->stMB.fRef) {
400  rout << "Block " << setw(4) << iCount << ':' << std::endl
401  << "pointer " << pstL->stMB.pv
402  << ", size " << pstL->stMB.size
403  << ", status: ";
404 
405  if (pstL->stMB.eSt == ALLOCATED) {
406  rout << "ALLOCATED" << std::endl;
407  } else if (pstL->stMB.eSt == FREED) {
408  rout << "FREED" << std::endl;
409  } else if (pstL->stMB.eSt == FREEDBUTNOTRELEASED) {
410  rout << "FREEDBUTNOTRELEASED" << std::endl;
411  }
412  }
413  }
414 
415  return rout;
416 }
417 
418 void
419 clMemMan::add(const void *pvIn, size_t sizeIn, flag fArr)
420 {
421  ASSERT(pvIn);
422  ASSERT(sizeIn);
423  ASSERT(fArr == 0 || fArr == 1);
424 
425  stList *pstL = pstRoot;
426  stList *pstN = NULL;
427  ASSERT(pstL);
428 
429  while (pstL->pstNext) {
430  pstN = pstL->pstNext;
431  if ((pstN->stMB.pv == pvIn) && (pstN->stMB.eSt == ALLOCATED)) {
432  CERR << std::endl << "clMemMan" << sName
433  << " error: block pointed by "
434  << (void*)pvIn << ", size " << sizeIn << std::endl
435  << "is already defined. Previous size is "
436  << pstN->stMB.size << std::endl;
437  return;
438  }
439 
440  if (pstN->stMB.pv >= pvIn) {
441  break;
442  }
443  pstL = pstN;
444  }
445 
446  pstN = new stList(stMemBlock((void*)pvIn, sizeIn, ALLOCATED, fArr));
447  ASSERT(pstN);
448 
449  if (pstN == NULL) {
450  CERR << std::endl << "clMemMan " << sName
451  << ": error in allocation in add()" << std::endl;
453  }
454 
455  pstN->pstNext = pstL->pstNext;
456  pstL->pstNext = pstN;
457 }
458 
459 /* Operatore friend del memory manager */
460 std::ostream&
461 operator << (std::ostream& rout, const clMemMan& rm)
462 {
463  rout << "Memory Manager 1.0";
464  if (rm.sName) {
465  rout << ": " << rm.sName;
466  }
467  rout << std::endl;
468 
469  clMemMan::stList *pstL = rm.pstRoot;
470 
471  int iCount = 0;
472  while (pstL->pstNext) {
473  pstL = pstL->pstNext;
474  ASSERT(pstL->stMB.eSt != UNKNOWN);
475 
476  rout << "Block " << setw(4) << (++iCount) << ':' << std::endl
477  << "pointer " << pstL->stMB.pv
478  << ", size " << pstL->stMB.size
479  << ", status: ";
480 
481  if (pstL->stMB.eSt == ALLOCATED) {
482  rout << "ALLOCATED" << std::endl;
483  } else if (pstL->stMB.eSt == FREED) {
484  rout << "FREED" << std::endl;
485  } else if (pstL->stMB.eSt == FREEDBUTNOTRELEASED) {
486  rout << "FREEDBUTNOTRELEASED" << std::endl;
487  }
488  }
489 
490  return rout;
491 }
492 
493 #endif /* DEBUG_MEMMANAGER */
494 
495 #endif /* DEBUG */
496 
long int flag
Definition: mbdyn.h:43
#define MBDYN_EXCEPT_ARGS
Definition: except.h:63
#define CERR
Definition: myassert.h:228
std::ostream & operator<<(std::ostream &out, const FullMatrixHandler &m)
Definition: fullmh.cc:352
static char * file
Definition: ann_in.c:101
if(nargin< 1)
#define ASSERT(expression)
Definition: colamd.c:977
#define defaultMemoryManager
Definition: mynewmem.h:691