Browse Source

measure memory usage during runtime automatically

Stan Gurtler 2 years ago
parent
commit
b8662cc18f

+ 11 - 3
prsona/inc/networkClient.hpp

@@ -33,7 +33,9 @@ void make_vote(
     size_t numClients,
     const CivetServer& civetServer,
     std::mutex& outputMtx,
-    const std::string& outputFilename);
+    const std::string& outputFilename,
+    std::mutex& usageMtx,
+    const std::string& usageFilename);
 
 bool make_reputation_proof(
     std::default_random_engine& rng,
@@ -45,7 +47,9 @@ bool make_reputation_proof(
     size_t numClients,
     const CivetServer& civetServer,
     std::mutex& outputMtx,
-    const std::string& outputFilename);
+    const std::string& outputFilename,
+    std::mutex& usageMtx,
+    const std::string& usageFilename);
 
 /* "PRIVATE" FUNCTIONS */
 
@@ -182,7 +186,9 @@ class PrsonaClientWebSocketHandler : public CivetWebSocketHandler {
             const std::vector<std::string>& serverIPs,
             const std::vector<int>& serverPorts,
             std::mutex& outputMtx,
-            const std::string& outputFilename);
+            const std::string& outputFilename,
+            std::mutex& usageMtx,
+            const std::string& usageFilename);
 
         // REQUIRED BY INHERITED CLASS
         virtual bool handleConnection(
@@ -214,6 +220,8 @@ class PrsonaClientWebSocketHandler : public CivetWebSocketHandler {
 
         std::mutex& outputMtx;
         const std::string outputFilename;
+        std::mutex& usageMtx;
+        const std::string usageFilename;
 
         // RESPONSE ROUTER FUNCTION
         void generate_response(

+ 12 - 2
prsona/inc/networkServer.hpp

@@ -49,7 +49,9 @@ void make_epoch(
     std::mutex& breakDownOutputMtx,
     const std::string& breakDownOutputFilename,
     std::mutex& fullOutputMtx,
-    const std::string& fullOutputFilename);
+    const std::string& fullOutputFilename,
+    std::mutex& usageMtx,
+    const std::string& usageFilename);
 
 /* "PRIVATE" FUNCTIONS */
 
@@ -109,6 +111,8 @@ std::vector<Proof> epoch_build_up(
     const CivetServer& civetServer,
     std::mutex& outputMtx,
     const std::string& outputFilename,
+    std::mutex& usageMtx,
+    const std::string& usageFilename,
     std::vector<size_t>& bandwidthData);
 
 void epoch_break_down(
@@ -123,6 +127,8 @@ void epoch_break_down(
     const CivetServer& civetServer,
     std::mutex& outputMtx,
     const std::string& outputFilename,
+    std::mutex& usageMtx,
+    const std::string& usageFilename,
     std::vector<size_t>& bandwidthData);
 
 // HELPERS FOR EPOCH HELPERS
@@ -310,7 +316,9 @@ class PrsonaServerWebSocketHandler : public CivetWebSocketHandler  {
             std::mutex& updateOutputMtx,
             const std::string& updateOutputFilename,
             std::mutex& voteOutputMtx,
-            const std::string& voteOutputFilename);
+            const std::string& voteOutputFilename,
+            std::mutex& usageMtx,
+            const std::string& usageFilename);
 
         // REQUIRED BY INHERITED CLASS
         bool handleConnection(
@@ -355,6 +363,8 @@ class PrsonaServerWebSocketHandler : public CivetWebSocketHandler  {
         const std::string updateOutputFilename;
         std::mutex& voteOutputMtx;
         const std::string voteOutputFilename;
+        std::mutex& usageMtx;
+        const std::string usageFilename;
 
         struct synchronization_tool updateSynch, distributeSynch;
 

+ 7 - 0
prsona/inc/networking.hpp

@@ -200,6 +200,10 @@ void write_log_data(
     const std::vector<double>& timingData,
     const std::vector<size_t>& bandwidthData);
 
+void write_usage_data(
+    std::mutex& outputMtx,
+    const std::string& outputFilename);
+
 /* "PRIVATE" FUNCTIONS TO HELP THE GENERIC HELPERS */
 
 // Helper for set_temp_filename()
@@ -212,6 +216,9 @@ size_t parse_log_for_data(
     const char *input,
     const char *key);
 
+// This function gets current memory usage
+unsigned long mem_usage();
+
 /* WEBSOCKET HANDLER FUNCTIONS */
 
 // NULL

+ 5 - 3
prsona/src/clientMain.cpp

@@ -58,6 +58,8 @@ int main(int argc, char *argv[])
     string repProofOutputFilename = outputDir + "/repProver.out";
     mutex repVerifyOutputMtx;
     string repVerifyOutputFilename = outputDir + "/repVerifier.out";
+    mutex memUsageOutputMtx;
+    string memUsageOutputFilename = outputDir + "/usage.out";
 
     // Default to not doing proof batching if not specified
     size_t lambda = 0;
@@ -142,7 +144,7 @@ int main(int argc, char *argv[])
     cout << "[" << seedStr << "] Setting up handlers for client." << endl;
 
     // Main handler (in clients, only used for verifying reputation proofs)
-    PrsonaClientWebSocketHandler wsHandler(rng, prsonaClient, serverIPs, serverPorts, repVerifyOutputMtx, repVerifyOutputFilename);
+    PrsonaClientWebSocketHandler wsHandler(rng, prsonaClient, serverIPs, serverPorts, repVerifyOutputMtx, repVerifyOutputFilename, memUsageOutputMtx, memUsageOutputFilename);
     server.addWebSocketHandler("/ws", wsHandler);
 
     // Exit handler (allows client to be brought down by making correct GET request)
@@ -187,7 +189,7 @@ int main(int argc, char *argv[])
             case CLIENT_MAKE_VOTE:
                 cout << "[" << seedStr << "] Making new vote row." << endl;
                 whichServer = distribution(rng);
-                make_vote(rng, prsonaClient, serverIPs, serverPorts, serverIPs[whichServer], serverPorts[whichServer], numClients, server, voteOutputMtx, voteOutputFilename);
+                make_vote(rng, prsonaClient, serverIPs, serverPorts, serverIPs[whichServer], serverPorts[whichServer], numClients, server, voteOutputMtx, voteOutputFilename, memUsageOutputMtx, memUsageOutputFilename);
                 cout << "[" << seedStr << "] New vote row complete." << endl;
                 break;
 
@@ -199,7 +201,7 @@ int main(int argc, char *argv[])
                 targetPort = stoi(fullQuery.substr(colonLocation + 1));
 
                 cout << "[" << seedStr << "] Making new reputation proof." << endl;
-                make_reputation_proof(rng, prsonaClient, serverIPs, serverPorts, target, targetPort, numClients, server, repProofOutputMtx, repProofOutputFilename);
+                make_reputation_proof(rng, prsonaClient, serverIPs, serverPorts, target, targetPort, numClients, server, repProofOutputMtx, repProofOutputFilename, memUsageOutputMtx, memUsageOutputFilename);
                 cout << "[" << seedStr << "] New reputation proof complete." << endl;
                 break;
 

+ 13 - 4
prsona/src/networkClient.cpp

@@ -62,7 +62,9 @@ void make_vote(
     size_t numClients,
     const CivetServer& civetServer,
     std::mutex& outputMtx,
-    const std::string& outputFilename)
+    const std::string& outputFilename,
+    std::mutex& usageMtx,
+    const std::string& usageFilename)
 {
     std::uniform_int_distribution<int> voteDistribution(0, PrsonaBase::get_max_allowed_vote());
     std::uniform_int_distribution<int> numVoteDistribution(0, numClients);
@@ -119,6 +121,7 @@ void make_vote(
     bandwidthData[1] += bandwidthDataAfter[1] - bandwidthDataBefore[1];
 
     write_log_data(outputMtx, outputFilename, timingData, bandwidthData);
+    write_usage_data(usageMtx, usageFilename);
 }
 
 bool make_reputation_proof(
@@ -131,7 +134,9 @@ bool make_reputation_proof(
     size_t numClients,
     const CivetServer& civetServer,
     std::mutex& outputMtx,
-    const std::string& outputFilename)
+    const std::string& outputFilename,
+    std::mutex& usageMtx,
+    const std::string& usageFilename)
 {
     std::vector<size_t> bandwidthData(2);
 
@@ -180,6 +185,7 @@ bool make_reputation_proof(
     bandwidthData[1] += bandwidthDataAfter[1] - bandwidthDataBefore[1];
 
     write_log_data(outputMtx, outputFilename, timingData, bandwidthData);
+    write_usage_data(usageMtx, usageFilename);
 
     // The other client will give one byte back, containing whether or not it accepted the proof
     std::ifstream response(responseFile);
@@ -924,8 +930,10 @@ PrsonaClientWebSocketHandler::PrsonaClientWebSocketHandler(
     const std::vector<std::string>& serverIPs,
     const std::vector<int>& serverPorts,
     std::mutex& outputMtx,
-    const std::string& outputFilename)
-: rng(rng), prsonaClient(prsonaClient), serverIPs(serverIPs), serverPorts(serverPorts), outputMtx(outputMtx), outputFilename(outputFilename)
+    const std::string& outputFilename,
+    std::mutex& usageMtx,
+    const std::string& usageFilename)
+: rng(rng), prsonaClient(prsonaClient), serverIPs(serverIPs), serverPorts(serverPorts), outputMtx(outputMtx), outputFilename(outputFilename), usageMtx(usageMtx), usageFilename(usageFilename)
 { /* */ }
 
 /*
@@ -1099,6 +1107,7 @@ void PrsonaClientWebSocketHandler::verify_reputation_proof(
     bandwidthData[1] += bandwidthDataAfter[1] - bandwidthDataBefore[1] + 1;
 
     write_log_data(outputMtx, outputFilename, timingData, bandwidthData);
+    write_usage_data(usageMtx, usageFilename);
 
     // Tell the prover whether or not we accept the proof
     std::string data = flag ? "\x01" : "\x00";

+ 22 - 5
prsona/src/networkServer.cpp

@@ -103,7 +103,9 @@ void make_epoch(
     std::mutex& breakDownOutputMtx,
     const std::string& breakDownOutputFilename,
     std::mutex& fullOutputMtx,
-    const std::string& fullOutputFilename)
+    const std::string& fullOutputFilename,
+    std::mutex& usageMtx,
+    const std::string& usageFilename)
 {
     // As before, the fresh generator always starts from the same G
     Twistpoint nextGenerator = PrsonaServer::EL_GAMAL_GENERATOR;
@@ -120,7 +122,7 @@ void make_epoch(
     obtain_update_locks(updateLock, serverIPs, serverPorts, selfIP, selfPort, bandwidthData);
 
     // Do the first half of the epoch calculations (building up the intermediary values)
-    std::vector<Proof> generatorProof = epoch_build_up(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, nextGenerator, civetServer, buildUpOutputMtx, buildUpOutputFilename, bandwidthData);
+    std::vector<Proof> generatorProof = epoch_build_up(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, nextGenerator, civetServer, buildUpOutputMtx, buildUpOutputFilename, usageMtx, usageFilename, bandwidthData);
 
     // Tally up the current scores at the end of the epoch for the users
     std::vector<EGCiphertext> currentUserEncryptedTallies;
@@ -131,7 +133,7 @@ void make_epoch(
     distribute_tallied_scores(prsonaServer, serverIPs, serverPorts, selfIP, selfPort, nextGenerator, currentUserEncryptedTallies, currentServerEncryptedTallies, bandwidthData);
 
     // Do the second half of the epoch calculations (breaking down values to their final values, to be given to users)
-    epoch_break_down(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, generatorProof, nextGenerator, civetServer, breakDownOutputMtx, breakDownOutputFilename, bandwidthData);
+    epoch_break_down(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, generatorProof, nextGenerator, civetServer, breakDownOutputMtx, breakDownOutputFilename, usageMtx, usageFilename, bandwidthData);
 
     // Indicate we are in a new epoch
     epochNum.fetch_add(1);
@@ -151,6 +153,7 @@ void make_epoch(
     bandwidthData[1] += bandwidthDataAfter[1] - bandwidthDataBefore[1];
 
     write_log_data(fullOutputMtx, fullOutputFilename, timingData, bandwidthData);
+    write_usage_data(usageMtx, usageFilename);
 }
 
 /*********************************************************
@@ -479,6 +482,8 @@ std::vector<Proof> epoch_build_up(
     const CivetServer& civetServer,
     std::mutex& outputMtx,
     const std::string& outputFilename,
+    std::mutex& usageMtx,
+    const std::string& usageFilename,
     std::vector<size_t>& overallBandwidthData)
 {
     std::vector<std::vector<std::vector<Proof>>> pi;
@@ -571,6 +576,7 @@ std::vector<Proof> epoch_build_up(
             bandwidthData[1] += serverBandwidthDataAfter[1] - serverBandwidthDataBefore[1];
 
             write_log_data(outputMtx, outputFilename, timingData, bandwidthData);
+            write_usage_data(usageMtx, usageFilename);
 
             // Keep an up-to-date version of the proof of the new fresh generator
             generatorProofHolder = pi[0];
@@ -601,6 +607,8 @@ void epoch_break_down(
     const CivetServer& civetServer,
     std::mutex& outputMtx,
     const std::string& outputFilename,
+    std::mutex& usageMtx,
+    const std::string& usageFilename,
     std::vector<size_t>& overallBandwidthData)
 {
     std::vector<std::vector<std::vector<Proof>>> pi;
@@ -690,6 +698,9 @@ void epoch_break_down(
 
             bandwidthData[0] += serverBandwidthDataAfter[0] - serverBandwidthDataBefore[0];
             bandwidthData[1] += serverBandwidthDataAfter[1] - serverBandwidthDataBefore[1];
+
+            write_log_data(outputMtx, outputFilename, timingData, bandwidthData);
+            write_usage_data(usageMtx, usageFilename);
         }
         else    // When it's another server's turn, tell them to do their part
         {
@@ -1538,8 +1549,10 @@ PrsonaServerWebSocketHandler::PrsonaServerWebSocketHandler(
     std::mutex& updateOutputMtx,
     const std::string& updateOutputFilename,
     std::mutex& voteOutputMtx,
-    const std::string& voteOutputFilename)
-: rng(rng), prsonaServer(prsonaServer), serverIPs(serverIPs), serverPorts(serverPorts), selfIP(selfIP), selfPort(selfPort), updateMtx(updateMtx), epochNum(epochNum), buildUpOutputMtx(buildUpOutputMtx), buildUpOutputFilename(buildUpOutputFilename), breakDownOutputMtx(breakDownOutputMtx), breakDownOutputFilename(breakDownOutputFilename), updateOutputMtx(updateOutputMtx), updateOutputFilename(updateOutputFilename), voteOutputMtx(voteOutputMtx), voteOutputFilename(voteOutputFilename)
+    const std::string& voteOutputFilename,
+    std::mutex& usageMtx,
+    const std::string& usageFilename)
+: rng(rng), prsonaServer(prsonaServer), serverIPs(serverIPs), serverPorts(serverPorts), selfIP(selfIP), selfPort(selfPort), updateMtx(updateMtx), epochNum(epochNum), buildUpOutputMtx(buildUpOutputMtx), buildUpOutputFilename(buildUpOutputFilename), breakDownOutputMtx(breakDownOutputMtx), breakDownOutputFilename(breakDownOutputFilename), updateOutputMtx(updateOutputMtx), updateOutputFilename(updateOutputFilename), voteOutputMtx(voteOutputMtx), voteOutputFilename(voteOutputFilename), usageMtx(usageMtx), usageFilename(usageFilename)
 { /* */ }
 
 /*
@@ -2231,6 +2244,7 @@ void PrsonaServerWebSocketHandler::receive_vote(
     bandwidthData[1] += bandwidthDataAfter[1] - bandwidthDataBefore[1];
 
     write_log_data(voteOutputMtx, voteOutputFilename, timingData, bandwidthData);
+    write_usage_data(usageMtx, usageFilename);
 
     // Notify client their request has been completed
     mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);
@@ -2632,6 +2646,7 @@ void PrsonaServerWebSocketHandler::build_up_midway_pseudonyms(
     bandwidthData[1] += serverBandwidthDataAfter[1] - serverBandwidthDataBefore[1];
 
     write_log_data(buildUpOutputMtx, buildUpOutputFilename, timingData, bandwidthData);
+    write_usage_data(usageMtx, usageFilename);
     
     // Serialize response
     data = make_epoch_initiator_string(pi[0][0], nextGenerator);
@@ -2720,6 +2735,7 @@ void PrsonaServerWebSocketHandler::break_down_midway_pseudonyms(
     bandwidthData[1] += serverBandwidthDataAfter[1] - serverBandwidthDataBefore[1];
 
     write_log_data(breakDownOutputMtx, breakDownOutputFilename, timingData, bandwidthData);
+    write_usage_data(usageMtx, usageFilename);
 
     // Keep our epoch value up-to-date
     epochNum.fetch_add(1);
@@ -2769,6 +2785,7 @@ void PrsonaServerWebSocketHandler::accept_epoch_updates(
     bandwidthData[1] = bandwidthDataAfter[1] - bandwidthDataBefore[1];
 
     write_log_data(updateOutputMtx, updateOutputFilename, timingData, bandwidthData);
+    write_usage_data(usageMtx, usageFilename);
 
     // Acknowledge receipt of request
     mg_websocket_write(conn, MG_WEBSOCKET_OPCODE_DATACOMPLETE, "", 0);

+ 29 - 0
prsona/src/networking.cpp

@@ -158,6 +158,18 @@ void write_log_data(
     fclose(outputFile);
 }
 
+void write_usage_data(
+    std::mutex& outputMtx,
+    const std::string& outputFilename)
+{
+    std::unique_lock<std::mutex> lck(outputMtx);
+
+    FILE *outputFile = fopen(outputFilename.c_str(), "a");
+    unsigned long vsize = mem_usage();
+    fprintf(outputFile, "%lu\n", vsize);
+    fclose(outputFile);
+}
+
 /***********************************************************
  ****                                                   ****
  ****  "private" functions to help the generic helpers  ****
@@ -205,6 +217,23 @@ size_t parse_log_for_data(const char *input, const char *key)
     return retval;
 }
 
+unsigned long mem_usage()
+{
+    std::ifstream stat_stream("/proc/self/stat", std::ios_base::in);
+    std::string pid, comm, state, ppid, pgrp, session, tty_nr, tpgid, flags,
+            minflt, cminflt, majflt, cmajflt, utime, stime, cutime, cstime,
+            priority, nice, O, itrealvalue, starttime;
+    unsigned long vsize;
+    
+    stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
+                >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
+                >> utime >> stime >> cutime >> cstime >> priority >> nice
+                >> O >> itrealvalue >> starttime >> vsize;
+    stat_stream.close();
+
+    return vsize;
+}
+
 /***************************************
  ****                               ****
  ****  websocket handler functions  ****

+ 4 - 2
prsona/src/serverMain.cpp

@@ -62,6 +62,8 @@ int main(int argc, char *argv[])
     string voteUpdateOutputFilename = outputDir + "/voteUpdate.out";
     mutex fullEpochOutputMtx;
     string fullEpochOutputFilename = outputDir + "/overallEpoch.out";
+    mutex memUsageOutputMtx;
+    string memUsageOutputFilename = outputDir + "/usage.out";
 
     // Default to no proof batching if not specified
     size_t lambda = 0;
@@ -148,7 +150,7 @@ int main(int argc, char *argv[])
     cout << "[" << seedStr << "] Setting up handlers for server." << endl;
 
     // Main handler
-    PrsonaServerWebSocketHandler wsHandler(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, updateMtx, epochNum, epochBuildUpOutputMtx, epochBuildUpOutputFilename, epochBreakDownOutputMtx, epochBreakDownOutputFilename, epochUpdateOutputMtx, epochUpdateOutputFilename, voteUpdateOutputMtx, voteUpdateOutputFilename);
+    PrsonaServerWebSocketHandler wsHandler(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, updateMtx, epochNum, epochBuildUpOutputMtx, epochBuildUpOutputFilename, epochBreakDownOutputMtx, epochBreakDownOutputFilename, epochUpdateOutputMtx, epochUpdateOutputFilename, voteUpdateOutputMtx, voteUpdateOutputFilename, memUsageOutputMtx, memUsageOutputFilename);
     server.addWebSocketHandler("/ws", wsHandler);
 
     // Exit handler (allows server to be brought down by making correct GET request)
@@ -223,7 +225,7 @@ int main(int argc, char *argv[])
             {
                 size_t currEpoch = epochNum.load();
                 cout << "[" << seedStr << "] Executing epoch calculations (going from t = " << currEpoch << " to " << currEpoch + 1 << ")." << endl;
-                make_epoch(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, updateMtx, epochNum, server, epochBuildUpOutputMtx, epochBuildUpOutputFilename, epochBreakDownOutputMtx, epochBreakDownOutputFilename, fullEpochOutputMtx, fullEpochOutputFilename);
+                make_epoch(rng, prsonaServer, serverIPs, serverPorts, selfIP, selfPort, updateMtx, epochNum, server, epochBuildUpOutputMtx, epochBuildUpOutputFilename, epochBreakDownOutputMtx, epochBreakDownOutputFilename, fullEpochOutputMtx, fullEpochOutputFilename, memUsageOutputMtx, memUsageOutputFilename);
                 currEpoch = epochNum.load();
                 cout << "[" << seedStr << "] Epoch calculations complete (now in t = " << currEpoch << ")." << endl;
             }