0024512: clang++ compiler complains about extra semicolon
[occt.git] / src / OSD / OSD_MAllocHook.cxx
old mode 100755 (executable)
new mode 100644 (file)
index 8ed4385..b8081bd
@@ -1,7 +1,17 @@
-// File:       OSD_MAllocHook.cxx
-// Created:    04.02.2011
-// Author:     Mikhail SAZONOV
-// Copyright:  Open CASCADE S.A.S. 2011
+// Created on: 2011-02-04
+// Created by: Mikhail SAZONOV
+// Copyright (c) 2011-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and / or modify it
+// under the terms of the GNU Lesser General Public version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
 #include <OSD_MAllocHook.hxx>
 
 
 #include <set>
 #include <map>
+#include <cstdlib>
+#include <iomanip>
+
+#ifndef SIZE_MAX
+#define SIZE_MAX UINT_MAX
+#endif
 
 #define MAX_STR 80
 
 static OSD_MAllocHook::Callback* MypCurrentCallback = NULL;
 
+namespace {
+  // dummy function to call at place where break point might be needed
+  inline void place_for_breakpoint () {}
+}
+
 //=======================================================================
 //function : GetCallback
 //purpose  :
@@ -58,33 +79,46 @@ OSD_MAllocHook::CollectBySize* OSD_MAllocHook::GetCollectBySize()
 #ifdef WNT
 #include <crtdbg.h>
 
+#if _MSC_VER == 1500  /* VS 2008 */
+
 static long getRequestNum(void* pvData, long lRequest, size_t& theSize)
 {
-  if (_CrtIsValidHeapPointer(pvData))
-  {
-#if _MSC_VER == 1500   // VS 2008
+#ifdef _DEBUG /* protect against invalid pointer; in Release, _CrtIsValidHeapPointer is always 1 */
+  if (!_CrtIsValidHeapPointer(pvData))
+    return lRequest;
+#else
+  (void)lRequest; // avoid compiler warning on unused arg
+#endif
+
 #define nNoMansLandSize 4
-    // the header struct is taken from crt/src/dbgint.h
-    struct _CrtMemBlockHeader
-    {
+  // the header struct is taken from crt/src/dbgint.h
+  struct _CrtMemBlockHeader
+  {
 #ifdef _WIN64
-        int                         nBlockUse;
-        size_t                      nDataSize;
+      int                         nBlockUse;
+      size_t                      nDataSize;
 #else
-        size_t                      nDataSize;
-        int                         nBlockUse;
+      size_t                      nDataSize;
+      int                         nBlockUse;
 #endif
-      long                        lRequest;
-      unsigned char               gap[nNoMansLandSize];
-    };
-    _CrtMemBlockHeader* aHeader = ((_CrtMemBlockHeader*)pvData)-1;
-    theSize = aHeader->nDataSize;
-    return aHeader->lRequest;
-#endif
-  }
+    long                        lRequest;
+    unsigned char               gap[nNoMansLandSize];
+  };
+
+  _CrtMemBlockHeader* aHeader = ((_CrtMemBlockHeader*)pvData)-1;
+  theSize = aHeader->nDataSize;
+  return aHeader->lRequest;
+}
+
+#else /* _MSC_VER == 1500 */
+
+static long getRequestNum(void* /*pvData*/, long lRequest, size_t& /*theSize*/)
+{
   return lRequest;
 }
 
