Răsfoiți Sursa

Erste Implementation Speichernutzung.

Rind 5 ani în urmă
părinte
comite
498bed7a1a
14 a modificat fișierele cu 693 adăugiri și 156 ștergeri
  1. 100 100
      Test/Test.pro.user
  2. 47 23
      Test/main.cpp
  3. 83 8
      Test/qmlApp/main.qml
  4. 96 2
      Test/qmlApp/qappctrl.cpp
  5. 17 0
      Test/qmlApp/qappctrl.h
  6. 2 14
      Test/qmlApp/qmlApp.pro
  7. 1 1
      Test/test.pri
  8. 6 4
      gfaipc.pro
  9. 2 2
      gfaipc.pro.user
  10. 47 0
      src/appctrl.cpp
  11. 8 2
      src/appctrl.h
  12. 10 0
      src/gfaipc.h
  13. 157 0
      src/procmem.cpp
  14. 117 0
      src/procmem.h

+ 100 - 100
Test/Test.pro.user

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 4.11.1, 2020-02-20T12:20:53. -->
+<!-- Written by QtCreator 4.11.1, 2020-03-03T13:14:43. -->
 <qtcreator>
  <data>
   <variable>EnvironmentId</variable>
@@ -68,14 +68,14 @@
  <data>
   <variable>ProjectExplorer.Project.Target.0</variable>
   <valuemap type="QVariantMap">
-   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.7.1 GCC 64bit</value>
-   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.7.1 GCC 64bit</value>
-   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.57.gcc_64_kit</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Sitara 1</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Sitara 1</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{b0a415a1-ecbe-4123-8afc-05ffc0004131}</value>
    <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
    <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
    <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">3</value>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
-    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/wrk/share/gfaipc/Test/Debug/Desktop_Qt_5_7_1_GCC_64bit</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/wrk/share/gfaipc/Test/Debug/Sitara_1</value>
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
       <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
@@ -123,7 +123,7 @@
     <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
    </valuemap>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
-    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/wrk/share/gfaipc/Test/Release/Desktop_Qt_5_7_1_GCC_64bit</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/wrk/share/gfaipc/Test/Release/Sitara_1</value>
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
       <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
@@ -173,13 +173,47 @@
    <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
-     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.CheckForFreeDiskSpaceStep</value>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
+      <value type="QString" key="RemoteLinux.CheckForFreeDiskSpaceStep.PathToCheck">/</value>
+      <value type="qlonglong" key="RemoteLinux.CheckForFreeDiskSpaceStep.RequiredSpace">5242880</value>
+      <valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
+      <valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.KillAppStep</value>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
+      <valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
+      <valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.2">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.DirectUploadStep</value>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
+      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
+      <value type="bool" key="RemoteLinux.GenericDirectUploadStep.IgnoreMissingFiles">false</value>
+      <value type="bool" key="RemoteLinux.GenericDirectUploadStep.Incremental">false</value>
+      <valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
+      <valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">3</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
     </valuemap>
     <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">DeployToGenericLinux</value>
    </valuemap>
    <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
@@ -241,21 +275,26 @@
      <value type="int">13</value>
      <value type="int">14</value>
     </valuelist>
-    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <value type="int" key="PE.EnvironmentAspect.Base">1</value>
     <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/wrk/share/gfaipc/Test/app1/app1.pro</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">app1 (auf Sitara 1)</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinuxRunConfiguration:/home/wrk/share/gfaipc/Test/app1/app1.pro</value>
     <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/wrk/share/gfaipc/Test/app1/app1.pro</value>
+    <value type="int" key="RemoteLinux.EnvironmentAspect.Version">1</value>
+    <value type="QString" key="RemoteLinux.RunConfig.AlternateRemoteExecutable"></value>
+    <value type="bool" key="RemoteLinux.RunConfig.UseAlternateRemoteExecutable">false</value>
     <value type="QString" key="RunConfiguration.Arguments"></value>
     <value type="bool" key="RunConfiguration.Arguments.multi">false</value>
     <value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
     <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
     <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
-    <value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
     <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
-    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">false</value>
+    <value type="bool" key="RunConfiguration.UseX11Forwarding">false</value>
     <value type="QString" key="RunConfiguration.WorkingDirectory"></value>
-    <value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/wrk/share/gfaipc/Test/Debug/Desktop_Qt_5_7_1_GCC_64bit/app1</value>
+    <value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
+    <value type="QString" key="RunConfiguration.X11Forwarding">:0</value>
    </valuemap>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
     <value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
@@ -315,21 +354,26 @@
      <value type="int">13</value>
      <value type="int">14</value>
     </valuelist>
-    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <value type="int" key="PE.EnvironmentAspect.Base">1</value>
     <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/wrk/share/gfaipc/Test/app2/app2.pro</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">app2 (auf Sitara 1)</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinuxRunConfiguration:/home/wrk/share/gfaipc/Test/app2/app2.pro</value>
     <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/wrk/share/gfaipc/Test/app2/app2.pro</value>
+    <value type="int" key="RemoteLinux.EnvironmentAspect.Version">1</value>
+    <value type="QString" key="RemoteLinux.RunConfig.AlternateRemoteExecutable"></value>
+    <value type="bool" key="RemoteLinux.RunConfig.UseAlternateRemoteExecutable">false</value>
     <value type="QString" key="RunConfiguration.Arguments"></value>
     <value type="bool" key="RunConfiguration.Arguments.multi">false</value>
     <value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
     <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
     <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
-    <value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
     <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseX11Forwarding">false</value>
     <value type="QString" key="RunConfiguration.WorkingDirectory"></value>
-    <value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/wrk/share/gfaipc/Test/Debug/Desktop_Qt_5_7_1_GCC_64bit/app2</value>
+    <value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
+    <value type="QString" key="RunConfiguration.X11Forwarding">:0</value>
    </valuemap>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.2">
     <value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
@@ -389,21 +433,26 @@
      <value type="int">13</value>
      <value type="int">14</value>
     </valuelist>
-    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <value type="int" key="PE.EnvironmentAspect.Base">1</value>
     <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/wrk/share/gfaipc/Test/app3/app3.pro</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">app3 (auf Sitara 1)</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinuxRunConfiguration:/home/wrk/share/gfaipc/Test/app3/app3.pro</value>
     <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/wrk/share/gfaipc/Test/app3/app3.pro</value>
+    <value type="int" key="RemoteLinux.EnvironmentAspect.Version">1</value>
+    <value type="QString" key="RemoteLinux.RunConfig.AlternateRemoteExecutable"></value>
+    <value type="bool" key="RemoteLinux.RunConfig.UseAlternateRemoteExecutable">false</value>
     <value type="QString" key="RunConfiguration.Arguments"></value>
     <value type="bool" key="RunConfiguration.Arguments.multi">false</value>
     <value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
     <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
     <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
-    <value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
     <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseX11Forwarding">false</value>
     <value type="QString" key="RunConfiguration.WorkingDirectory"></value>
