From 0e8d1aef2097d8ff3121ede7873ca46608610d2d Mon Sep 17 00:00:00 2001 From: nds Date: Tue, 28 Jan 2020 15:01:42 +0300 Subject: [PATCH] 0030904: Visualization - OSD_MemInfo provide Update with parameter of computation kind Added method OSD_MemInfo::SetActive() for disabling specific counter. (cherry picked from commit eeeb58738f5764570990bc4a44c0ab187e5d6b80) (cherry picked from commit 8ba570a1b6140ff2bf47d9c87baca8b846ffa755) (cherry picked from commit 30ed014a3e726d75082c35519e3c6fbe29742dec) (cherry picked from commit 82afec25b64d04d5d0b7cfa5aca20e9556495ef6) (cherry picked from commit 157ba236509ca28aaed3eca18dedb72186ff1191) (cherry picked from commit 851779a01e421d19ce4c683a4fcad513118b30ec) --- src/Draw/Draw_BasicCommands.cxx | 30 ++++-- src/OSD/OSD_MemInfo.cxx | 167 +++++++++++++++++++++----------- src/OSD/OSD_MemInfo.hxx | 22 ++++- 3 files changed, 155 insertions(+), 64 deletions(-) diff --git a/src/Draw/Draw_BasicCommands.cxx b/src/Draw/Draw_BasicCommands.cxx index 8c57448a03..467bd42297 100644 --- a/src/Draw/Draw_BasicCommands.cxx +++ b/src/Draw/Draw_BasicCommands.cxx @@ -767,50 +767,64 @@ static int dmeminfo (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec) { - OSD_MemInfo aMemInfo; if (theArgNb <= 1) { + OSD_MemInfo aMemInfo; theDI << aMemInfo.ToString(); return 0; } + NCollection_Map aCounters; for (Standard_Integer anIter = 1; anIter < theArgNb; ++anIter) { TCollection_AsciiString anArg (theArgVec[anIter]); anArg.LowerCase(); if (anArg == "virt" || anArg == "v") { - theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemVirtual)) << " "; + aCounters.Add (OSD_MemInfo::MemVirtual); } else if (anArg == "heap" || anArg == "h") { - theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemHeapUsage)) << " "; + aCounters.Add (OSD_MemInfo::MemHeapUsage); } else if (anArg == "wset" || anArg == "w") { - theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemWorkingSet)) << " "; + aCounters.Add (OSD_MemInfo::MemWorkingSet); } else if (anArg == "wsetpeak") { - theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemWorkingSetPeak)) << " "; + aCounters.Add (OSD_MemInfo::MemWorkingSetPeak); } else if (anArg == "swap") { - theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemSwapUsage)) << " "; + aCounters.Add (OSD_MemInfo::MemSwapUsage); } else if (anArg == "swappeak") { - theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemSwapUsagePeak)) << " "; + aCounters.Add (OSD_MemInfo::MemSwapUsagePeak); } else if (anArg == "private") { - theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemPrivate)) << " "; + aCounters.Add (OSD_MemInfo::MemPrivate); } else { std::cerr << "Unknown argument '" << theArgVec[anIter] << "'!\n"; } } + + OSD_MemInfo aMemInfo (Standard_False); + aMemInfo.SetActive (Standard_False); + for (NCollection_Map::Iterator aCountersIt (aCounters); aCountersIt.More(); aCountersIt.Next()) + { + aMemInfo.SetActive (aCountersIt.Value(), Standard_True); + } + aMemInfo.Update(); + + for (NCollection_Map::Iterator aCountersIt (aCounters); aCountersIt.More(); aCountersIt.Next()) + { + theDI << Standard_Real (aMemInfo.Value (aCountersIt.Value())) << " "; + } theDI << "\n"; return 0; } diff --git a/src/OSD/OSD_MemInfo.cxx b/src/OSD/OSD_MemInfo.cxx index 277804e203..7893bf3316 100644 --- a/src/OSD/OSD_MemInfo.cxx +++ b/src/OSD/OSD_MemInfo.cxx @@ -43,6 +43,7 @@ // ======================================================================= OSD_MemInfo::OSD_MemInfo (const Standard_Boolean theImmediateUpdate) { + SetActive (Standard_True); if (theImmediateUpdate) { Update(); @@ -53,6 +54,17 @@ OSD_MemInfo::OSD_MemInfo (const Standard_Boolean theImmediateUpdate) } } +// ======================================================================= +// function : SetActive +// purpose : +// ======================================================================= +void OSD_MemInfo::SetActive (const Standard_Boolean theActive) +{ + for (Standard_Integer anIter = 0; anIter < MemCounter_NB; ++anIter) + { + SetActive ((Counter)anIter, theActive); + } +} // ======================================================================= // function : Clear @@ -76,47 +88,82 @@ void OSD_MemInfo::Update() #ifndef OCCT_UWP #if defined(_WIN32) #if (_WIN32_WINNT >= 0x0500) - MEMORYSTATUSEX aStatEx; - aStatEx.dwLength = sizeof(aStatEx); - GlobalMemoryStatusEx (&aStatEx); - myCounters[MemVirtual] = Standard_Size(aStatEx.ullTotalVirtual - aStatEx.ullAvailVirtual); + if (IsActive (MemVirtual)) + { + MEMORYSTATUSEX aStatEx; + aStatEx.dwLength = sizeof(aStatEx); + GlobalMemoryStatusEx (&aStatEx); + myCounters[MemVirtual] = Standard_Size(aStatEx.ullTotalVirtual - aStatEx.ullAvailVirtual); + } #else - MEMORYSTATUS aStat; - aStat.dwLength = sizeof(aStat); - GlobalMemoryStatus (&aStat); - myCounters[MemVirtual] = Standard_Size(aStat.dwTotalVirtual - aStat.dwAvailVirtual); + if (IsActive (MemVirtual)) + { + MEMORYSTATUS aStat; + aStat.dwLength = sizeof(aStat); + GlobalMemoryStatus (&aStat); + myCounters[MemVirtual] = Standard_Size(aStat.dwTotalVirtual - aStat.dwAvailVirtual); + } #endif - // use Psapi library - HANDLE aProcess = GetCurrentProcess(); -#if (_WIN32_WINNT >= 0x0501) - PROCESS_MEMORY_COUNTERS_EX aProcMemCnts; -#else - PROCESS_MEMORY_COUNTERS aProcMemCnts; -#endif - if (GetProcessMemoryInfo (aProcess, (PROCESS_MEMORY_COUNTERS* )&aProcMemCnts, sizeof(aProcMemCnts))) + if (IsActive (MemPrivate) + || IsActive (MemWorkingSet) + || IsActive (MemWorkingSetPeak) + || IsActive (MemSwapUsage) + || IsActive (MemSwapUsagePeak)) { + // use Psapi library + HANDLE aProcess = GetCurrentProcess(); #if (_WIN32_WINNT >= 0x0501) - myCounters[MemPrivate] = aProcMemCnts.PrivateUsage; + PROCESS_MEMORY_COUNTERS_EX aProcMemCnts; + #else + PROCESS_MEMORY_COUNTERS aProcMemCnts; #endif - myCounters[MemWorkingSet] = aProcMemCnts.WorkingSetSize; - myCounters[MemWorkingSetPeak] = aProcMemCnts.PeakWorkingSetSize; - myCounters[MemSwapUsage] = aProcMemCnts.PagefileUsage; - myCounters[MemSwapUsagePeak] = aProcMemCnts.PeakPagefileUsage; + if (GetProcessMemoryInfo (aProcess, (PROCESS_MEMORY_COUNTERS* )&aProcMemCnts, sizeof(aProcMemCnts))) + { + #if (_WIN32_WINNT >= 0x0501) + myCounters[MemPrivate] = aProcMemCnts.PrivateUsage; + #endif + myCounters[MemWorkingSet] = aProcMemCnts.WorkingSetSize; + myCounters[MemWorkingSetPeak] = aProcMemCnts.PeakWorkingSetSize; + myCounters[MemSwapUsage] = aProcMemCnts.PagefileUsage; + myCounters[MemSwapUsagePeak] = aProcMemCnts.PeakPagefileUsage; + } } - _HEAPINFO hinfo; - int heapstatus; - hinfo._pentry = NULL; + if (IsActive (MemHeapUsage)) + { + _HEAPINFO hinfo; + int heapstatus; + hinfo._pentry = NULL; + + myCounters[MemHeapUsage] = 0; + while((heapstatus = _heapwalk(&hinfo)) == _HEAPOK) + { + if (hinfo._useflag == _USEDENTRY) + { + myCounters[MemHeapUsage] += hinfo._size; + } + } + } - myCounters[MemHeapUsage] = 0; - while((heapstatus = _heapwalk(&hinfo)) == _HEAPOK) +#elif (defined(__linux__) || defined(__linux) || defined(__EMSCRIPTEN__)) + const struct mallinfo aMI = mallinfo(); + if (IsActive (MemHeapUsage)) { - if(hinfo._useflag == _USEDENTRY) - myCounters[MemHeapUsage] += hinfo._size; + myCounters[MemHeapUsage] = aMI.uordblks; } +#if defined(__EMSCRIPTEN__) + // /proc/%d/status is not emulated - get more info from mallinfo() + if (IsActive (MemWorkingSet)) + { + myCounters[MemWorkingSet] = aMI.uordblks; + } + if (IsActive (MemWorkingSetPeak)) + { + myCounters[MemWorkingSetPeak] = aMI.usmblks; + } +#endif -#elif (defined(__linux__) || defined(__linux)) // use procfs on Linux char aBuff[4096]; snprintf (aBuff, sizeof(aBuff), "/proc/%d/status", getpid()); @@ -136,26 +183,31 @@ void OSD_MemInfo::Update() continue; } - if (strncmp (aBuff, "VmSize:", strlen ("VmSize:")) == 0) + if (IsActive (MemVirtual) + && strncmp (aBuff, "VmSize:", strlen ("VmSize:")) == 0) { myCounters[MemVirtual] = atol (aBuff + strlen ("VmSize:")) * 1024; } //else if (strncmp (aBuff, "VmPeak:", strlen ("VmPeak:")) == 0) // myVirtualPeak = atol (aBuff + strlen ("VmPeak:")) * 1024; - else if (strncmp (aBuff, "VmRSS:", strlen ("VmRSS:")) == 0) + else if (IsActive (MemWorkingSet) + && strncmp (aBuff, "VmRSS:", strlen ("VmRSS:")) == 0) { myCounters[MemWorkingSet] = atol (aBuff + strlen ("VmRSS:")) * 1024; // RSS - resident set size } - else if (strncmp (aBuff, "VmHWM:", strlen ("VmHWM:")) == 0) + else if (IsActive (MemWorkingSetPeak) + && strncmp (aBuff, "VmHWM:", strlen ("VmHWM:")) == 0) { myCounters[MemWorkingSetPeak] = atol (aBuff + strlen ("VmHWM:")) * 1024; // HWM - high water mark } - else if (strncmp (aBuff, "VmData:", strlen ("VmData:")) == 0) + else if (IsActive (MemPrivate) + && strncmp (aBuff, "VmData:", strlen ("VmData:")) == 0) { if (myCounters[MemPrivate] == Standard_Size(-1)) ++myCounters[MemPrivate]; myCounters[MemPrivate] += atol (aBuff + strlen ("VmData:")) * 1024; } - else if (strncmp (aBuff, "VmStk:", strlen ("VmStk:")) == 0) + else if (IsActive (MemPrivate) + && strncmp (aBuff, "VmStk:", strlen ("VmStk:")) == 0) { if (myCounters[MemPrivate] == Standard_Size(-1)) ++myCounters[MemPrivate]; myCounters[MemPrivate] += atol (aBuff + strlen ("VmStk:")) * 1024; @@ -167,20 +219,25 @@ void OSD_MemInfo::Update() myCounters[MemHeapUsage] = aMI.uordblks; #elif (defined(__APPLE__)) - struct task_basic_info aTaskInfo; - mach_msg_type_number_t aTaskInfoCount = TASK_BASIC_INFO_COUNT; - if (task_info (mach_task_self(), TASK_BASIC_INFO, - (task_info_t )&aTaskInfo, &aTaskInfoCount) == KERN_SUCCESS) + if (IsActive (MemVirtual) + || IsActive (MemWorkingSet) + || IsActive (MemHeapUsage)) { - // On Mac OS X, these values in bytes, not pages! - myCounters[MemVirtual] = aTaskInfo.virtual_size; - myCounters[MemWorkingSet] = aTaskInfo.resident_size; + struct task_basic_info aTaskInfo; + mach_msg_type_number_t aTaskInfoCount = TASK_BASIC_INFO_COUNT; + if (task_info (mach_task_self(), TASK_BASIC_INFO, + (task_info_t )&aTaskInfo, &aTaskInfoCount) == KERN_SUCCESS) + { + // On Mac OS X, these values in bytes, not pages! + myCounters[MemVirtual] = aTaskInfo.virtual_size; + myCounters[MemWorkingSet] = aTaskInfo.resident_size; - //Getting malloc statistics - malloc_statistics_t aStats; - malloc_zone_statistics (NULL, &aStats); + //Getting malloc statistics + malloc_statistics_t aStats; + malloc_zone_statistics (NULL, &aStats); - myCounters[MemHeapUsage] = aStats.size_in_use; + myCounters[MemHeapUsage] = aStats.size_in_use; + } } #endif #endif @@ -193,33 +250,33 @@ void OSD_MemInfo::Update() TCollection_AsciiString OSD_MemInfo::ToString() const { TCollection_AsciiString anInfo; - if (myCounters[MemPrivate] != Standard_Size(-1)) + if (hasValue (MemPrivate)) { anInfo += TCollection_AsciiString(" Private memory: ") + Standard_Integer (ValueMiB (MemPrivate)) + " MiB\n"; } - if (myCounters[MemWorkingSet] != Standard_Size(-1)) + if (hasValue (MemWorkingSet)) { anInfo += TCollection_AsciiString(" Working Set: ") + Standard_Integer (ValueMiB (MemWorkingSet)) + " MiB"; - if (myCounters[MemWorkingSetPeak] != Standard_Size(-1)) + if (hasValue (MemWorkingSetPeak)) { anInfo += TCollection_AsciiString(" (peak: ") + Standard_Integer (ValueMiB (MemWorkingSetPeak)) + " MiB)"; } anInfo += "\n"; } - if (myCounters[MemSwapUsage] != Standard_Size(-1)) + if (hasValue (MemSwapUsage)) { anInfo += TCollection_AsciiString(" Pagefile usage: ") + Standard_Integer (ValueMiB (MemSwapUsage)) + " MiB"; - if (myCounters[MemSwapUsagePeak] != Standard_Size(-1)) + if (hasValue (MemSwapUsagePeak)) { anInfo += TCollection_AsciiString(" (peak: ") + Standard_Integer (ValueMiB (MemSwapUsagePeak)) + " MiB)"; } anInfo += "\n"; } - if (myCounters[MemVirtual] != Standard_Size(-1)) + if (hasValue (MemVirtual)) { anInfo += TCollection_AsciiString(" Virtual memory: ") + Standard_Integer (ValueMiB (MemVirtual)) + " MiB\n"; } - if (myCounters[MemHeapUsage] != Standard_Size(-1)) + if (hasValue (MemHeapUsage)) { anInfo += TCollection_AsciiString(" Heap memory: ") + Standard_Integer (ValueMiB (MemHeapUsage)) + " MiB\n"; } @@ -232,7 +289,7 @@ TCollection_AsciiString OSD_MemInfo::ToString() const // ======================================================================= Standard_Size OSD_MemInfo::Value (const OSD_MemInfo::Counter theCounter) const { - if (theCounter < 0 || theCounter >= MemCounter_NB) + if (theCounter < 0 || theCounter >= MemCounter_NB || !IsActive (theCounter)) { return Standard_Size(-1); } @@ -245,7 +302,7 @@ Standard_Size OSD_MemInfo::Value (const OSD_MemInfo::Counter theCounter) const // ======================================================================= Standard_Size OSD_MemInfo::ValueMiB (const OSD_MemInfo::Counter theCounter) const { - if (theCounter < 0 || theCounter >= MemCounter_NB) + if (theCounter < 0 || theCounter >= MemCounter_NB || !IsActive (theCounter)) { return Standard_Size(-1); } @@ -259,7 +316,7 @@ Standard_Size OSD_MemInfo::ValueMiB (const OSD_MemInfo::Counter theCounter) cons // ======================================================================= Standard_Real OSD_MemInfo::ValuePreciseMiB (const OSD_MemInfo::Counter theCounter) const { - if (theCounter < 0 || theCounter >= MemCounter_NB) + if (theCounter < 0 || theCounter >= MemCounter_NB || !IsActive (theCounter)) { return -1.0; } diff --git a/src/OSD/OSD_MemInfo.hxx b/src/OSD/OSD_MemInfo.hxx index f06d5d05a1..0e59c57d9c 100644 --- a/src/OSD/OSD_MemInfo.hxx +++ b/src/OSD/OSD_MemInfo.hxx @@ -16,6 +16,7 @@ #ifndef _OSD_MemInfo_H__ #define _OSD_MemInfo_H__ +#include #include //! This class provide information about memory utilized by current process. @@ -65,9 +66,21 @@ public: public: - //! Create and initialize + //! Create and initialize. By default all countes are active Standard_EXPORT OSD_MemInfo (const Standard_Boolean theImmediateUpdate = Standard_True); + //! Return true if the counter is active + Standard_Boolean IsActive (const OSD_MemInfo::Counter theCounter) const { return myActiveCounters[theCounter]; } + + //! Set all counters active. The information is collected for active counters. + //! @param theActive state for counters + Standard_EXPORT void SetActive (const Standard_Boolean theActive); + + //! Set the counter active. The information is collected for active counters. + //! @param theCounter type of counter + //! @param theActive state for the counter + void SetActive (const OSD_MemInfo::Counter theCounter, const Standard_Boolean theActive) { myActiveCounters[theCounter] = theActive; } + //! Clear counters Standard_EXPORT void Clear(); @@ -97,9 +110,16 @@ public: //! Return the string representation for all available counter. Standard_EXPORT static TCollection_AsciiString PrintInfo(); +protected: + + //! Return true if the counter is active and the value is valid + Standard_Boolean hasValue (const OSD_MemInfo::Counter theCounter) const + { return IsActive (theCounter) && myCounters[theCounter] != Standard_Size(-1); } + private: Standard_Size myCounters[MemCounter_NB]; //!< Counters' values, in bytes + Standard_Boolean myActiveCounters[MemCounter_NB]; //!< container of active state for a counter }; -- 2.39.5