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