-    <value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/wrk/share/gfaipc/Test/Debug/Desktop_Qt_5_7_1_GCC_64bit/app3</value>
+    <value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
+    <value type="QString" key="RunConfiguration.X11Forwarding">:0</value>
    </valuemap>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.3">
     <value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
@@ -463,21 +512,26 @@
      <value type="int">13</value>
      <value type="int">14</value>
     </valuelist>
-    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <value type="int" key="PE.EnvironmentAspect.Base">1</value>
     <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/wrk/share/gfaipc/Test/qmlApp/qmlApp.pro</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">qmlApp (auf Sitara 1)</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinuxRunConfiguration:/home/wrk/share/gfaipc/Test/qmlApp/qmlApp.pro</value>
     <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/wrk/share/gfaipc/Test/qmlApp/qmlApp.pro</value>
+    <value type="int" key="RemoteLinux.EnvironmentAspect.Version">1</value>
+    <value type="QString" key="RemoteLinux.RunConfig.AlternateRemoteExecutable"></value>
+    <value type="bool" key="RemoteLinux.RunConfig.UseAlternateRemoteExecutable">false</value>
     <value type="QString" key="RunConfiguration.Arguments"></value>
     <value type="bool" key="RunConfiguration.Arguments.multi">false</value>
     <value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
     <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
     <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
-    <value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
     <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseX11Forwarding">false</value>
     <value type="QString" key="RunConfiguration.WorkingDirectory"></value>
-    <value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/wrk/share/gfaipc/Test/Debug/Desktop_Qt_5_7_1_GCC_64bit/qmlApp</value>
+    <value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
+    <value type="QString" key="RunConfiguration.X11Forwarding">:0</value>
    </valuemap>
    <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">4</value>
   </valuemap>
@@ -485,14 +539,14 @@
  <data>
   <variable>ProjectExplorer.Project.Target.1</variable>
   <valuemap type="QVariantMap">
-   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Sitara 1</value>
-   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Sitara 1</value>
-   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{b0a415a1-ecbe-4123-8afc-05ffc0004131}</value>
-   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.7.1 GCC 64bit</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.7.1 GCC 64bit</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.57.gcc_64_kit</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
    <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
    <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">3</value>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
-    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/wrk/share/gfaipc/Test/Debug/Sitara_1</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/wrk/share/gfaipc/Test/Debug/Desktop_Qt_5_7_1_GCC_64bit</value>
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
       <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
@@ -540,7 +594,7 @@
     <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
    </valuemap>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
-    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/wrk/share/gfaipc/Test/Release/Sitara_1</value>
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/wrk/share/gfaipc/Test/Release/Desktop_Qt_5_7_1_GCC_64bit</value>
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
       <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
@@ -590,47 +644,13 @@
    <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
-     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
-      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
-      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.CheckForFreeDiskSpaceStep</value>
-      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
-      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
-      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
-      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
-      <value type="QString" key="RemoteLinux.CheckForFreeDiskSpaceStep.PathToCheck">/</value>
-      <value type="qlonglong" key="RemoteLinux.CheckForFreeDiskSpaceStep.RequiredSpace">5242880</value>
-      <valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
-      <valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
-     </valuemap>
-     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
-      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
-      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.KillAppStep</value>
-      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
-      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
-      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
-      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
-      <valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
-      <valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
-     </valuemap>
-     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.2">
-      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
-      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.DirectUploadStep</value>
-      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
-      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
-      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
-      <valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
-      <value type="bool" key="RemoteLinux.GenericDirectUploadStep.IgnoreMissingFiles">false</value>
-      <value type="bool" key="RemoteLinux.GenericDirectUploadStep.Incremental">false</value>
-      <valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
-      <valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
-     </valuemap>
-     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">3</value>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
     </valuemap>
     <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">DeployToGenericLinux</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
    </valuemap>
    <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
@@ -692,26 +712,21 @@
      <value type="int">13</value>
      <value type="int">14</value>
     </valuelist>
-    <value type="int" key="PE.EnvironmentAspect.Base">1</value>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
     <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">app1 (auf Sitara 1)</value>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinuxRunConfiguration:/home/wrk/share/gfaipc/Test/app1/app1.pro</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/wrk/share/gfaipc/Test/app1/app1.pro</value>
     <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/wrk/share/gfaipc/Test/app1/app1.pro</value>
-    <value type="int" key="RemoteLinux.EnvironmentAspect.Version">1</value>
-    <value type="QString" key="RemoteLinux.RunConfig.AlternateRemoteExecutable"></value>
-    <value type="bool" key="RemoteLinux.RunConfig.UseAlternateRemoteExecutable">false</value>
     <value type="QString" key="RunConfiguration.Arguments"></value>
     <value type="bool" key="RunConfiguration.Arguments.multi">false</value>
     <value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
     <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
     <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
     <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
-    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">false</value>
-    <value type="bool" key="RunConfiguration.UseX11Forwarding">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
     <value type="QString" key="RunConfiguration.WorkingDirectory"></value>
     <value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
-    <value type="QString" key="RunConfiguration.X11Forwarding">:0</value>
    </valuemap>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
     <value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
@@ -771,26 +786,21 @@
      <value type="int">13</value>
      <value type="int">14</value>
     </valuelist>
-    <value type="int" key="PE.EnvironmentAspect.Base">1</value>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
     <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">app2 (auf Sitara 1)</value>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinuxRunConfiguration:/home/wrk/share/gfaipc/Test/app2/app2.pro</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/wrk/share/gfaipc/Test/app2/app2.pro</value>
     <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/wrk/share/gfaipc/Test/app2/app2.pro</value>
-    <value type="int" key="RemoteLinux.EnvironmentAspect.Version">1</value>
-    <value type="QString" key="RemoteLinux.RunConfig.AlternateRemoteExecutable"></value>
-    <value type="bool" key="RemoteLinux.RunConfig.UseAlternateRemoteExecutable">false</value>
     <value type="QString" key="RunConfiguration.Arguments"></value>
     <value type="bool" key="RunConfiguration.Arguments.multi">false</value>
     <value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
     <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
     <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
     <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
-    <value type="bool" key="RunConfiguration.UseX11Forwarding">false</value>
     <value type="QString" key="RunConfiguration.WorkingDirectory"></value>
     <value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
-    <value type="QString" key="RunConfiguration.X11Forwarding">:0</value>
    </valuemap>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.2">
     <value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
@@ -850,26 +860,21 @@
      <value type="int">13</value>
      <value type="int">14</value>
     </valuelist>
-    <value type="int" key="PE.EnvironmentAspect.Base">1</value>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
     <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">app3 (auf Sitara 1)</value>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinuxRunConfiguration:/home/wrk/share/gfaipc/Test/app3/app3.pro</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/wrk/share/gfaipc/Test/app3/app3.pro</value>
     <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/wrk/share/gfaipc/Test/app3/app3.pro</value>
