Resource Tracking for FlightGear: Difference between revisions

Jump to navigation Jump to search
m
→‎Proof of concept (patch): removed leading whitespaces (which broke syntaxhighlighting)
mNo edit summary
m (→‎Proof of concept (patch): removed leading whitespaces (which broke syntaxhighlighting))
Line 226: Line 226:


Here's a first stab at a simple subsystem to monitor FlightGear memory usage on Linux at 5 second intervals, consider it a "proof of concept" prototype now, as this would need to be cleaned up and implemented for Mac/Windows respectively - on Linux it simply works such that it merely fopen()s /proc/pid/smaps and copies two metrics to the property tree:
Here's a first stab at a simple subsystem to monitor FlightGear memory usage on Linux at 5 second intervals, consider it a "proof of concept" prototype now, as this would need to be cleaned up and implemented for Mac/Windows respectively - on Linux it simply works such that it merely fopen()s /proc/pid/smaps and copies two metrics to the property tree:
<syntaxhighlight lang="diff">
<syntaxhighlight lang="diff">
    diff -urN a/src/Main/CMakeLists.txt b/src/Main/CMakeLists.txt
diff -urN a/src/Main/CMakeLists.txt b/src/Main/CMakeLists.txt
    --- a/src/Main/CMakeLists.txt   2015-08-20 23:03:15.070835000 +0300
--- a/src/Main/CMakeLists.txt 2015-08-20 23:03:15.070835000 +0300
    +++ b/src/Main/CMakeLists.txt   2015-08-20 23:26:58.706798388 +0300
+++ b/src/Main/CMakeLists.txt 2015-08-20 23:26:58.706798388 +0300
    @@ -17,12 +17,17 @@
@@ -17,12 +17,17 @@
            main.cxx
main.cxx
            options.cxx
options.cxx
            util.cxx
util.cxx
    +       ram_usage.cxx
+ ram_usage.cxx
        positioninit.cxx
positioninit.cxx
        subsystemFactory.cxx
subsystemFactory.cxx
        screensaver_control.cxx
screensaver_control.cxx
            ${RESOURCE_FILE}
