From 342568511948ddabd4ce0ca58efc510b6c02904b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 14 Oct 2013 12:09:44 -0700 Subject: [PATCH] first cut at added voxel node memory usage debugging to client and server --- interface/src/Application.cpp | 5 +- libraries/voxel-server-library/CMakeLists.txt | 5 ++ .../voxel-server-library/src/VoxelServer.cpp | 46 +++++++++++++++++++ .../voxel-server-library/src/VoxelServer.h | 7 +++ libraries/voxels/src/VoxelNode.cpp | 8 ++++ libraries/voxels/src/VoxelNode.h | 3 ++ 6 files changed, 72 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 81e40cc109..070062f164 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2993,14 +2993,15 @@ void Application::displayStats() { drawtext(10, statsVerticalOffset + 230, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); voxelStats.str(""); - voxelStats << "Voxels Memory RAM: " << _voxels.getVoxelMemoryUsageRAM() / 1000000.f << "MB " << + voxelStats << "Voxels Memory Nodes: " << VoxelNode::getVoxelMemoryUsage() / 1000000.f << "MB " + "Geometry RAM: " << _voxels.getVoxelMemoryUsageRAM() / 1000000.f << "MB " << "VBO: " << _voxels.getVoxelMemoryUsageVBO() / 1000000.f << "MB "; if (_voxels.hasVoxelMemoryUsageGPU()) { voxelStats << "GPU: " << _voxels.getVoxelMemoryUsageGPU() / 1000000.f << "MB "; } drawtext(10, statsVerticalOffset + 250, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); - + voxelStats.str(""); char* voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_VOXELS); voxelStats << "Voxels Sent from Server: " << voxelDetails; diff --git a/libraries/voxel-server-library/CMakeLists.txt b/libraries/voxel-server-library/CMakeLists.txt index 9eabb95508..1298ef1bae 100644 --- a/libraries/voxel-server-library/CMakeLists.txt +++ b/libraries/voxel-server-library/CMakeLists.txt @@ -18,6 +18,11 @@ qt5_use_modules(${TARGET_NAME} Widgets) include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} ${ROOT_DIR}) +# setup a library for civetweb and link it to the voxel-server-library +# this assumes that the domain-server cmake has already correctly set up the civetweb library +include_directories(../../domain-server/external/civetweb/include) +target_link_libraries(${TARGET_NAME} civetweb) + include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) diff --git a/libraries/voxel-server-library/src/VoxelServer.cpp b/libraries/voxel-server-library/src/VoxelServer.cpp index aeda7cf277..07a0b65c57 100644 --- a/libraries/voxel-server-library/src/VoxelServer.cpp +++ b/libraries/voxel-server-library/src/VoxelServer.cpp @@ -70,6 +70,7 @@ VoxelServer::VoxelServer(Assignment::Command command, Assignment::Location locat _parsedArgV = NULL; } + VoxelServer::VoxelServer(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes), _serverTree(true) { _argc = 0; @@ -101,6 +102,43 @@ VoxelServer::~VoxelServer() { } } +void VoxelServer::initMongoose(int port) { + // setup the mongoose web server + struct mg_callbacks callbacks = {}; + + QString documentRoot = QString("%1/resources/web").arg(QCoreApplication::applicationDirPath()); + QString listenPort = QString("%1").arg(port); + + + // list of options. Last element must be NULL. + const char* options[] = { + "listening_ports", listenPort.toLocal8Bit().constData(), + "document_root", documentRoot.toLocal8Bit().constData(), + NULL }; + + callbacks.begin_request = civetwebRequestHandler; + + // Start the web server. + mg_start(&callbacks, NULL, options); +} + +int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) { + const struct mg_request_info* ri = mg_get_request_info(connection); + + if (strcmp(ri->uri, "/") == 0 && strcmp(ri->request_method, "GET") == 0) { + // return a 200 + mg_printf(connection, "%s", "HTTP/1.0 200 OK\r\n\r\n"); + mg_printf(connection, "%s", "Your Voxel Server is running.\r\n"); + mg_printf(connection, "%s", "Current Statistics\r\n"); + mg_printf(connection, "Voxel Node Memory Usage: %f MB\r\n", VoxelNode::getVoxelMemoryUsage() / 1000000.f); + return 1; + } else { + // have mongoose process this request from the document_root + return 0; + } +} + + void VoxelServer::setArguments(int argc, char** argv) { _argc = argc; _argv = const_cast(argv); @@ -157,6 +195,14 @@ void VoxelServer::run() { qInstallMessageHandler(Logging::verboseMessageHandler); + const char* STATUS_PORT = "--statusPort"; + const char* statusPort = getCmdOption(_argc, _argv, STATUS_PORT); + if (statusPort) { + int statusPortNumber = atoi(statusPort); + initMongoose(statusPortNumber); + } + + const char* JURISDICTION_FILE = "--jurisdictionFile"; const char* jurisdictionFile = getCmdOption(_argc, _argv, JURISDICTION_FILE); if (jurisdictionFile) { diff --git a/libraries/voxel-server-library/src/VoxelServer.h b/libraries/voxel-server-library/src/VoxelServer.h index 464938706e..c05a2037c1 100644 --- a/libraries/voxel-server-library/src/VoxelServer.h +++ b/libraries/voxel-server-library/src/VoxelServer.h @@ -10,7 +10,10 @@ #ifndef __voxel_server__VoxelServer__ #define __voxel_server__VoxelServer__ +#include "../../domain-server/external/civetweb/include/civetweb.h" + #include +#include #include #include @@ -82,6 +85,10 @@ private: NodeWatcher _nodeWatcher; // used to cleanup AGENT data when agents are killed void parsePayload(); + + void initMongoose(int port); + + static int civetwebRequestHandler(struct mg_connection *connection); }; #endif // __voxel_server__VoxelServer__ diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index a7675f4609..154d573836 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -21,6 +21,8 @@ #include "VoxelNode.h" #include "VoxelTree.h" +uint64_t VoxelNode::_voxelMemoryUsage = 0; + VoxelNode::VoxelNode() { unsigned char* rootCode = new unsigned char[1]; *rootCode = 0; @@ -56,11 +58,17 @@ void VoxelNode::init(unsigned char * octalCode) { _sourceID = UNKNOWN_NODE_ID; calculateAABox(); markWithChangedTime(); + + _voxelMemoryUsage += sizeof(VoxelNode); + _voxelMemoryUsage += bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(_octalCode)); } VoxelNode::~VoxelNode() { notifyDeleteHooks(); + _voxelMemoryUsage -= sizeof(VoxelNode); + _voxelMemoryUsage -= bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(_octalCode)); + delete[] _octalCode; // delete all of this node's children diff --git a/libraries/voxels/src/VoxelNode.h b/libraries/voxels/src/VoxelNode.h index 9664b33a29..6a92ab1e42 100644 --- a/libraries/voxels/src/VoxelNode.h +++ b/libraries/voxels/src/VoxelNode.h @@ -127,6 +127,8 @@ public: unsigned long getSubTreeInternalNodeCount() const { return _subtreeNodeCount - _subtreeLeafNodeCount; } unsigned long getSubTreeLeafNodeCount() const { return _subtreeLeafNodeCount; } + static uint64_t getVoxelMemoryUsage() { return _voxelMemoryUsage; } + private: void calculateAABox(); void init(unsigned char * octalCode); @@ -154,6 +156,7 @@ private: static std::vector _deleteHooks; static std::vector _updateHooks; + static uint64_t _voxelMemoryUsage; }; #endif /* defined(__hifi__VoxelNode__) */