-    <value type="int" key="RemoteLinux.EnvironmentAspect.Version">1</value>
-    <value type="QString" key="RemoteLinux.RunConfig.AlternateRemoteExecutable"></value>
-    <value type="bool" key="RemoteLinux.RunConfig.UseAlternateRemoteExecutable">false</value>
     <value type="QString" key="RunConfiguration.Arguments"></value>
     <value type="bool" key="RunConfiguration.Arguments.multi">false</value>
     <value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
     <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
     <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
     <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
-    <value type="bool" key="RunConfiguration.UseX11Forwarding">false</value>
     <value type="QString" key="RunConfiguration.WorkingDirectory"></value>
     <value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
-    <value type="QString" key="RunConfiguration.X11Forwarding">:0</value>
    </valuemap>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.3">
     <value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
@@ -929,26 +934,21 @@
      <value type="int">13</value>
      <value type="int">14</value>
     </valuelist>
-    <value type="int" key="PE.EnvironmentAspect.Base">1</value>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
     <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">qmlApp (auf Sitara 1)</value>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinuxRunConfiguration:/home/wrk/share/gfaipc/Test/qmlApp/qmlApp.pro</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/wrk/share/gfaipc/Test/qmlApp/qmlApp.pro</value>
     <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/wrk/share/gfaipc/Test/qmlApp/qmlApp.pro</value>
-    <value type="int" key="RemoteLinux.EnvironmentAspect.Version">1</value>
-    <value type="QString" key="RemoteLinux.RunConfig.AlternateRemoteExecutable"></value>
-    <value type="bool" key="RemoteLinux.RunConfig.UseAlternateRemoteExecutable">false</value>
     <value type="QString" key="RunConfiguration.Arguments"></value>
     <value type="bool" key="RunConfiguration.Arguments.multi">false</value>
     <value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
     <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
     <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
     <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
-    <value type="bool" key="RunConfiguration.UseX11Forwarding">false</value>
     <value type="QString" key="RunConfiguration.WorkingDirectory"></value>
     <value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
-    <value type="QString" key="RunConfiguration.X11Forwarding">:0</value>
    </valuemap>
    <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">4</value>
   </valuemap>

+ 47 - 23
Test/main.cpp

@@ -3,6 +3,7 @@
 #include <string.h>
 #include <signal.h>
 #include <poll.h>
+#include <vector>
 #include <gfa/gfasitarautils.h>
 #include <gfa/gfaipc.h>
 #include "../src/defines.h"
@@ -14,8 +15,12 @@
 #define _APPNAME_REMANENT		"Remanent"
 #define _APPNAME_REST			"REST"
 
-#define _CTRL_MSG_DELAY			8
-#define _HANG_DELAY				10
+#define _CTRL_MSG_HANG			0x08
+#define _CTRL_MSG_ALLOC			0x10
+#define _CTRL_MSG_FREE			0x20
+#define _HANG_LOOPS				1000000000
+#define _NORMAL_LOOPS			100000
+#define _MEM_WASTE_SIZE			524288
 
 /////////////////////////////////////////////////////////////////////////////
 
@@ -24,6 +29,8 @@
 static volatile bool g_fRun		= false;
 static volatile bool g_fPause	= false;
 static volatile bool g_fHang	= false;
+static volatile bool g_fAlloc	= false;
+static volatile bool g_fFree	= false;
 
 /////////////////////////////////////////////////////////////////////////////
 
@@ -38,6 +45,8 @@ static const char *g_pszStateNames[] =
 	"Invalid"
 };
 
+static std::vector<void*> g_vP;
+
 /////////////////////////////////////////////////////////////////////////////
 
 static void _SigHandler(int sig)
@@ -58,20 +67,6 @@ static int _InputAvailable(void)
 
 /////////////////////////////////////////////////////////////////////////////
 
-static void _DoHang(time_t nSec)
-{
-	time_t t = time(NULL) + nSec;
-
-	do
-	{
-		if(t < time(NULL))
-			break;
-	}
-	while(true);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
 static void _ProcessCtrlMessages(HAPPCTRL hAC, HAPPINFO hAI)
 {
     ctrlmsg_t nCtrlMsg;
@@ -100,10 +95,14 @@ static void _ProcessCtrlMessages(HAPPCTRL hAC, HAPPINFO hAI)
 				TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Running]);
 			}
 			break;
-		case _CTRL_MSG_DELAY:
-			TRACE("Hanging %d seconds.\n", _HANG_DELAY);
+		case _CTRL_MSG_HANG:
 			g_fHang = true;
-			_DoHang(_HANG_DELAY);
+			break;
+		case _CTRL_MSG_ALLOC:
+			g_fAlloc = true;
+			break;
+		case _CTRL_MSG_FREE:
+			g_fFree = true;
 			break;
 		default:
 			break;
@@ -175,9 +174,35 @@ static void _ProcessInput(HAPPCTRL hAC)
 
 static int _DoWork(void)
 {
-	int i, j = 0;
-	int k = g_fHang ? 1000000000 : 100000;
-	
+	int i, j = 0, k = _NORMAL_LOOPS;
+
+    if(g_fAlloc)
+    {
+        TRACE("Wasting %d KiB of memory.\n", _MEM_WASTE_SIZE >> 10);
+        void *p = malloc(_MEM_WASTE_SIZE);
+        g_vP.push_back(p);
+        g_fAlloc = false;
+        UNUSED(p);
+    }
+
+	if(g_fFree)
+	{
+        TRACE("Freeing memory.\n");
+		for(auto i = g_vP.begin(); i != g_vP.end(); i++)
+		{
+			free(*i);
+		}
+		g_vP.clear();
+		g_fFree = false;
+	}
+
+	if(g_fHang)
+	{
+        k = _HANG_LOOPS;
+        TRACE("Performing %d nonsense loops.\n", k);
+        g_fHang = false;
+    }
+
 	for(i = 0; i < k; ++i)
 	{
 		j += 4;
@@ -186,7 +211,6 @@ static int _DoWork(void)
 		j -= 3;
 	}
 
-	g_fHang = false;
 	return j;
 }
 

+ 83 - 8
Test/qmlApp/main.qml

@@ -5,7 +5,7 @@ import com.gfa.ipc.appctrl 1.0
 
 Window {
     visible: true
-    width: 640
+    width: 800
     height: 480
     title: qsTr("GfA App Control")
     
@@ -147,7 +147,7 @@ Window {
 		        font.italic: true
 				anchors.verticalCenter: parent.verticalCenter
 	            anchors.left: parent.left
-		        text: "Uptime H:M:S:"
+		        text: "VM RSS KiB:"
 		    }
 		}
 
@@ -161,7 +161,7 @@ Window {
 		        font.italic: true
 				anchors.verticalCenter: parent.verticalCenter
 	            anchors.left: parent.left
-		        text: "</Ø pass μs"
+		        text: "VM Size KiB:"
 		    }
 		}
 