${RESOURCE_FILE}
            )
)
   
    +IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
    +        list(APPEND SOURCES ram_usage_linux.cxx)
    +ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
    +
    set(HEADERS
            fg_commands.hxx
            fg_init.hxx
    @@ -35,12 +40,19 @@
            main.hxx
            options.hxx
            util.hxx
    +      ram_usage.hxx
        positioninit.hxx
        subsystemFactory.hxx
        AircraftDirVisitorBase.hxx
        screensaver_control.hxx
            )
   
    +IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
    +        list(APPEND HEADERS ram_usage_linux.hxx)
    +ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
    +
    +
    +
    get_property(FG_SOURCES GLOBAL PROPERTY FG_SOURCES)
    get_property(FG_HEADERS GLOBAL PROPERTY FG_HEADERS)
   
    diff -urN a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx
    --- a/src/Main/fg_init.cxx      2015-08-20 23:22:52.166804000 +0300
    +++ b/src/Main/fg_init.cxx      2015-08-20 23:29:15.074794813 +0300
    @@ -141,6 +141,7 @@
    #include "globals.hxx"
    #include "logger.hxx"
    #include "main.hxx"
    +#include "ram_usage.hxx"
    #include "positioninit.hxx"
    #include "util.hxx"
    #include "AircraftDirVisitorBase.hxx"
    @@ -715,6 +716,10 @@
        ////////////////////////////////////////////////////////////////////
        globals->add_subsystem("properties", new FGProperties);
   
    +    ////////////////////////////////////////////////////////////////////
    +    // Add the ram usage statistics system
    +    ////////////////////////////////////////////////////////////////////
    +    globals->add_subsystem("memory-stats", new MemoryUsageStats, SGSubsystemMgr::INIT, 5.00);
   
        ////////////////////////////////////////////////////////////////////
        // Add the performance monitoring system.
    diff -urN a/src/Main/ram_usage.cxx b/src/Main/ram_usage.cxx
    --- a/src/Main/ram_usage.cxx    1970-01-01 03:00:00.000000000 +0300
    +++ b/src/Main/ram_usage.cxx    2015-08-20 23:29:53.950793794 +0300
    @@ -0,0 +1,22 @@
    +#include "ram_usage_linux.hxx"
    +
    +MemoryUsageStats::MemoryUsageStats() {
    + _mem = new LinuxMemoryInterface(); //FIXME: should be implemented for Win/Mac & Linux
    +}
    +
    +MemoryUsageStats::~MemoryUsageStats() {
    + delete _mem;
    +}
    +
    +void
    +MemoryUsageStats::update(double dt) {
    +  _mem->update();
    +  double swap = _mem->getSwapSize();
    +  double total = _mem->getTotalSize();
    +  SG_LOG(SG_GENERAL, SG_DEBUG, "Updating Memory Stats:" << total << " kb");
    +  fgSetInt("/memory-usage/swap-usage-kb",  swap );
    +  fgSetInt("/memory-usage/total-usage-kb", total );
    +}
    +
    +
    +
    diff -urN a/src/Main/ram_usage.hxx b/src/Main/ram_usage.hxx
    --- a/src/Main/ram_usage.hxx    1970-01-01 03:00:00.000000000 +0300
    +++ b/src/Main/ram_usage.hxx    2015-08-20 23:29:53.950793794 +0300
    @@ -0,0 +1,51 @@
    +#ifndef __RAM_USAGE
    +#define __RAM_USAGE
    +
    +#include <simgear/timing/timestamp.hxx>
    +#include <simgear/structure/subsystem_mgr.hxx>
    +
    +#include <Main/globals.hxx>
    +#include <Main/fg_props.hxx>
    +
    +#include <string>
    +#include <map>
    +
    +using std::map;
    +
    +// Linux: /proc/pid/smaps
    +// Windows: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682050(v=vs.85).aspx
    +
    +class MemoryInterface {
    +public:
    + MemoryInterface() {}
    + typedef map<const char*, double> RamMap;
    +//protected:
    + virtual void update() = 0;
    +
    + double getTotalSize() const {return _total_size;}
    + //virtual void  setTotalSize(double t) {_total_size=t;}
    +
    + double getSwapSize() const {return _swap_size;}
    + //virtual void  setSwapSize(double s) {_swap_size=s;}
    +protected:
    + RamMap _size;
    + std::string _path;
    + std::stringstream _pid;
    +
    + double _total_size;
    + double _swap_size;
    +};
    +
    +class MemoryUsageStats : public SGSubsystem
    +{
    +public:
    +  MemoryUsageStats();
    + ~MemoryUsageStats();
    +  virtual void update(double);
    +protected:
    +private:
    +  MemoryInterface* _mem;
    +};
    +
    +#endif
    +
    diff -urN a/src/Main/ram_usage_linux.cxx b/src/Main/ram_usage_linux.cxx
    --- a/src/Main/ram_usage_linux.cxx      1970-01-01 03:00:00.000000000 +0300
    +++ b/src/Main/ram_usage_linux.cxx      2015-08-20 23:29:53.950793794 +0300
    @@ -0,0 +1,49 @@
    +// https://gist.github.com/896026/c346c7c8e4a9ab18577b4e6abfca37e358de83c1
    +
    +#include "ram_usage_linux.hxx"
    +
    +#include <cstring>
    +#include <string>
    +
    +#include "Main/globals.hxx"
    +
    +using std::string;
    +
    +LinuxMemoryInterface::LinuxMemoryInterface() {
    + _pid << getpid();
    + _path = "/proc/"+ _pid.str() +"/smaps";
    +}
    +
    +void
    +LinuxMemoryInterface::OpenProcFile() {
    + file = fopen(_path.c_str(),"r" );
    + if (!file) {
    +        throw("MemoryTracker:Cannot open /proc/pid/smaps");
    +    }
    + SG_LOG(SG_GENERAL, SG_DEBUG, "Opened:"<< _path.c_str() );
    +}
    +
    +LinuxMemoryInterface::~LinuxMemoryInterface() {
    + if (file) fclose(file);
    +}
    +
    +void LinuxMemoryInterface::update() {
    + OpenProcFile();
    + if (!file) throw("MemoryTracker: ProcFile not open");
    +
    +  _total_size = 0;
    +  _swap_size = 0;
    +
    +  char line[1024];
    +  while (fgets(line, sizeof line, file))
    +    {
    +        char substr[32];
    +        int n;
    +        if (sscanf(line, "%31[^:]: %d", substr, &n) == 2) {
    +          if (strcmp(substr, "Size") == 0)          { _total_size += n; }
    +              else    if (strcmp(substr, "Swap") == 0)          { _swap_size += n; }
    +    }
    +  }
    +  fclose(file);
    +}
    +
    diff -urN a/src/Main/ram_usage_linux.hxx b/src/Main/ram_usage_linux.hxx
    --- a/src/Main/ram_usage_linux.hxx      1970-01-01 03:00:00.000000000 +0300
    +++ b/src/Main/ram_usage_linux.hxx      2015-08-20 23:29:53.950793794 +0300
    @@ -0,0 +1,22 @@
    +#ifndef __RAM_USAGE_LINUX
    +#define __RAM_USAGE_LINUX
    +
    + #include <sys/types.h>
    + #include <unistd.h>
    + #include <stdio.h>
    +
    + #include "ram_usage.hxx"
    +
    +class LinuxMemoryInterface : public MemoryInterface {
    +public:
    + LinuxMemoryInterface();
    +~LinuxMemoryInterface();
    + virtual void update();
    +private:
    + void OpenProcFile();
    + const char* filename;
    + FILE *file;
    +};
    +
    +
    +#endif
    +


+IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+ list(APPEND SOURCES ram_usage_linux.cxx)
+ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+
set(HEADERS
fg_commands.hxx
fg_init.hxx
@@ -35,12 +40,19 @@
main.hxx
options.hxx
util.hxx
+ ram_usage.hxx
positioninit.hxx
subsystemFactory.hxx
AircraftDirVisitorBase.hxx
screensaver_control.hxx
)
+IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+ list(APPEND HEADERS ram_usage_linux.hxx)
+ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+
+
+
get_property(FG_SOURCES GLOBAL PROPERTY FG_SOURCES)
get_property(FG_HEADERS GLOBAL PROPERTY FG_HEADERS)
diff -urN a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx
--- a/src/Main/fg_init.cxx 2015-08-20 23:22:52.166804000 +0300
+++ b/src/Main/fg_init.cxx 2015-08-20 23:29:15.074794813 +0300
@@ -141,6 +141,7 @@
#include "globals.hxx"
#include "logger.hxx"
#include "main.hxx"
+#include "ram_usage.hxx"
#include "positioninit.hxx"
#include "util.hxx"
#include "AircraftDirVisitorBase.hxx"
@@ -715,6 +716,10 @@
////////////////////////////////////////////////////////////////////
globals->add_subsystem("properties", new FGProperties);
+ ////////////////////////////////////////////////////////////////////
+ // Add the ram usage statistics system
+ ////////////////////////////////////////////////////////////////////
+ globals->add_subsystem("memory-stats", new MemoryUsageStats, SGSubsystemMgr::INIT, 5.00);
////////////////////////////////////////////////////////////////////
// Add the performance monitoring system.
diff -urN a/src/Main/ram_usage.cxx b/src/Main/ram_usage.cxx
--- a/src/Main/ram_usage.cxx 1970-01-01 03:00:00.000000000 +0300
+++ b/src/Main/ram_usage.cxx 2015-08-20 23:29:53.950793794 +0300
@@ -0,0 +1,22 @@
+#include "ram_usage_linux.hxx"
+
+MemoryUsageStats::MemoryUsageStats() {
+ _mem = new LinuxMemoryInterface(); //FIXME: should be implemented for Win/Mac & Linux
+}
+
+MemoryUsageStats::~MemoryUsageStats() {
+ delete _mem;
+}
+
+void
+MemoryUsageStats::update(double dt) {
+ _mem->update();
+ double swap = _mem->getSwapSize();
+ double total = _mem->getTotalSize();
+ SG_LOG(SG_GENERAL, SG_DEBUG, "Updating Memory Stats:" << total << " kb");
+ fgSetInt("/memory-usage/swap-usage-kb", swap );
+ fgSetInt("/memory-usage/total-usage-kb", total );
+}
+
+
+
diff -urN a/src/Main/ram_usage.hxx b/src/Main/ram_usage.hxx
--- a/src/Main/ram_usage.hxx 1970-01-01 03:00:00.000000000 +0300
+++ b/src/Main/ram_usage.hxx 2015-08-20 23:29:53.950793794 +0300
@@ -0,0 +1,51 @@
+#ifndef __RAM_USAGE
+#define __RAM_USAGE
+
+#include <simgear/timing/timestamp.hxx>
+#include <simgear/structure/subsystem_mgr.hxx>
+
+#include <Main/globals.hxx>
+#include <Main/fg_props.hxx>
+
+#include <string>
+#include <map>
+
+using std::map;
+
+// Linux: /proc/pid/smaps
+// Windows: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682050(v=vs.85).aspx
+
+class MemoryInterface {
+public:
+ MemoryInterface() {}
+ typedef map<const char*, double> RamMap;
+//protected:
+ virtual void update() = 0;
+
+ double getTotalSize() const {return _total_size;}
+ //virtual void setTotalSize(double t) {_total_size=t;}
+
+ double getSwapSize() const {return _swap_size;}
+ //virtual void setSwapSize(double s) {_swap_size=s;}
+protected:
+ RamMap _size;
+ std::string _path;
+ std::stringstream _pid;
+
+ double _total_size;
+ double _swap_size;
+};
+
+class MemoryUsageStats : public SGSubsystem
+{
+public:
+ MemoryUsageStats();
+ ~MemoryUsageStats();
+ virtual void update(double);
+protected:
+private:
+ MemoryInterface* _mem;
+};
+
+#endif
+
diff -urN a/src/Main/ram_usage_linux.cxx b/src/Main/ram_usage_linux.cxx
--- a/src/Main/ram_usage_linux.cxx 1970-01-01 03:00:00.000000000 +0300
+++ b/src/Main/ram_usage_linux.cxx 2015-08-20 23:29:53.950793794 +0300
@@ -0,0 +1,49 @@
+// https://gist.github.com/896026/c346c7c8e4a9ab18577b4e6abfca37e358de83c1
+
+#include "ram_usage_linux.hxx"
+
+#include <cstring>
+#include <string>
+
+#include "Main/globals.hxx"
+
+using std::string;
+
+LinuxMemoryInterface::LinuxMemoryInterface() {
+ _pid << getpid();
+ _path = "/proc/"+ _pid.str() +"/smaps";
+}
+
+void
+LinuxMemoryInterface::OpenProcFile() {
+ file = fopen(_path.c_str(),"r" );
+ if (!file) {
+ throw("MemoryTracker:Cannot open /proc/pid/smaps");
+ }
+ SG_LOG(SG_GENERAL, SG_DEBUG, "Opened:"<< _path.c_str() );
+}
+
+LinuxMemoryInterface::~LinuxMemoryInterface() {
+ if (file) fclose(file);
+}
+
+void LinuxMemoryInterface::update() {
+ OpenProcFile();
+ if (!file) throw("MemoryTracker: ProcFile not open");
+
+ _total_size = 0;
+ _swap_size = 0;
+
+ char line[1024];
+ while (fgets(line, sizeof line, file))
+ {
+ char substr[32];
+ int n;
+ if (sscanf(line, "%31[^:]: %d", substr, &n) == 2) {
+ if (strcmp(substr, "Size") == 0) { _total_size += n; }
+ else if (strcmp(substr, "Swap") == 0) { _swap_size += n; }
+ }
+ }
+ fclose(file);
+}
+
diff -urN a/src/Main/ram_usage_linux.hxx b/src/Main/ram_usage_linux.hxx
--- a/src/Main/ram_usage_linux.hxx 1970-01-01 03:00:00.000000000 +0300
+++ b/src/Main/ram_usage_linux.hxx 2015-08-20 23:29:53.950793794 +0300
@@ -0,0 +1,22 @@
+#ifndef __RAM_USAGE_LINUX
+#define __RAM_USAGE_LINUX
+
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <stdio.h>
+
+ #include "ram_usage.hxx"
+
+class LinuxMemoryInterface : public MemoryInterface {
+public:
+ LinuxMemoryInterface();
+~LinuxMemoryInterface();
+ virtual void update();
+private:
+ void OpenProcFile();
+ const char* filename;
+ FILE *file;
+};
+
+
+#endif
+
</syntaxhighlight>
</syntaxhighlight>


[[Category:Core development projects]]
[[Category:Core development projects]]

Navigation menu