+#endif /* _MSC_VER == 1500 */
+
 int __cdecl MyAllocHook(int      nAllocType,
                         void   * pvData,
                         size_t   nSize,
@@ -155,9 +189,9 @@ void OSD_MAllocHook::SetCallback(Callback* theCB)
 //=======================================================================
 
 OSD_MAllocHook::LogFileHandler::LogFileHandler()
-: myLogFile(NULL),
-  myBreakSize(0)
+: myBreakSize(0)
 {
+  myLogFile.imbue (std::locale ("C"));
 }
 
 //=======================================================================
@@ -178,13 +212,15 @@ OSD_MAllocHook::LogFileHandler::~LogFileHandler()
 Standard_Boolean OSD_MAllocHook::LogFileHandler::Open(const char* theFileName)
 {
   Close();
-  myLogFile = fopen(theFileName, "w");
-  if (myLogFile != NULL)
+  myLogFile.open (theFileName);
+  if (!myLogFile.is_open())
   {
-    fputs("Operation type; Request Number; Block Size\n", myLogFile);
-    fputs("------------------------------------------\n", myLogFile);
+    return Standard_False;
   }
-  return myLogFile != NULL;
+
+  myLogFile << "Operation type; Request Number; Block Size\n"
+               "------------------------------------------\n";
+  return Standard_True;
 }
 
 //=======================================================================
@@ -194,10 +230,9 @@ Standard_Boolean OSD_MAllocHook::LogFileHandler::Open(const char* theFileName)
 
 void OSD_MAllocHook::LogFileHandler::Close()
 {
-  if (myLogFile != NULL)
+  if (myLogFile.is_open())
   {
-    fclose(myLogFile);
-    myLogFile = NULL;
+    myLogFile.close();
   }
 }
 
@@ -322,12 +357,21 @@ Standard_Boolean OSD_MAllocHook::LogFileHandler::MakeReport
   fclose(aLogFile);
 
   // print the report
-  FILE* aRepFile = fopen(theOutFile, "w");
-  if (aRepFile == NULL)
+  std::ofstream aRepFile (theOutFile);
+  if(!aRepFile.is_open())
+  {
     return Standard_False;
-  fprintf(aRepFile, "%10s %10s %10s %10s %10s %10s %10s\n",
-          "BlockSize", "NbAlloc", "NbLeft", "NbLeftPeak",
-          "AllocSize", "LeftSize", "PeakSize");
+  }
+  aRepFile.imbue (std::locale ("C"));
+
+  aRepFile << std::setw(20) << "BlockSize "
+           << std::setw(10) << "NbAlloc "
+           << std::setw(10) << "NbLeft "
+           << std::setw(10) << "NbLeftPeak "
+           << std::setw(20) << "AllocSize "
+           << std::setw(20) << "LeftSize "
+           << std::setw(20) << "PeakSize " << std::endl;
+
   Standard_Size aTotAlloc = 0;
   for (std::set<StorageInfo>::const_iterator it = aStMap.begin();
        it != aStMap.end(); ++it)
@@ -337,9 +381,15 @@ Standard_Boolean OSD_MAllocHook::LogFileHandler::MakeReport
     Standard_Size aSizeAlloc = aInfo.nbAlloc * aInfo.size;
     Standard_Size aSizeLeft = nbLeft * aInfo.size;
     Standard_Size aSizePeak = aInfo.nbLeftPeak * aInfo.size;
-    fprintf(aRepFile, "%10d %10d %10d %10d %10Iu %10Iu %10Iu\n", aInfo.size,
-            aInfo.nbAlloc, nbLeft, aInfo.nbLeftPeak,
-            aSizeAlloc, aSizeLeft, aSizePeak);
+
+    aRepFile << std::setw(20) << aInfo.size << ' '
+             << std::setw(10) << aInfo.nbAlloc << ' '
+             << std::setw(10) << nbLeft << ' '
+             << std::setw(10) << aInfo.nbLeftPeak << ' '
+             << std::setw(20) << aSizeAlloc << ' '
+             << std::setw(20) << aSizeLeft << ' '
+             << std::setw(20) << aSizePeak << std::endl;
+
     if (aTotAlloc + aSizeAlloc < aTotAlloc) // overflow ?
       aTotAlloc = SIZE_MAX;
     else
@@ -348,13 +398,19 @@ Standard_Boolean OSD_MAllocHook::LogFileHandler::MakeReport
     {
       for (std::set<unsigned long>::const_iterator it1 = aInfo.alive->begin();
            it1 != aInfo.alive->end(); ++it1)
-        fprintf(aRepFile, "%10lu\n", *it1);
+      aRepFile << std::setw(10) << *it1;
     }
   }