@@ -349,7 +349,22 @@ Window {
 		    Text {
 		        font.pixelSize: 14
 	            anchors.centerIn: parent
-		        text: sec2HMS(parent.parent.appInfo.upTime)
+		        text: parent.parent.appInfo.vmRSS
+		    }
+		}
+
+		Rectangle {
+	        x: 0
+	        y: 280
+	        width: parent.width
+	        height: 30
+	        border.width: 1
+			border.color: "lightgrey"
+	        radius: 5
+		    Text {
+		        font.pixelSize: 14
+	            anchors.centerIn: parent
+		        text: parent.parent.appInfo.vmSize
 		    }
 		}
 
@@ -534,7 +549,22 @@ Window {
 		    Text {
 		        font.pixelSize: 14
 	            anchors.centerIn: parent
-		        text: sec2HMS(parent.parent.appInfo.upTime)
+		        text: parent.parent.appInfo.vmRSS
+		    }
+		}
+
+		Rectangle {
+	        x: 0
+	        y: 280
+	        width: parent.width
+	        height: 30
+	        border.width: 1
+			border.color: "lightgrey"
+	        radius: 5
+		    Text {
+		        font.pixelSize: 14
+	            anchors.centerIn: parent
+		        text: parent.parent.appInfo.vmSize
 		    }
 		}
 
@@ -719,7 +749,22 @@ Window {
 		    Text {
 		        font.pixelSize: 14
 	            anchors.centerIn: parent
-		        text: sec2HMS(parent.parent.appInfo.upTime)
+		        text: parent.parent.appInfo.vmRSS
+		    }
+		}
+
+		Rectangle {
+	        x: 0
+	        y: 280
+	        width: parent.width
+	        height: 30
+	        border.width: 1
+			border.color: "lightgrey"
+	        radius: 5
+		    Text {
+		        font.pixelSize: 14
+	            anchors.centerIn: parent
+		        text: parent.parent.appInfo.vmSize
 		    }
 		}
 
@@ -904,7 +949,22 @@ Window {
 		    Text {
 		        font.pixelSize: 14
 	            anchors.centerIn: parent
-		        text: sec2HMS(parent.parent.appInfo.upTime)
+		        text: parent.parent.appInfo.vmRSS
+		    }
+		}
+
+		Rectangle {
+	        x: 0
+	        y: 280
+	        width: parent.width
+	        height: 30
+	        border.width: 1
+			border.color: "lightgrey"
+	        radius: 5
+		    Text {
+		        font.pixelSize: 14
+	            anchors.centerIn: parent
+		        text: parent.parent.appInfo.vmSize
 		    }
 		}
 
@@ -1089,7 +1149,22 @@ Window {
 		    Text {
 		        font.pixelSize: 14
 	            anchors.centerIn: parent
-		        text: sec2HMS(parent.parent.appInfo.upTime)
+		        text: parent.parent.appInfo.vmRSS
+		    }
+		}
+
+		Rectangle {
+	        x: 0
+	        y: 280
+	        width: parent.width
+	        height: 30
+	        border.width: 1
+			border.color: "lightgrey"
+	        radius: 5
+		    Text {
+		        font.pixelSize: 14
+	            anchors.centerIn: parent
+		        text: parent.parent.appInfo.vmSize
 		    }
 		}
 

+ 96 - 2
Test/qmlApp/qappctrl.cpp

@@ -30,7 +30,11 @@ QGfaAppInfo::QGfaAppInfo(int nIndex, QObject *pParent) :	QObject(pParent),
 															m_upTime(0),
 															m_cpuTime(0.0),
 															m_cpuPercCur(0.0),
-															m_cpuPercAvg(0.0)
+															m_cpuPercAvg(0.0),
+															m_vmPeak(0),
+															m_vmSize(0),
+															m_vmHWM(0),
+															m_vmRSS(0)
 {
 	m_nAppID = 1ull << m_nIndex;
 	setStateText(m_state);
@@ -153,6 +157,87 @@ double QGfaAppInfo::cpuAvg(void) const
 	return m_cpuPercAvg;
 }
 
+quint32 QGfaAppInfo::vmPeak(void) const
+{
+	return m_vmPeak;
+}
+
+quint32 QGfaAppInfo::vmSize(void) const
+{
+	return m_vmSize;
+}
+
+quint32 QGfaAppInfo::vmHWM(void) const
+{
+	return m_vmHWM;
+}
+
+quint32 QGfaAppInfo::vmRSS(void) const
+{
+	return m_vmRSS;
+}
+
+void QGfaAppInfo::setAppMemInfo(LPCGFA_APPCTRL_APPMEM pam, GfaIpcAppStates state, bool bDoHeavyLoadUpdate)
+{
+	UNUSED(state);
+	
+	if(pam)
+	{
+		if(bDoHeavyLoadUpdate)
+		{
+			if(m_vmPeak != pam->vmPeak)
+			{
+				m_vmPeak = pam->vmPeak;
+				emit vmPeakChanged(m_vmPeak);
+			}
+
+			if(m_vmSize != pam->vmSize)
+			{
+				m_vmSize = pam->vmSize;
+				emit vmSizeChanged(m_vmSize);
+			}
+
+			if(m_vmHWM != pam->vmHWM)
+			{
+				m_vmHWM = pam->vmHWM;
+				emit vmHWMChanged(m_vmHWM);
+			}
+
+			if(m_vmRSS != pam->vmRSS)
+			{
+				m_vmRSS = pam->vmRSS;
+				emit vmRSSChanged(m_vmRSS);
+			}
+		}
+	}
+	else if(state != GIAS_Hanging)
+	{
+		if(m_vmPeak != 0)
+		{
+			m_vmPeak = 0;
+			emit vmPeakChanged(m_vmPeak);
+		}
+
+		if(m_vmSize != 0)
+		{
+			m_vmSize = 0;
+			emit vmSizeChanged(m_vmSize);
+		}
+
+		if(m_vmHWM != 0)
+		{
+			m_vmHWM = 0;
+			emit vmHWMChanged(m_vmHWM);
+		}
+
+		if(m_vmRSS != 0)
+		{
+			m_vmRSS = 0;
+			emit vmRSSChanged(m_vmRSS);
+		}
+	}
+}
+
 void QGfaAppInfo::setAppTimes(LPCGFA_APPCTRL_APPTIMES pat, GfaIpcAppStates state, bool bDoHeavyLoadUpdate)
 {
 	if(pat)
@@ -481,6 +566,7 @@ void QGfaAppCtrl::timerEvent(QTimerEvent *event)
 			int b;
 		    appid_t app, nAppIdSrc;
 			GFA_APPCTRL_APPTIMES at;
+			GFA_APPCTRL_APPMEM am;
 			char szDispName[128];
 #if 0
 		    ctrlmsg_t nCtrlMsg;
@@ -513,7 +599,10 @@ void QGfaAppCtrl::timerEvent(QTimerEvent *event)
 					if(state == GIAS_Running)
 						memset(&m_tsLastHeavyLoadUpdate, 0, sizeof(m_tsLastHeavyLoadUpdate));
 					else if(state != GIAS_Paused)
+					{
 						ai.setAppTimes(NULL, state);
+						ai.setAppMemInfo(NULL, state);
+					}
 				}
 
 				if((state >= GIAS_StateNotRunning) && (state <= GIAS_Paused))
