Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2011-02-04 |
2 | // Created by: Mikhail SAZONOV | |
973c2be1 | 3 | // Copyright (c) 2011-2014 OPEN CASCADE SAS |
b311480e | 4 | // |
973c2be1 | 5 | // This file is part of Open CASCADE Technology software library. |
b311480e | 6 | // |
d5f74e42 | 7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
11 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 12 | // |
973c2be1 | 13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. | |
b311480e | 15 | |
7af17f1e MA |
16 | #include <OSD_MAllocHook.hxx> |
17 | ||
57c28b61 | 18 | #ifndef _MSC_VER |
7af17f1e MA |
19 | #if !defined __STDC_LIMIT_MACROS |
20 | #define __STDC_LIMIT_MACROS | |
21 | #endif | |
22 | #include <stdint.h> | |
23 | #endif | |
24 | ||
25 | #include <set> | |
26 | #include <map> | |
e2f8b392 | 27 | #include <cstdlib> |
2cb44241 | 28 | #include <cstring> |
64531d9c | 29 | #include <iomanip> |
7af17f1e | 30 | |
213cb888 M |
31 | #ifndef SIZE_MAX |
32 | #define SIZE_MAX UINT_MAX | |
33 | #endif | |
34 | ||
7af17f1e MA |
35 | #define MAX_STR 80 |
36 | ||
37 | static OSD_MAllocHook::Callback* MypCurrentCallback = NULL; | |
38 | ||
302f96fb | 39 | namespace { |
40 | // dummy function to call at place where break point might be needed | |
de9a2842 | 41 | static unsigned debug_counter = 0; |
42 | inline void place_for_breakpoint () { | |
43 | // this statement is just to have any instruction in object code, | |
44 | // otherwise compiler does not leave a place for break point | |
45 | debug_counter++; | |
46 | } | |
a3f6f591 | 47 | } |
302f96fb | 48 | |
7af17f1e MA |
49 | //======================================================================= |
50 | //function : GetCallback | |
51 | //purpose : | |
52 | //======================================================================= | |
53 | ||
54 | OSD_MAllocHook::Callback* OSD_MAllocHook::GetCallback() | |
55 | { | |
56 | return MypCurrentCallback; | |
57 | } | |
58 | ||
59 | //======================================================================= | |
60 | //function : GetLogFileHandler | |
61 | //purpose : | |
62 | //======================================================================= | |
63 | ||
64 | OSD_MAllocHook::LogFileHandler* OSD_MAllocHook::GetLogFileHandler() | |
65 | { | |
66 | static LogFileHandler MyHandler; | |
67 | return &MyHandler; | |
68 | } | |
69 | ||
70 | //======================================================================= | |
71 | //function : GetCollectBySize | |
72 | //purpose : | |
73 | //======================================================================= | |
74 | ||
75 | OSD_MAllocHook::CollectBySize* OSD_MAllocHook::GetCollectBySize() | |
76 | { | |
77 | static CollectBySize MyHandler; | |
78 | return &MyHandler; | |
79 | } | |
80 | ||
81 | //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
82 | // Platform-dependent methods | |
83 | //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
84 | ||
57c28b61 | 85 | #ifdef _MSC_VER |
7af17f1e MA |
86 | #include <crtdbg.h> |
87 | ||
de9a2842 | 88 | #if _MSC_VER >= 1500 /* VS 2008 */ |
295cb053 | 89 | |
7af17f1e MA |
90 | static long getRequestNum(void* pvData, long lRequest, size_t& theSize) |
91 | { | |
295cb053 | 92 | #ifdef _DEBUG /* protect against invalid pointer; in Release, _CrtIsValidHeapPointer is always 1 */ |
93 | if (!_CrtIsValidHeapPointer(pvData)) | |
94 | return lRequest; | |
95 | #else | |
96 | (void)lRequest; // avoid compiler warning on unused arg | |
105aae76 | 97 | #endif |
295cb053 | 98 | |
7af17f1e | 99 | #define nNoMansLandSize 4 |
295cb053 | 100 | // the header struct is taken from crt/src/dbgint.h |
101 | struct _CrtMemBlockHeader | |
102 | { | |
7af17f1e | 103 | #ifdef _WIN64 |
295cb053 | 104 | int nBlockUse; |
105 | size_t nDataSize; | |
7af17f1e | 106 | #else |
295cb053 | 107 | size_t nDataSize; |
108 | int nBlockUse; | |
105aae76 | 109 | #endif |
295cb053 | 110 | long lRequest; |
111 | unsigned char gap[nNoMansLandSize]; | |
112 | }; | |
113 | ||
114 | _CrtMemBlockHeader* aHeader = ((_CrtMemBlockHeader*)pvData)-1; | |
115 | theSize = aHeader->nDataSize; | |
116 | return aHeader->lRequest; | |
117 | } | |
118 | ||
de9a2842 | 119 | #else /* _MSC_VER < 1500 */ |
295cb053 | 120 | |
121 | static long getRequestNum(void* /*pvData*/, long lRequest, size_t& /*theSize*/) | |
122 | { | |
7af17f1e MA |
123 | return lRequest; |
124 | } | |
125 | ||
295cb053 | 126 | #endif /* _MSC_VER == 1500 */ |
127 | ||
7af17f1e MA |
128 | int __cdecl MyAllocHook(int nAllocType, |
129 | void * pvData, | |
130 | size_t nSize, | |
131 | int nBlockUse, | |
132 | long lRequest, | |
133 | const unsigned char * /*szFileName*/, | |
134 | int /*nLine*/) | |
135 | { | |
136 | if (nBlockUse == _CRT_BLOCK || // Ignore internal C runtime library allocations | |
137 | MypCurrentCallback == NULL) | |
138 | return(1); | |
139 | ||
140 | if (nAllocType == _HOOK_ALLOC) | |
141 | MypCurrentCallback->AllocEvent(nSize, lRequest); | |
142 | else if (nAllocType == _HOOK_FREE) | |
143 | { | |
144 | // for free hook, lRequest is not defined, | |
145 | // but we can take it from the CRT mem block header | |
146 | size_t aSize = 0; | |
147 | lRequest = getRequestNum(pvData, lRequest, aSize); | |
148 | MypCurrentCallback->FreeEvent(pvData, aSize, lRequest); | |
149 | } | |
150 | else // _HOOK_REALLOC | |
151 | { | |
152 | // for realloc hook, lRequest shows the new request, | |
153 | // and we should get request number for old block | |
154 | size_t anOldSize = 0; | |
155 | long anOldRequest = getRequestNum(pvData, 0, anOldSize); | |
156 | MypCurrentCallback->FreeEvent(pvData, anOldSize, anOldRequest); | |
157 | MypCurrentCallback->AllocEvent(nSize, lRequest); | |
158 | } | |
159 | ||
160 | return(1); // Allow the memory operation to proceed | |
161 | } | |
162 | ||
163 | //======================================================================= | |
164 | //function : SetCallback | |
165 | //purpose : | |
166 | //======================================================================= | |
167 | ||
168 | void OSD_MAllocHook::SetCallback(Callback* theCB) | |
169 | { | |
170 | MypCurrentCallback = theCB; | |
171 | if (theCB == NULL) | |
172 | _CrtSetAllocHook(NULL); | |
173 | else | |
174 | _CrtSetAllocHook(MyAllocHook); | |
175 | } | |
176 | ||
57c28b61 | 177 | #else // ! _MSC_VER |
7af17f1e MA |
178 | |
179 | // Not yet implemented for non-WNT platform | |
180 | ||
181 | void OSD_MAllocHook::SetCallback(Callback* theCB) | |
182 | { | |
183 | MypCurrentCallback = theCB; | |
184 | } | |
185 | ||
57c28b61 | 186 | #endif // _MSC_VER |
7af17f1e MA |
187 | |
188 | //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
189 | // LogFileHandler handler methods | |
190 | //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
191 | ||
192 | //======================================================================= | |
193 | //function : LogFileHandler::LogFileHandler | |
194 | //purpose : | |
195 | //======================================================================= | |
196 | ||
197 | OSD_MAllocHook::LogFileHandler::LogFileHandler() | |
64531d9c | 198 | : myBreakSize(0) |
7af17f1e | 199 | { |
64531d9c | 200 | myLogFile.imbue (std::locale ("C")); |
7af17f1e MA |
201 | } |
202 | ||
203 | //======================================================================= | |
204 | //function : LogFileHandler::~LogFileHandler | |
205 | //purpose : | |
206 | //======================================================================= | |
207 | ||
208 | OSD_MAllocHook::LogFileHandler::~LogFileHandler() | |
209 | { | |
210 | Close(); | |
211 | } | |
212 | ||
213 | //======================================================================= | |
214 | //function : LogFileHandler::Open | |
215 | //purpose : | |
216 | //======================================================================= | |
217 | ||
218 | Standard_Boolean OSD_MAllocHook::LogFileHandler::Open(const char* theFileName) | |
219 | { | |
220 | Close(); | |
64531d9c | 221 | myLogFile.open (theFileName); |
222 | if (!myLogFile.is_open()) | |
7af17f1e | 223 | { |
64531d9c | 224 | return Standard_False; |
7af17f1e | 225 | } |
64531d9c | 226 | |
227 | myLogFile << "Operation type; Request Number; Block Size\n" | |
228 | "------------------------------------------\n"; | |
229 | return Standard_True; | |
7af17f1e MA |
230 | } |
231 | ||
232 | //======================================================================= | |
233 | //function : LogFileHandler::Close | |
234 | //purpose : | |
235 | //======================================================================= | |
236 | ||
237 | void OSD_MAllocHook::LogFileHandler::Close() | |
238 | { | |
64531d9c | 239 | if (myLogFile.is_open()) |
7af17f1e | 240 | { |
64531d9c | 241 | myLogFile.close(); |
7af17f1e MA |
242 | } |
243 | } | |
244 | ||
245 | //======================================================================= | |
246 | //function : LogFileHandler::MakeReport | |
247 | //purpose : | |
248 | //======================================================================= | |
9eefb360 | 249 | namespace |
7af17f1e | 250 | { |
9eefb360 | 251 | struct StorageInfo |
7af17f1e | 252 | { |
9eefb360 | 253 | Standard_Size size; |
254 | Standard_Integer nbAlloc; | |
255 | Standard_Integer nbFree; | |
256 | Standard_Integer nbLeftPeak; | |
257 | std::set<unsigned long> alive; | |
258 | ||
259 | StorageInfo(Standard_Size theSize = 0) | |
260 | : size (theSize), | |
261 | nbAlloc (0), | |
262 | nbFree (0), | |
263 | nbLeftPeak(0), | |
264 | alive() | |
265 | { | |
266 | } | |
267 | ||
268 | bool operator < (const StorageInfo& theOther) const | |
269 | { | |
270 | return size < theOther.size; | |
271 | } | |
272 | }; | |
273 | } | |
7af17f1e | 274 | |
7af17f1e MA |
275 | Standard_Boolean OSD_MAllocHook::LogFileHandler::MakeReport |
276 | (const char* theLogFile, | |
277 | const char* theOutFile, | |
278 | const Standard_Boolean theIncludeAlive) | |
279 | { | |
280 | // open log file | |
281 | FILE* aLogFile = fopen(theLogFile, "r"); | |
282 | if (aLogFile == NULL) | |
283 | return Standard_False; | |
284 | ||
285 | // skip 2 header lines | |
286 | char aStr[MAX_STR]; | |
287 | if (fgets(aStr, MAX_STR-1, aLogFile) == NULL) | |
288 | { | |
289 | fclose(aLogFile); | |
290 | return Standard_False; | |
291 | } | |
292 | if (fgets(aStr, MAX_STR-1, aLogFile) == NULL) | |
293 | { | |
294 | fclose(aLogFile); | |
295 | return Standard_False; | |
296 | } | |
297 | ||
298 | // scan the log file | |
299 | size_t aTotalLeftSize = 0; | |
300 | size_t aTotalPeakSize = 0; | |
301 | std::set<StorageInfo> aStMap; | |
302 | while (fgets(aStr, MAX_STR-1, aLogFile) != NULL) | |
303 | { | |
304 | // detect operation type, request number and block size | |
305 | unsigned long aReqNum, aSize; | |
306 | char* aType = aStr; | |
307 | char* pStr = aStr; | |
308 | //sscanf(aStr, "%5s %lu %lu", aType, &aReqNum, &aSize); | |
309 | while (*pStr != ' ' && *pStr) pStr++; | |
310 | *pStr++ = '\0'; | |
311 | while (*pStr == ' ' && *pStr) pStr++; | |
312 | aReqNum = atol(pStr); | |
313 | while (*pStr != ' ' && *pStr) pStr++; | |
314 | while (*pStr == ' ' && *pStr) pStr++; | |
315 | aSize = atol(pStr); | |
316 | Standard_Boolean isAlloc = Standard_False; | |
317 | if (strcmp(aType, "alloc") == 0) | |
318 | { | |
319 | isAlloc = Standard_True; | |
320 | } | |
321 | else if (strcmp(aType, "free") != 0) | |
322 | continue; | |
323 | ||
324 | // collect statistics by storage size | |
325 | StorageInfo aSuchInfo(aSize); | |
326 | std::set<StorageInfo>::iterator aFound = aStMap.find(aSuchInfo); | |
327 | if (aFound == aStMap.end()) | |
328 | aFound = aStMap.insert(aSuchInfo).first; | |
329 | StorageInfo& aInfo = const_cast<StorageInfo&>(*aFound); | |
330 | if (isAlloc) | |
331 | { | |
332 | if (aInfo.nbAlloc + 1 > 0) | |
333 | aInfo.nbAlloc++; | |
334 | aTotalLeftSize += aSize; | |
335 | if (aTotalLeftSize > aTotalPeakSize) | |
336 | aTotalPeakSize = aTotalLeftSize; | |
337 | int nbLeft = aInfo.nbAlloc - aInfo.nbFree; | |
338 | if (nbLeft > aInfo.nbLeftPeak) | |
339 | aInfo.nbLeftPeak = nbLeft; | |
96f3bacc | 340 | aInfo.alive.insert(aReqNum); |
7af17f1e MA |
341 | } |
342 | else | |
343 | { | |
344 | std::set<unsigned long>::iterator aFoundReqNum = | |
96f3bacc | 345 | aInfo.alive.find(aReqNum); |
346 | if (aFoundReqNum == aInfo.alive.end()) | |
7af17f1e MA |
347 | // freeing non-registered block, skip it |
348 | continue; | |
349 | aTotalLeftSize -= aSize; | |
96f3bacc | 350 | aInfo.alive.erase(aFoundReqNum); |
7af17f1e MA |
351 | if (aInfo.nbAlloc + 1 > 0) |
352 | aInfo.nbFree++; | |
353 | } | |
354 | } | |
355 | fclose(aLogFile); | |
356 | ||
357 | // print the report | |
64531d9c | 358 | std::ofstream aRepFile (theOutFile); |
359 | if(!aRepFile.is_open()) | |
360 | { | |
7af17f1e | 361 | return Standard_False; |
64531d9c | 362 | } |
363 | aRepFile.imbue (std::locale ("C")); | |
364 | ||
365 | aRepFile << std::setw(20) << "BlockSize " | |
366 | << std::setw(10) << "NbAlloc " | |
367 | << std::setw(10) << "NbLeft " | |
368 | << std::setw(10) << "NbLeftPeak " | |
369 | << std::setw(20) << "AllocSize " | |
370 | << std::setw(20) << "LeftSize " | |
371 | << std::setw(20) << "PeakSize " << std::endl; | |
372 | ||
7af17f1e MA |
373 | Standard_Size aTotAlloc = 0; |
374 | for (std::set<StorageInfo>::const_iterator it = aStMap.begin(); | |
375 | it != aStMap.end(); ++it) | |
376 | { | |
377 | const StorageInfo& aInfo = *it; | |
378 | Standard_Integer nbLeft = aInfo.nbAlloc - aInfo.nbFree; | |
379 | Standard_Size aSizeAlloc = aInfo.nbAlloc * aInfo.size; | |
380 | Standard_Size aSizeLeft = nbLeft * aInfo.size; | |
381 | Standard_Size aSizePeak = aInfo.nbLeftPeak * aInfo.size; | |
64531d9c | 382 | |
383 | aRepFile << std::setw(20) << aInfo.size << ' ' | |
384 | << std::setw(10) << aInfo.nbAlloc << ' ' | |
385 | << std::setw(10) << nbLeft << ' ' | |
386 | << std::setw(10) << aInfo.nbLeftPeak << ' ' | |
387 | << std::setw(20) << aSizeAlloc << ' ' | |
388 | << std::setw(20) << aSizeLeft << ' ' | |
389 | << std::setw(20) << aSizePeak << std::endl; | |
390 | ||
7af17f1e MA |
391 | if (aTotAlloc + aSizeAlloc < aTotAlloc) // overflow ? |
392 | aTotAlloc = SIZE_MAX; | |
393 | else | |
394 | aTotAlloc += aSizeAlloc; | |
96f3bacc | 395 | if (theIncludeAlive && !aInfo.alive.empty()) |
7af17f1e | 396 | { |
96f3bacc | 397 | for (std::set<unsigned long>::const_iterator it1 = aInfo.alive.begin(); |
398 | it1 != aInfo.alive.end(); ++it1) | |
64531d9c | 399 | aRepFile << std::setw(10) << *it1; |
7af17f1e MA |
400 | } |
401 | } | |
64531d9c | 402 | aRepFile << std::setw(20) << "Total:" |
403 | << std::setw(10) << "" << ' ' | |
404 | << std::setw(10) << "" << ' ' | |
405 | << std::setw(10) << "" << ' ' | |
406 | << (aTotAlloc == SIZE_MAX ? '>' : ' ') | |
407 | << std::setw(20) << aTotAlloc << ' ' | |
408 | << std::setw(20) << aTotalLeftSize << ' ' | |
409 | << std::setw(20) << aTotalPeakSize << std::endl; | |
410 | ||
411 | aRepFile.close(); | |
7af17f1e MA |
412 | return Standard_True; |
413 | } | |
414 | ||
415 | //======================================================================= | |
416 | //function : LogFileHandler::AllocEvent | |
417 | //purpose : | |
418 | //======================================================================= | |
419 | ||
420 | void OSD_MAllocHook::LogFileHandler::AllocEvent | |
421 | (size_t theSize, | |
422 | long theRequestNum) | |
423 | { | |
64531d9c | 424 | if (myLogFile.is_open()) |
7af17f1e MA |
425 | { |
426 | myMutex.Lock(); | |
64531d9c | 427 | myLogFile << "alloc "<< std::setw(10) << theRequestNum |
428 | << std::setw(20) << theSize << std::endl; | |
7af17f1e | 429 | if (myBreakSize == theSize) |
302f96fb | 430 | place_for_breakpoint(); |
431 | myMutex.Unlock(); | |
7af17f1e MA |
432 | } |
433 | } | |
434 | ||
435 | //======================================================================= | |
436 | //function : LogFileHandler::FreeEvent | |
437 | //purpose : | |
438 | //======================================================================= | |
439 | ||
440 | void OSD_MAllocHook::LogFileHandler::FreeEvent | |
441 | (void* /*theData*/, | |
442 | size_t theSize, | |
443 | long theRequestNum) | |
444 | { | |
64531d9c | 445 | if (myLogFile.is_open()) |
7af17f1e MA |
446 | { |
447 | myMutex.Lock(); | |
64531d9c | 448 | myLogFile << "free " << std::setw(20) << theRequestNum |
449 | << std::setw(20) << theSize << std::endl; | |
7af17f1e MA |
450 | myMutex.Unlock(); |
451 | } | |
452 | } | |
453 | ||
454 | //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
455 | // CollectBySize handler methods | |
456 | //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | |
457 | ||
458 | //======================================================================= | |
459 | //function : CollectBySize::CollectBySize | |
460 | //purpose : | |
461 | //======================================================================= | |
462 | ||
463 | OSD_MAllocHook::CollectBySize::CollectBySize() | |
464 | : myArray(NULL), | |
465 | myTotalLeftSize(0), | |
466 | myTotalPeakSize(0), | |
941a7a24 | 467 | myBreakSize(0), |
468 | myBreakPeak(0) | |
7af17f1e MA |
469 | { |
470 | Reset(); | |
471 | } | |
472 | ||
473 | //======================================================================= | |
474 | //function : CollectBySize::~CollectBySize | |
475 | //purpose : | |
476 | //======================================================================= | |
477 | ||
478 | OSD_MAllocHook::CollectBySize::~CollectBySize() | |
479 | { | |
480 | if (myArray != NULL) | |
481 | delete [] myArray; | |
482 | } | |
483 | ||
484 | //======================================================================= | |
485 | //function : CollectBySize::Reset | |
486 | //purpose : | |
487 | //======================================================================= | |
488 | ||
8cb69787 | 489 | #define MAX_ALLOC_SIZE 2000000 |
1cc1abe1 | 490 | const size_t OSD_MAllocHook::CollectBySize::myMaxAllocSize = MAX_ALLOC_SIZE; |
7af17f1e MA |
491 | |
492 | void OSD_MAllocHook::CollectBySize::Reset() | |
493 | { | |
494 | myMutex.Lock(); | |
495 | if (myArray == NULL) | |
496 | myArray = new Numbers[MAX_ALLOC_SIZE]; | |
497 | else | |
498 | { | |
499 | for (int i = 0; i < MAX_ALLOC_SIZE; i++) | |
500 | myArray[i] = Numbers(); | |
501 | } | |
502 | myTotalLeftSize = 0; | |
503 | myTotalPeakSize = 0; | |
504 | myMutex.Unlock(); | |
505 | } | |
506 | ||
507 | //======================================================================= | |
508 | //function : CollectBySize::MakeReport | |
509 | //purpose : | |
510 | //======================================================================= | |
511 | ||
512 | Standard_Boolean OSD_MAllocHook::CollectBySize::MakeReport(const char* theOutFile) | |
513 | { | |
514 | // print the report | |
64531d9c | 515 | std::ofstream aRepFile(theOutFile); |
516 | if (!aRepFile.is_open()) | |
7af17f1e | 517 | return Standard_False; |
64531d9c | 518 | std::locale aCLoc("C"); |
519 | aRepFile.imbue(aCLoc); | |
520 | ||
521 | aRepFile << std::setw(10) << "BlockSize " | |
522 | << std::setw(10) << "NbAlloc " | |
523 | << std::setw(10) << "NbLeft " | |
524 | << std::setw(10) << "NbLeftPeak " | |
525 | << std::setw(20) << "AllocSize " | |
526 | << std::setw(20) << "LeftSize " | |
527 | << std::setw(20) << "PeakSize " << std::endl; | |
528 | ||
7af17f1e MA |
529 | Standard_Size aTotAlloc = 0; |
530 | for (int i = 0; i < MAX_ALLOC_SIZE; i++) | |
531 | { | |
13b4230b | 532 | if (myArray[i].nbAlloc > 0 || myArray[i].nbFree > 0) |
7af17f1e MA |
533 | { |
534 | Standard_Integer nbLeft = myArray[i].nbAlloc - myArray[i].nbFree; | |
7af17f1e MA |
535 | int aSize = i + 1; |
536 | Standard_Size aSizeAlloc = myArray[i].nbAlloc * aSize; | |
13b4230b | 537 | ptrdiff_t aSizeLeft = nbLeft * aSize; |
7af17f1e | 538 | Standard_Size aSizePeak = myArray[i].nbLeftPeak * aSize; |
64531d9c | 539 | |
540 | aRepFile << std::setw(10) << aSize << ' ' | |
541 | << std::setw(10) << myArray[i].nbAlloc << ' ' | |
542 | << std::setw(10) << nbLeft << ' ' | |
543 | << std::setw(10) << myArray[i].nbLeftPeak << ' ' | |
544 | << std::setw(20) << aSizeAlloc << ' ' | |
545 | << std::setw(20) << aSizeLeft << ' ' | |
546 | << std::setw(20) << aSizePeak << std::endl; | |
547 | ||
7af17f1e MA |
548 | if (aTotAlloc + aSizeAlloc < aTotAlloc) // overflow ? |
549 | aTotAlloc = SIZE_MAX; | |
550 | else | |
551 | aTotAlloc += aSizeAlloc; | |
552 | } | |
553 | } | |
64531d9c | 554 | aRepFile << std::setw(10) << "Total:" << ' ' |
555 | << std::setw(10) << "" << ' ' | |
556 | << std::setw(10) << "" << ' ' | |
557 | << std::setw(10) << "" << ' ' | |
558 | << (aTotAlloc == SIZE_MAX ? '>' : ' ') | |
559 | << std::setw(20) << aTotAlloc << ' ' | |
560 | << std::setw(20) << myTotalLeftSize << ' ' | |
561 | << std::setw(20) << myTotalPeakSize << std::endl; | |
562 | aRepFile.close(); | |
7af17f1e MA |
563 | return Standard_True; |
564 | } | |
565 | ||
566 | //======================================================================= | |
567 | //function : CollectBySize::AllocEvent | |
568 | //purpose : | |
569 | //======================================================================= | |
570 | ||
571 | void OSD_MAllocHook::CollectBySize::AllocEvent | |
572 | (size_t theSize, | |
573 | long /*theRequestNum*/) | |
574 | { | |
575 | if (myBreakSize == theSize) | |
302f96fb | 576 | place_for_breakpoint(); |
7af17f1e MA |
577 | if (theSize > 0) |
578 | { | |
579 | myMutex.Lock(); | |
580 | int ind = (theSize > MAX_ALLOC_SIZE ? MAX_ALLOC_SIZE-1 : (int)(theSize-1)); | |
13b4230b | 581 | myArray[ind].nbAlloc++; |
7af17f1e MA |
582 | myTotalLeftSize += theSize; |
583 | int nbLeft = myArray[ind].nbAlloc - myArray[ind].nbFree; | |
584 | if (nbLeft > myArray[ind].nbLeftPeak) | |
941a7a24 | 585 | { |
7af17f1e | 586 | myArray[ind].nbLeftPeak = nbLeft; |
941a7a24 | 587 | if (myBreakPeak != 0 |
588 | && (myBreakSize == theSize || myBreakSize == 0)) | |
589 | { | |
590 | const Standard_Size aSizePeak = myArray[ind].nbLeftPeak * theSize; | |
591 | if (aSizePeak > myBreakPeak) | |
592 | { | |
593 | place_for_breakpoint(); | |
594 | } | |
595 | } | |
596 | } | |
13b4230b | 597 | if (myTotalLeftSize > (ptrdiff_t)myTotalPeakSize) |
7af17f1e MA |
598 | myTotalPeakSize = myTotalLeftSize; |
599 | myMutex.Unlock(); | |
600 | } | |
601 | } | |
602 | ||
603 | //======================================================================= | |
604 | //function : CollectBySize::FreeEvent | |
605 | //purpose : | |
606 | //======================================================================= | |
607 | ||
608 | void OSD_MAllocHook::CollectBySize::FreeEvent | |
609 | (void* /*theData*/, | |
610 | size_t theSize, | |
611 | long /*theRequestNum*/) | |
612 | { | |
13b4230b | 613 | if (theSize > 0) |
7af17f1e MA |
614 | { |
615 | myMutex.Lock(); | |
616 | int ind = (theSize > MAX_ALLOC_SIZE ? MAX_ALLOC_SIZE-1 : (int)(theSize-1)); | |
13b4230b | 617 | myArray[ind].nbFree++; |
7af17f1e MA |
618 | myTotalLeftSize -= theSize; |
619 | myMutex.Unlock(); | |
620 | } | |
621 | } |