From e4c7d2fa8c09ec777e9298d28f7d166429396bfd Mon Sep 17 00:00:00 2001
From: Fons Rademakers <Fons.Rademakers@cern.ch>
Date: Tue, 2 Nov 2010 13:23:08 +0000
Subject: [PATCH] From Gerri: add the possibility to control the resident and
 virtual memory of a proofserv using 'ulimit', which has less limitations and
 more flexibility than setrlimit.

git-svn-id: http://root.cern.ch/svn/root/trunk@36475 27541ba8-7e3a-0410-8455-c3a389f83636
---
 config/proofserv.in                    | 22 ++++++++++++++++++++++
 proof/proof/inc/TProofServ.h           |  4 ++++
 proof/proof/src/TProofServ.cxx         | 12 ++++++++++++
 proof/proofplayer/src/TProofPlayer.cxx |  4 ++--
 4 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/config/proofserv.in b/config/proofserv.in
index aa7c265bfb6..17b292a0eb9 100644
--- a/config/proofserv.in
+++ b/config/proofserv.in
@@ -70,6 +70,28 @@ else
    fi
 fi
 
+# Apply limit on the resident memory, if requested
+ECHOMEM=""
+if [ "x$PROOF_RESMEMMAX" != "x" ]; then
+   resmemmax=`expr $PROOF_RESMEMMAX \* 1024`
+   ulimit -m $resmemmax
+   ECHOMEM="yes"
+fi
+# Apply limit on the virtual memory, if requested
+if [ "x$PROOF_VIRTMEMMAX" != "x" -o  "x$ROOTPROOFASHARD" != "x" ]; then
+   if [ "x$PROOF_VIRTMEMMAX" != "x" ]; then
+      virmemmax=`expr $PROOF_VIRTMEMMAX \* 1024`
+   else
+      virmemmax=`expr $ROOTPROOFASHARD \* 1024`
+   fi
+   ulimit -v $virmemmax
+   ECHOMEM="yes"
+fi
+if [ "x$ECHOMEM" != "x" ]; then
+   NOW=`date +%H:%M:%S`
+   echo "$NOW: $1: limiting {resident, virtual} memory to {$resmemmax,$virmemmax} kBytes" >> $LOGFILE
+fi
+
 if [ "x$WRAPPER" != "x" ]; then
    NOW=`date +%H:%M:%S`
    echo "$NOW: $1: executing $WRAPPER @bindir@/proofserv.exe $@" >> $LOGFILE
diff --git a/proof/proof/inc/TProofServ.h b/proof/proof/inc/TProofServ.h
index b43a99ce9ef..3591ac996c3 100644
--- a/proof/proof/inc/TProofServ.h
+++ b/proof/proof/inc/TProofServ.h
@@ -164,6 +164,8 @@ private:
    // Memory limits (-1 to disable) set by envs ROOTPROOFASSOFT and RPPTPROFOASHARD
    Long_t        fVirtMemHWM;       //Above this we terminate gently (in kB)
    Long_t        fVirtMemMax;       //Hard limit enforced by the system (in kB)
+   Long_t        fResMemMax;        //Hard limit on the resident memory checked
+                                    //in TProofPlayer::Process (in kB)
 
    // In bytes; default is 1MB
    Long64_t      fMsgSizeHWM;       //High-Water-Mark on the size of messages with results
@@ -266,6 +268,8 @@ public:
    Int_t          GetInflateFactor() const { return fInflateFactor; }
 
    Long_t         GetVirtMemHWM() const { return fVirtMemHWM; }
+   Long_t         GetVirtMemMax() const { return fVirtMemMax; }
+   Long_t         GetResMemMax() const { return fResMemMax; }
 
    Long64_t       GetMsgSizeHWM() const { return fMsgSizeHWM; }
 
diff --git a/proof/proof/src/TProofServ.cxx b/proof/proof/src/TProofServ.cxx
index 1adb8d8b802..e60168963f5 100644
--- a/proof/proof/src/TProofServ.cxx
+++ b/proof/proof/src/TProofServ.cxx
@@ -539,6 +539,18 @@ TProofServ::TProofServ(Int_t *argc, char **argv, FILE *flog)
       if (mmx < kMaxLong && mmx > 0)
          fVirtMemMax = mmx * 1024;
    }
+   if (gSystem->Getenv("PROOF_VIRTMEMMAX")) {
+      Long_t mmx = strtol(gSystem->Getenv("PROOF_VIRTMEMMAX"), 0, 10);
+      if (mmx < kMaxLong && mmx > 0)
+         fVirtMemMax = mmx * 1024;
+   }
+   // Upper limit on Resident Memory (in kB)
+   fResMemMax = gEnv->GetValue("Proof.ResMemMax",-1);
+   if (fResMemMax < 0 && gSystem->Getenv("PROOF_RESMEMMAX")) {
+      Long_t mmx = strtol(gSystem->Getenv("PROOF_RESMEMMAX"), 0, 10);
+      if (mmx < kMaxLong && mmx > 0)
+         fResMemMax = mmx * 1024;
+   }
 
    // Wait (loop) to allow debugger to connect
    Bool_t test = (*argc >= 4 && !strcmp(argv[3], "test")) ? kTRUE : kFALSE;
diff --git a/proof/proofplayer/src/TProofPlayer.cxx b/proof/proofplayer/src/TProofPlayer.cxx
index 3258fd297f3..d2e0705f383 100644
--- a/proof/proofplayer/src/TProofPlayer.cxx
+++ b/proof/proofplayer/src/TProofPlayer.cxx
@@ -849,10 +849,10 @@ Long64_t TProofPlayer::Process(TDSet *dset, const char *selector_file,
    Long64_t entry;
    fProgressStatus->Reset();
 
-   // Get the frequency for logging memory consumption information
+   // Get the frequency for checking memory consumption and logging information
    TParameter<Long64_t> *par = (TParameter<Long64_t>*)fInput->FindObject("PROOF_MemLogFreq");
    volatile Long64_t memlogfreq = (par) ? par->GetVal() : 100;
-   volatile Long_t memlim = (gProofServ) ? gProofServ->GetVirtMemHWM() : -1;
+   volatile Long_t memlim = gProofServ ? gProofServ->GetVirtMemMax() : -1;
    volatile Bool_t warn80 = kTRUE;
 
    TRY {
-- 
GitLab