@@ -533,8 +622,14 @@ void QGfaAppCtrl::timerEvent(QTimerEvent *event)
 				b = ffsll(nAppIdSrc) - 1;
 				app = ((appid_t)0x1 << b);
 				nAppIdSrc &= ~app;
+				QGfaAppInfo &ai = *m_appInfo[b];
 				GfaIpcAppStates state = ::GfaIpcAppCtrlGetState(m_hAC, app);
 
+				if(::GfaIpcAppCtrlGetAppMem(m_hAC, app, &am))
+				{
+					ai.setAppMemInfo(&am, state, bUpdate);
+				}
+
 				if(::GfaIpcAppCtrlGetAppTimes(m_hAC, app, &at) >= 0)
 				{
 					if(!at.nCycleLastUs)
@@ -543,7 +638,6 @@ void QGfaAppCtrl::timerEvent(QTimerEvent *event)
 						continue;
 					}
 
-					QGfaAppInfo &ai = *m_appInfo[b];
 					ai.setAppTimes(&at, state, bUpdate);
 				}
 			}

+ 17 - 0
Test/qmlApp/qappctrl.h

@@ -31,6 +31,10 @@ class QGfaAppInfo : public QObject
 	Q_PROPERTY(double cpuTime READ cpuTime NOTIFY cpuTimeChanged)
 	Q_PROPERTY(double cpuCur READ cpuCur NOTIFY cpuCurChanged)
 	Q_PROPERTY(double cpuAvg READ cpuAvg NOTIFY cpuAvgChanged)
+	Q_PROPERTY(quint32 vmPeak READ vmPeak NOTIFY vmPeakChanged)
+	Q_PROPERTY(quint32 vmSize READ vmSize NOTIFY vmSizeChanged)
+	Q_PROPERTY(quint32 vmHWM READ vmHWM NOTIFY vmHWMChanged)
+	Q_PROPERTY(quint32 vmRSS READ vmRSS NOTIFY vmRSSChanged)
 
 public:
 	Q_INVOKABLE bool pause(void);
@@ -53,6 +57,10 @@ signals:
 	void cpuTimeChanged(double val);
 	void cpuCurChanged(double val);
 	void cpuAvgChanged(double val);
+	void vmPeakChanged(quint32 val);
+	void vmSizeChanged(quint32 val);
+	void vmHWMChanged(quint32 val);
+	void vmRSSChanged(quint32 val);
 
 public:
 	explicit QGfaAppInfo(int nIndex, QObject *pParent = NULL);
@@ -78,8 +86,13 @@ public:
 	double cpuTime(void) const;
 	double cpuCur(void) const;
 	double cpuAvg(void) const;
+	quint32 vmPeak(void) const;
+	quint32 vmSize(void) const;
+	quint32 vmHWM(void) const;
+	quint32 vmRSS(void) const;
 
 	void setAppTimes(LPCGFA_APPCTRL_APPTIMES pat, GfaIpcAppStates state, bool bDoHeavyLoadUpdate = false);
+	void setAppMemInfo(LPCGFA_APPCTRL_APPMEM pam, GfaIpcAppStates state, bool bDoHeavyLoadUpdate = false);
 
 private:
 
@@ -100,6 +113,10 @@ private:
 	double m_cpuTime;
 	double m_cpuPercCur;
 	double m_cpuPercAvg;
+	quint32 m_vmPeak;
+	quint32 m_vmSize;
+	quint32 m_vmHWM;
+	quint32 m_vmRSS;
 };
 
 /////////////////////////////////////////////////////////////////////////////

+ 2 - 14
Test/qmlApp/qmlApp.pro

@@ -2,28 +2,16 @@ QT += quick
 
 CONFIG += c++11
 
-# The following define makes your compiler emit warnings if you use
-# any Qt feature that has been marked deprecated (the exact warnings
-# depend on your compiler). Refer to the documentation for the
-# deprecated API to know how to port your code away from it.
 DEFINES += QT_DEPRECATED_WARNINGS
 
-# You can also make your code fail to compile if it uses deprecated APIs.
-# In order to do so, uncomment the following line.
-# You can also select to disable deprecated APIs only up to a certain version of Qt.
-#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
-
 SOURCES += \
         main.cpp \
         qappctrl.cpp
 
 RESOURCES += qml.qrc
 