-  fprintf(aRepFile, "%10s %10s %10s %10s%c%10Iu %10Iu %10Iu\n", "Total:",
-          "", "", "", (aTotAlloc == SIZE_MAX ? '>' : ' '), aTotAlloc,
-          aTotalLeftSize, aTotalPeakSize);
-  fclose(aRepFile);
+  aRepFile << std::setw(20) << "Total:"
+           << std::setw(10) << "" << ' '
+           << std::setw(10) << "" << ' '
+           << std::setw(10) << "" << ' '
+           << (aTotAlloc == SIZE_MAX ? '>' : ' ')
+           << std::setw(20) << aTotAlloc << ' '
+           << std::setw(20) << aTotalLeftSize << ' '
+           << std::setw(20) << aTotalPeakSize << std::endl;
+
+  aRepFile.close();
   return Standard_True;
 }
 
@@ -367,15 +423,14 @@ void OSD_MAllocHook::LogFileHandler::AllocEvent
                    (size_t      theSize,
                     long        theRequestNum)
 {
-  if (myLogFile != NULL)
+  if (myLogFile.is_open())
   {
     myMutex.Lock();
-    fprintf(myLogFile, "alloc %10lu %10u\n", theRequestNum, theSize);
-    myMutex.Unlock();
+    myLogFile << "alloc "<< std::setw(10) << theRequestNum
+              << std::setw(20) << theSize << std::endl;
     if (myBreakSize == theSize)
-    {
-      int a = 1;
-    }
+      place_for_breakpoint();
+    myMutex.Unlock();
   }
 }
 
@@ -389,10 +444,11 @@ void OSD_MAllocHook::LogFileHandler::FreeEvent
                     size_t      theSize,
                     long        theRequestNum)
 {
-  if (myLogFile != NULL)
+  if (myLogFile.is_open())
   {
     myMutex.Lock();
-    fprintf(myLogFile, "free  %10lu %10u\n", theRequestNum, theSize);
+    myLogFile << "free " << std::setw(20) << theRequestNum
+              << std::setw(20) << theSize << std::endl;
     myMutex.Unlock();
   }
 }
@@ -410,7 +466,8 @@ OSD_MAllocHook::CollectBySize::CollectBySize()
 : myArray(NULL),
   myTotalLeftSize(0),
   myTotalPeakSize(0),
-  myBreakSize(0)
+  myBreakSize(0),
+  myBreakPeak(0)
 {
   Reset();
 }
@@ -432,6 +489,7 @@ OSD_MAllocHook::CollectBySize::~CollectBySize()
 //=======================================================================
 
 #define MAX_ALLOC_SIZE 2000000u