-# Additional import path used to resolve QML modules in Qt Creator's code model
-QML_IMPORT_PATH =
-
-# Additional import path used to resolve QML modules just for Qt Quick Designer
-QML_DESIGNER_IMPORT_PATH =
+QMAKE_LIBDIR += $$[QT_SYSROOT]/usr/lib/gfa
+QMAKE_RPATHDIR += /usr/lib/gfa
 
 CONFIG(debug, debug|release) {
     QMAKE_CXXFLAGS -= -Os -pthread

+ 1 - 1
Test/test.pri

@@ -3,8 +3,8 @@ CONFIG += console
 CONFIG -= app_bundle
 CONFIG -= qt
 
-QMAKE_LFLAGS += -Wl,-rpath=/usr/lib/gfa
 QMAKE_LIBDIR += $$[QT_SYSROOT]/usr/lib/gfa
+QMAKE_RPATHDIR += /usr/lib/gfa
 
 CONFIG(debug, debug|release) {
     QMAKE_CXXFLAGS -= -Os

+ 6 - 4
gfaipc.pro

@@ -10,6 +10,7 @@ SOURCES += \
     src/ipcshm.cpp \
     src/locmtx.cpp \
     src/mutex.cpp \
+    src/procmem.cpp \
     src/sema.cpp \
     src/shm.cpp \
     src/shmrot.cpp \
@@ -20,6 +21,7 @@ HEADERS += \
     src/defines.h \
     src/gfaipc.h \
     src/mutex.h \
+    src/procmem.h \
     src/sema.h \
     src/shm.h \
     src/shmrot.h \
@@ -56,13 +58,13 @@ linux-g++ {
 	includes.extra += $$escape_expand(\\n\\t)-$(INSTALL_FILE) $$PWD/src/mutex.h $(INSTALL_ROOT)$$includes.path
 	includes.extra += $$escape_expand(\\n\\t)-$(INSTALL_FILE) $$PWD/src/sema.h $(INSTALL_ROOT)$$includes.path
 	includes.extra += $$escape_expand(\\n\\t)-$(INSTALL_FILE) $$PWD/src/shm.h $(INSTALL_ROOT)$$includes.path
-	includes.extra += $$escape_expand(\\n\\t)-$(INSTALL_FILE) $$PWD/src/shmrot.h $(INSTALL_ROOT)$$includes.path
+	includes.extra += $$escape_expand(\\n\\t)-$(INSTALL_FILE) $$PWD/src/procmem.h $(INSTALL_ROOT)$$includes.path
 	includes.extra += $$escape_expand(\\n\\t)-$(INSTALL_FILE) $$PWD/src/uuid.h $(INSTALL_ROOT)$$includes.path
 	includes.uninstall += -$(DEL_FILE) $(INSTALL_ROOT)$$includes.path/gfaipc.h
 	includes.uninstall += $$escape_expand(\\n\\t)-$(DEL_FILE) $(INSTALL_ROOT)$$includes.path/mutex.h
 	includes.uninstall += $$escape_expand(\\n\\t)-$(DEL_FILE) $(INSTALL_ROOT)$$includes.path/sema.h
 	includes.uninstall += $$escape_expand(\\n\\t)-$(DEL_FILE) $(INSTALL_ROOT)$$includes.path/shm.h
-	includes.uninstall += $$escape_expand(\\n\\t)-$(DEL_FILE) $(INSTALL_ROOT)$$includes.path/shmrot.h
+	includes.uninstall += $$escape_expand(\\n\\t)-$(DEL_FILE) $(INSTALL_ROOT)$$includes.path/procmem.h
 	includes.uninstall += $$escape_expand(\\n\\t)-$(DEL_FILE) $(INSTALL_ROOT)$$includes.path/uuid.h
 	INSTALLS += includes
 }
@@ -87,13 +89,13 @@ linux-buildroot-g++ {
 		includes.extra += $$escape_expand(\\n\\t)-$(INSTALL_FILE) $$PWD/src/mutex.h $(INSTALL_ROOT)$$includes.path
 		includes.extra += $$escape_expand(\\n\\t)-$(INSTALL_FILE) $$PWD/src/sema.h $(INSTALL_ROOT)$$includes.path
 		includes.extra += $$escape_expand(\\n\\t)-$(INSTALL_FILE) $$PWD/src/shm.h $(INSTALL_ROOT)$$includes.path
-		includes.extra += $$escape_expand(\\n\\t)-$(INSTALL_FILE) $$PWD/src/shmrot.h $(INSTALL_ROOT)$$includes.path
+		includes.extra += $$escape_expand(\\n\\t)-$(INSTALL_FILE) $$PWD/src/procmem.h $(INSTALL_ROOT)$$includes.path
 		includes.extra += $$escape_expand(\\n\\t)-$(INSTALL_FILE) $$PWD/src/uuid.h $(INSTALL_ROOT)$$includes.path
 		includes.uninstall += -$(DEL_FILE) $(INSTALL_ROOT)$$includes.path/gfaipc.h
 		includes.uninstall += $$escape_expand(\\n\\t)-$(DEL_FILE) $(INSTALL_ROOT)$$includes.path/mutex.h
 		includes.uninstall += $$escape_expand(\\n\\t)-$(DEL_FILE) $(INSTALL_ROOT)$$includes.path/sema.h
 		includes.uninstall += $$escape_expand(\\n\\t)-$(DEL_FILE) $(INSTALL_ROOT)$$includes.path/shm.h
-		includes.uninstall += $$escape_expand(\\n\\t)-$(DEL_FILE) $(INSTALL_ROOT)$$includes.path/shmrot.h
+		includes.uninstall += $$escape_expand(\\n\\t)-$(DEL_FILE) $(INSTALL_ROOT)$$includes.path/procmem.h
 		includes.uninstall += $$escape_expand(\\n\\t)-$(DEL_FILE) $(INSTALL_ROOT)$$includes.path/uuid.h
 		INSTALLS += includes
 

+ 2 - 2
gfaipc.pro.user

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 4.11.1, 2020-02-25T09:36:25. -->
+<!-- Written by QtCreator 4.11.1, 2020-03-03T13:14:43. -->
 <qtcreator>
  <data>
   <variable>EnvironmentId</variable>
@@ -378,7 +378,7 @@
    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.7.1 GCC 64bit</value>
    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.7.1 GCC 64bit</value>
    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.57.gcc_64_kit</value>
-   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
    <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
    <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">

+ 47 - 0
src/appctrl.cpp

@@ -132,6 +132,8 @@ bool CAppCtrl::Create(appid_t nAppID, const char *pszDisplayName, clock64_t nCyc
 
 	if(!CAppCtrl::GetAppPath(szAppPath, sizeof(szAppPath), m_pid))
 		return false;
+	
+	m_procMem.Update();
 
 	if((m_hShm = ::GfaIpcAcquireSHM(_UUID_SHM_APP_CTRL, sizeof(APP_CTRL), 1, _NAME_SHM_APP_CTRL)))
 	{
@@ -282,6 +284,19 @@ LPAPP_CTRL_INFO CAppCtrl::AppInfoUpdate(clock64_t nCurWorkingTime)
 			}
 
 			m_nLastTimesCallUs = proc.nHeartbeatCurUs;
+			m_procMem.Update();
+
+			const VM_VALUE &rVmPeak = m_procMem.VmPeak();
+			proc.am.vmPeak = rVmPeak.valid ? rVmPeak.cb : 0;
+
+			const VM_VALUE &rVmSize = m_procMem.VmSize();
+			proc.am.vmSize = rVmSize.valid ? rVmSize.cb : 0;
+
+			const VM_VALUE &rVmHWM = m_procMem.VmHWM();
+			proc.am.vmHWM = rVmHWM.valid ? rVmHWM.cb : 0;
+
+			const VM_VALUE &rVmRSS = m_procMem.VmRSS();
+			proc.am.vmRSS = rVmRSS.valid ? rVmRSS.cb : 0;
 		}
 
 		if((proc.state == GIAS_Running))
@@ -630,6 +645,28 @@ clock64_t CAppCtrl::GetAppTimes(appid_t nAppID, LPGFA_APPCTRL_APPTIMES pat)
 
 /////////////////////////////////////////////////////////////////////////////
 
+bool CAppCtrl::GetAppMem(appid_t nAppID, LPGFA_APPCTRL_APPMEM pam)
+{
+	if(m_hShm && _IS_VALID_APP_ID(nAppID))
+	{
+		int nIndex = SlotIndexFromAppID(nAppID);
+		const APP_CTRL_PROCESS &proc = m_pAppCtrl->proc[nIndex];
+		CAppCtrlShmLocker locker(*this);
+		if(proc.nAppID == nAppID)
+		{
+			if(pam)
+			{
+				memcpy(pam, &proc.am, sizeof(GFA_APPCTRL_APPMEM));
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
 int CAppCtrl::SlotIndexFromAppID(appid_t nAppID)
 {
 	if(nAppID == 0)
@@ -836,6 +873,16 @@ clock64_t GfaIpcAppCtrlGetAppTimes(HAPPCTRL hAC, appid_t nAppID, LPGFA_APPCTRL_A
 	return -1;
 }
 
+/////////////////////////////////////////////////////////////////////////////
+
+bool GfaIpcAppCtrlGetAppMem(HAPPCTRL hAC, appid_t nAppID, LPGFA_APPCTRL_APPMEM pam)
+{
+	CAppCtrl *p = reinterpret_cast<CAppCtrl*>(hAC);
+	if(p)
+		return p->GetAppMem(nAppID, pam);
+	return false;
+}
+
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////

+ 8 - 2
src/appctrl.h

@@ -8,6 +8,7 @@
 #include <time.h>
 #include <sys/times.h>
 #include "gfaipc.h"
+#include "procmem.h"
 
 /////////////////////////////////////////////////////////////////////////////
 #ifdef __cplusplus
@@ -19,7 +20,7 @@
 
 #define _APP_CTRL_MAX_SLOTS								((int)(sizeof(appid_t) * 8))
 
-#define _UUID_SHM_APP_CTRL_V1							"c3316f45-bcd6-424f-83bd-7d37ef9c3c6f"
+#define _UUID_SHM_APP_CTRL_V1							"c3316f45-bcd6-424f-83bd-7d37ef9c3c6e"
 #define _NAME_SHM_APP_CTRL_V1							"GfA IPC Application Control SHM v1"
 
 #define _UUID_SHM_APP_CTRL								_UUID_SHM_APP_CTRL_V1
@@ -31,7 +32,8 @@ typedef struct _APP_CTRL_INFO
 {
 	appid_t			nStateEvtPending;
 	ctrlmsg_t		nCtrlMsgPending;
-	GFA_APPCTRL_APPTIMES at;
+//	GFA_APPCTRL_APPTIMES at;
+//	GFA_APPCTRL_APPMEM am;
 }APP_CTRL_INFO, *LPAPP_CTRL_INFO;
 typedef const APP_CTRL_INFO *LPCAPP_CTRL_INFO;
 
@@ -47,6 +49,8 @@ typedef const APP_CTRL_SYSTEM *LPCAPP_CTRL_SYSTEM;
 
 typedef struct _APP_CTRL_PROCESS : public APP_CTRL_INFO
 {
+	GFA_APPCTRL_APPTIMES at;
+	GFA_APPCTRL_APPMEM am;
 	clock64_t		nHeartbeatCurUs;
 	clock64_t		nHeartbeatLastUs;
 	appid_t			nAppID;
@@ -114,6 +118,7 @@ public:
 	ctrlmsg_t GetPendingCtrlMsg(void);
 	
 	clock64_t GetAppTimes(appid_t nAppID, LPGFA_APPCTRL_APPTIMES pat);
+	bool GetAppMem(appid_t nAppID, LPGFA_APPCTRL_APPMEM pam);
 
 private:
 	int SlotIndexFromAppID(appid_t nAppID);
@@ -134,6 +139,7 @@ private:
 	clock64_t m_nClkTicksPerSec;
 	clock64_t m_nClockStartUs;
 	clock64_t m_nLastTimesCallUs;
+	CProcMem m_procMem;
 };
 
 /////////////////////////////////////////////////////////////////////////////

+ 10 - 0
src/gfaipc.h

@@ -181,6 +181,15 @@ typedef struct _GFA_APPCTRL_APPTIMES
 }GFA_APPCTRL_APPTIMES, *LPGFA_APPCTRL_APPTIMES;
 typedef const GFA_APPCTRL_APPTIMES *LPCGFA_APPCTRL_APPTIMES;
 
+typedef struct _GFA_APPCTRL_APPMEM
+{
+	size_t vmPeak;
+	size_t vmSize;
+	size_t vmHWM;
+	size_t vmRSS;
+}GFA_APPCTRL_APPMEM, *LPGFA_APPCTRL_APPMEM;
+typedef const GFA_APPCTRL_APPMEM *LPCGFA_APPCTRL_APPMEM;
+
 /////////////////////////////////////////////////////////////////////////////
 
 HAPPCTRL		GfaIpcAppCtrlAcquire			(appid_t nAppID, const char *pszDisplayName, clock64_t nCycleIntvUs, clock64_t nMaxHeartbeatDelayUs);
@@ -203,6 +212,7 @@ bool			GfaIpcAppCtrlSendCtrlMsg		(HAPPCTRL hAC, appid_t nAppID, ctrlmsg_t msg);
 ctrlmsg_t		GfaIpcAppCtrlGetPendingCtrlMsg	(HAPPCTRL hAC);
 
 clock64_t		GfaIpcAppCtrlGetAppTimes		(HAPPCTRL hAC, appid_t nAppID, LPGFA_APPCTRL_APPTIMES pat);
+bool			GfaIpcAppCtrlGetAppMem			(HAPPCTRL hAC, appid_t nAppID, LPGFA_APPCTRL_APPMEM pam);
 
 /////////////////////////////////////////////////////////////////////////////
 

+ 157 - 0
src/procmem.cpp

@@ -0,0 +1,157 @@
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include "defines.h"
+#include "procmem.h"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// https://linuxwiki.de/proc
+// https://linuxwiki.de/proc/pid
+// http://man7.org/linux/man-pages/man5/proc.5.html
+//
+
+/////////////////////////////////////////////////////////////////////////////
+
+#define _STATUS_BUFFER_SIZE				1024
+
+/////////////////////////////////////////////////////////////////////////////
+
+static char* _GetNextLine(char *psz, const char **ppszKey, const char **ppszValue)
+{
+	*ppszKey = *ppszValue = NULL;
+	
+	if(psz && *psz)
+	{
+		while(isspace(*psz))
+			++psz;
+
+		char *pszRet = NULL;
+		char *nl = strchr(psz, '\n');
+
+		if(nl)
+		{
+			*nl = '\0';
+			pszRet = ++nl;
+		}
+
+		char *cl = strchr(psz, ':');
+
+		if(cl)
+		{
+			*ppszKey = psz;
+			*cl = '\0';
+			psz = ++cl;
+			while(isspace(*psz))
+				++psz;
+			if(*psz)
+				*ppszValue = psz;
+		}
+		
+		return *pszRet ? pszRet : NULL;
+	}
+
+	return NULL;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+static void _GetVmValue(const char *pszValue, VM_VALUE &vm)
+{
+	char szUnit[3];
+	size_t val;
+	int n = sscanf(pszValue, "%zu %2s", &val, szUnit);
+
+	if((n == 2) && !strcmp(szUnit, "kB"))
+	{
+		vm.cb = val;
+		vm.valid = true;
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+CProcMem::CProcMem(pid_t pid)
+{
+	m_pid = pid ? pid : getpid();
+	sprintf(m_szStatusFilePath, "/proc/%d/status", m_pid);
+	Clear();
+}
+
+CProcMem::~CProcMem(void)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+bool CProcMem::Update(void)
+{
+	char szStatus[_STATUS_BUFFER_SIZE];
+	int fd = open(m_szStatusFilePath, O_RDONLY, 0);
+
+	if(fd >= 0)
+	{
+	    int nRead = read(fd, szStatus, sizeof(szStatus) - 1);
+		close(fd);
+		
+		if(nRead > 0)
+		{
+			szStatus[nRead] = '\0';
+			char *pszStat = szStatus;
+			const char *pszKey, *pszValue;
+			
+			do
+			{
+				pszStat = _GetNextLine(pszStat, &pszKey, &pszValue);
+				
+				if(pszKey && *pszKey && pszValue && *pszValue)
+				{
+					if(!strcmp(pszKey, "VmPeak"))
+						_GetVmValue(pszValue, m_vmMap.VmPeak);
+					else if(!strcmp(pszKey, "VmSize"))
+						_GetVmValue(pszValue, m_vmMap.VmSize);
+					else if(!strcmp(pszKey, "VmHWM"))
+						_GetVmValue(pszValue, m_vmMap.VmHWM);
+					else if(!strcmp(pszKey, "VmRSS"))
+						_GetVmValue(pszValue, m_vmMap.VmRSS);
+#if _EXTENDED_VM_VALUES
+					else if(!strcmp(pszKey, "VmLck"))
+						_GetVmValue(pszValue, m_vmMap.VmLck);
+					else if(!strcmp(pszKey, "VmPin"))
+						_GetVmValue(pszValue, m_vmMap.VmPin);
+					else if(!strcmp(pszKey, "VmData"))
+						_GetVmValue(pszValue, m_vmMap.VmData);
+					else if(!strcmp(pszKey, "VmStk"))
+						_GetVmValue(pszValue, m_vmMap.VmStk);
+					else if(!strcmp(pszKey, "VmExe"))
+						_GetVmValue(pszValue, m_vmMap.VmExe);
+					else if(!strcmp(pszKey, "VmLib"))
+						_GetVmValue(pszValue, m_vmMap.VmLib);
+					else if(!strcmp(pszKey, "VmPTE"))
+						_GetVmValue(pszValue, m_vmMap.VmPTE);
+					else if(!strcmp(pszKey, "VmPMD"))
+						_GetVmValue(pszValue, m_vmMap.VmPMD);
+					else if(!strcmp(pszKey, "VmSwap"))
+						_GetVmValue(pszValue, m_vmMap.VmSwap);
+#endif // _EXTENDED_VM_VALUES
+				}
+			}
+			while(pszStat);
+
+			return true;
+		}
+	}
+
+	return false;
+}
+
+void CProcMem::Clear(void)
+{
+	memset(&m_vmMap, 0, sizeof(m_vmMap));
+}

+ 117 - 0
src/procmem.h

@@ -0,0 +1,117 @@
+// procmem.h : process memory
+//
+
+#if !defined(AGD_PROCMEM_H__0D8AD8BF_0953_4C0C_879D_CC0A60B6B639__INCLUDED_)
+#define AGD_PROCMEM_H__0D8AD8BF_0953_4C0C_879D_CC0A60B6B639__INCLUDED_
+
+#include <stdint.h>
+#include <unistd.h>
+
+#ifdef __cplusplus
+
+/////////////////////////////////////////////////////////////////////////////
+// procmem.h - Declarations:
+
+#define _EXTENDED_VM_VALUES				0
+
+typedef struct _VM_VALUE
+{
+	size_t cb;
+	bool valid;
+}VM_VALUE, *LPVM_VALUE;
+typedef const VM_VALUE *LPCVM_VALUE;
+
+typedef struct _VM_MAP
+{
+	VM_VALUE VmPeak;	// Peak virtual memory size.
+	VM_VALUE VmSize;	// Virtual memory size.
+	VM_VALUE VmHWM;		// Peak resident set size ("high water mark").
+	VM_VALUE VmRSS;		// Resident set size.
+#if _EXTENDED_VM_VALUES
+	VM_VALUE VmLck;		// Locked memory size.
+	VM_VALUE VmPin;		// Pinned memory size (since Linux 3.2).  These are pages that can't be moved because something needs to directly access physical memory.
+	VM_VALUE VmData;	// Size of data segment.
+	VM_VALUE VmStk;		// Size of stack.
+	VM_VALUE VmExe;		// Size of text segment.
+	VM_VALUE VmLib;		// Shared library code size.
+	VM_VALUE VmPTE;		// Page table entries size (since Linux 2.6.10).
+	VM_VALUE VmPMD;		// Size of second-level page tables (added in Linux 4.0; removed in Linux 4.15).
+	VM_VALUE VmSwap;	// Swapped-out virtual memory size by anonymous private pages; shmem swap usage is not included (since Linux 2.6.34).
+#endif	//	_EXTENDED_VM_VALUES
+}VM_MAP, *LPVM_MAP;
+typedef const VM_MAP *LPCVM_MAP;
+
+/////////////////////////////////////////////////////////////////////////////
+
+class CProcMem
+{
+public:
+	CProcMem(pid_t pid = 0);
+	virtual ~CProcMem(void);
+	
+	bool Update(void);
+	void Clear(void);
+
+	const VM_VALUE& VmPeak(void) const {
+		return m_vmMap.VmPeak;
+	}
+
+	const VM_VALUE& VmSize(void) const {
+		return m_vmMap.VmSize;
+	}
+
+	const VM_VALUE& VmHWM(void) const {
+		return m_vmMap.VmHWM;
+	}
+
+	const VM_VALUE& VmRSS(void) const {
+		return m_vmMap.VmRSS;
+	}
+
+#if _EXTENDED_VM_VALUES
+	const VM_VALUE& VmLck(void) const {
+		return m_vmMap.VmLck;
+	}
+
+	const VM_VALUE& VmPin(void) const {
+		return m_vmMap.VmPin;
+	}
+
+	const VM_VALUE& VmData(void) const {
+		return m_vmMap.VmData;
+	}
+
+	const VM_VALUE& VmStk(void) const {
+		return m_vmMap.VmStk;
+	}
+
+	const VM_VALUE& VmExe(void) const {
+		return m_vmMap.VmExe;
+	}
+
+	const VM_VALUE& VmLib(void) const {
+		return m_vmMap.VmLib;
+	}
+
+	const VM_VALUE& VmPTE(void) const {
+		return m_vmMap.VmPTE;
+	}
+
+	const VM_VALUE& VmPMD(void) const {
+		return m_vmMap.VmPMD;
+	}
+
+	const VM_VALUE& VmSwap(void) const {
+		return m_vmMap.VmSwap;
+	}
+#endif	//	_EXTENDED_VM_VALUES
+
+private:
+	pid_t m_pid;
+	VM_MAP m_vmMap;
+	char m_szStatusFilePath[32];
+};
+
+/////////////////////////////////////////////////////////////////////////////
+#endif	//	__cplusplus
+#endif	//	!defined(AGD_PROCMEM_H__0D8AD8BF_0953_4C0C_879D_CC0A60B6B639__INCLUDED_)