+const size_t OSD_MAllocHook::CollectBySize::myMaxAllocSize = MAX_ALLOC_SIZE;
 
 void OSD_MAllocHook::CollectBySize::Reset()
 {
@@ -456,37 +514,54 @@ void OSD_MAllocHook::CollectBySize::Reset()
 Standard_Boolean OSD_MAllocHook::CollectBySize::MakeReport(const char* theOutFile)
 {
   // print the report
-  FILE* aRepFile = fopen(theOutFile, "w");
-  if (aRepFile == NULL)
+  std::ofstream aRepFile(theOutFile);
+  if (!aRepFile.is_open())
     return Standard_False;
-  fprintf(aRepFile, "%10s %10s %10s %10s %10s %10s %10s\n",
-          "BlockSize", "NbAlloc", "NbLeft", "NbLeftPeak",
-          "AllocSize", "LeftSize", "PeakSize");
+  std::locale aCLoc("C");
+  aRepFile.imbue(aCLoc);
+
+  aRepFile << std::setw(10) << "BlockSize "
+           << std::setw(10) << "NbAlloc "
+           << std::setw(10) << "NbLeft "
+           << std::setw(10) << "NbLeftPeak "
+           << std::setw(20) << "AllocSize "
+           << std::setw(20) << "LeftSize "
+           << std::setw(20) << "PeakSize " << std::endl;
+
   Standard_Size aTotAlloc = 0;
   for (int i = 0; i < MAX_ALLOC_SIZE; i++)
   {
-    if (myArray[i].nbAlloc > 0)
+    if (myArray[i].nbAlloc > 0 || myArray[i].nbFree > 0)
     {
       Standard_Integer nbLeft = myArray[i].nbAlloc - myArray[i].nbFree;
-      if (nbLeft < 0)
-        nbLeft = 0;
       int aSize = i + 1;
       Standard_Size aSizeAlloc = myArray[i].nbAlloc * aSize;
-      Standard_Size aSizeLeft = nbLeft * aSize;
+      ptrdiff_t     aSizeLeft = nbLeft * aSize;
       Standard_Size aSizePeak = myArray[i].nbLeftPeak * aSize;
-      fprintf(aRepFile, "%10d %10d %10d %10d %10Iu %10Iu %10Iu\n", aSize,
-              myArray[i].nbAlloc, nbLeft, myArray[i].nbLeftPeak,
-              aSizeAlloc, aSizeLeft, aSizePeak);
+
+      aRepFile << std::setw(10) << aSize << ' '
+               << std::setw(10) << myArray[i].nbAlloc << ' '
+               << std::setw(10) << nbLeft << ' '
+               << std::setw(10) << myArray[i].nbLeftPeak << ' '
+               << std::setw(20) << aSizeAlloc << ' '
+               << std::setw(20) << aSizeLeft << ' '
+               << std::setw(20) << aSizePeak << std::endl;
+
       if (aTotAlloc + aSizeAlloc < aTotAlloc) // overflow ?
         aTotAlloc = SIZE_MAX;
       else
         aTotAlloc += aSizeAlloc;
     }
   }
-  fprintf(aRepFile, "%10s %10s %10s %10s%c%10Iu %10Iu %10Iu\n", "Total:",
-          "", "", "", (aTotAlloc == SIZE_MAX ? '>' : ' '), aTotAlloc,
-          myTotalLeftSize, myTotalPeakSize);
-  fclose(aRepFile);
+  aRepFile << std::setw(10) << "Total:" << ' '
+           << std::setw(10) << "" << ' '
+           << std::setw(10) << "" << ' '
+           << std::setw(10) << "" << ' '
+           << (aTotAlloc == SIZE_MAX ? '>' : ' ')
+           << std::setw(20) << aTotAlloc  << ' '
+           << std::setw(20) << myTotalLeftSize  << ' '
+           << std::setw(20) << myTotalPeakSize << std::endl;
+  aRepFile.close();
   return Standard_True;
 }
 
@@ -500,20 +575,28 @@ void OSD_MAllocHook::CollectBySize::AllocEvent
                     long        /*theRequestNum*/)
 {
   if (myBreakSize == theSize)
-  {
-    int a = 1;
-  }
+    place_for_breakpoint();
   if (theSize > 0)
   {
     myMutex.Lock();
     int ind = (theSize > MAX_ALLOC_SIZE ? MAX_ALLOC_SIZE-1 : (int)(theSize-1));
-    if (myArray[ind].nbAlloc + 1 > 0)
-      myArray[ind].nbAlloc++;
+    myArray[ind].nbAlloc++;
     myTotalLeftSize += theSize;
     int nbLeft = myArray[ind].nbAlloc - myArray[ind].nbFree;
     if (nbLeft > myArray[ind].nbLeftPeak)
+    {
       myArray[ind].nbLeftPeak = nbLeft;
-    if (myTotalLeftSize > myTotalPeakSize)
+      if (myBreakPeak != 0
+       && (myBreakSize == theSize || myBreakSize == 0))
+      {
+        const Standard_Size aSizePeak = myArray[ind].nbLeftPeak * theSize;
+        if (aSizePeak > myBreakPeak)
+        {
+          place_for_breakpoint();
+        }
+      }
+    }
+    if (myTotalLeftSize > (ptrdiff_t)myTotalPeakSize)
       myTotalPeakSize = myTotalLeftSize;
     myMutex.Unlock();
   }
@@ -529,12 +612,11 @@ void OSD_MAllocHook::CollectBySize::FreeEvent
                     size_t      theSize,
                     long        /*theRequestNum*/)
 {
-  if (theSize > 0 && myTotalLeftSize >= theSize)
+  if (theSize > 0)
   {
     myMutex.Lock();
     int ind = (theSize > MAX_ALLOC_SIZE ? MAX_ALLOC_SIZE-1 : (int)(theSize-1));
-    if (myArray[ind].nbFree + 1 > 0)
-      myArray[ind].nbFree++;
+    myArray[ind].nbFree++;
     myTotalLeftSize -= theSize;
     myMutex.Unlock();
   }