| [2615] | 1 | #include "sopnamsp.h"
 | 
|---|
| [2101] | 2 | #include "resusage.h"
 | 
|---|
 | 3 | 
 | 
|---|
| [2255] | 4 | #include <typeinfo>
 | 
|---|
| [2101] | 5 | #include <sys/types.h>
 | 
|---|
 | 6 | #include <sys/time.h>
 | 
|---|
| [2255] | 7 | #include <sys/stat.h>
 | 
|---|
| [2101] | 8 | #include <sys/resource.h>
 | 
|---|
 | 9 | #include <unistd.h>
 | 
|---|
 | 10 | #include <time.h>
 | 
|---|
| [2255] | 11 | #include <fcntl.h>
 | 
|---|
| [2322] | 12 | #include <fstream>
 | 
|---|
| [2255] | 13 | #include <stdio.h>
 | 
|---|
 | 14 | #include <string>
 | 
|---|
| [2101] | 15 | /*!
 | 
|---|
 | 16 |   \class SOPHYA::ResourceUsage
 | 
|---|
 | 17 |   \ingroup SysTools
 | 
|---|
 | 18 |   This class gives acces to various system resource usage 
 | 
|---|
 | 19 |   (CPU, memory, ...).
 | 
|---|
 | 20 |   All returned values are in kilobytes for memory consumptions
 | 
|---|
 | 21 |   and in milli-seconds fo CPU and elapsed times.
 | 
|---|
 | 22 |   The information should be updated through the call to the 
 | 
|---|
 | 23 |   Update() method. 
 | 
|---|
| [2212] | 24 |   Note: The information is obtained through \c getrusage()   
 | 
|---|
 | 25 |   and \c getrlimit() system calls, and depending on the OS, 
 | 
|---|
 | 26 |   not all of the memory usage values are correctly filled.
 | 
|---|
 | 27 |   \code
 | 
|---|
 | 28 |   // How to check resource usage for a given part of the program
 | 
|---|
 | 29 |   ResourceUsage res;
 | 
|---|
 | 30 |   // --- Part of the program to be checked : Start
 | 
|---|
 | 31 |   // ...
 | 
|---|
 | 32 |   res.Update();
 | 
|---|
 | 33 |   cout << " Memory size increase (KB):" << res.getDeltaMemorySize() << endl;
 | 
|---|
 | 34 |   cout << " Resource usage info : \n" << res << endl;
 | 
|---|
 | 35 |   \endcode
 | 
|---|
| [2101] | 36 | */
 | 
|---|
| [2212] | 37 | /*!
 | 
|---|
 | 38 |   Constructor. the \b Update() method is called.
 | 
|---|
| [2487] | 39 |   \param pg: Process group RU_Self or RU_Children or RU_All
 | 
|---|
| [2598] | 40 |   - pg = RU_Self : Resource usage for the process itself
 | 
|---|
 | 41 |   - pg = RU_Children : Resource usage for the child processes
 | 
|---|
 | 42 |   - pg = RU_All : resource usage for the process itself and its child processes
 | 
|---|
| [2212] | 43 | */
 | 
|---|
| [2487] | 44 | ResourceUsage::ResourceUsage(RU_ProcGrp pg)
 | 
|---|
| [2101] | 45 | {
 | 
|---|
| [2487] | 46 |   procgrp = pg;
 | 
|---|
| [2101] | 47 |   struct rlimit rl;
 | 
|---|
 | 48 |   getrlimit(RLIMIT_DATA, &rl);
 | 
|---|
 | 49 |   max_datasz = rl.rlim_cur/1024;
 | 
|---|
| [2191] | 50 | #if defined(SunOS)
 | 
|---|
 | 51 |   // Max resident size ne semble pas etre defini sur SunOS
 | 
|---|
 | 52 |   max_rss = max_datasz; 
 | 
|---|
 | 53 | #else
 | 
|---|
| [2101] | 54 |   getrlimit(RLIMIT_RSS, &rl);
 | 
|---|
 | 55 |   max_rss = rl.rlim_cur/1024;
 | 
|---|
| [2191] | 56 | #endif
 | 
|---|
| [2101] | 57 |   getrlimit(RLIMIT_STACK, &rl);
 | 
|---|
 | 58 |   max_stack = rl.rlim_cur/1024;
 | 
|---|
| [2255] | 59 | #if defined(Linux)
 | 
|---|
 | 60 |   // recuperation des limites sous Linux 
 | 
|---|
 | 61 |   // car je ne comprends pas ce que renc=voie getrlimit
 | 
|---|
 | 62 |   // OPerdereau LAL Orsay  11/2002
 | 
|---|
 | 63 |   ReadLinuxTotMem();
 | 
|---|
 | 64 | #endif
 | 
|---|
| [2101] | 65 | 
 | 
|---|
 | 66 |   cur_datasz = 0;
 | 
|---|
 | 67 |   cur_stack = 0; 
 | 
|---|
 | 68 |   cur_rss = 0; 
 | 
|---|
 | 69 |   delta_rss = 0; 
 | 
|---|
 | 70 |   cur_tottm = 0;
 | 
|---|
 | 71 |   cur_usrtm = 0;
 | 
|---|
 | 72 |   cur_systm = 0;
 | 
|---|
 | 73 |   elapsed_time = 0;
 | 
|---|
 | 74 |   delta_rss = 0;
 | 
|---|
 | 75 |   delta_tottm = 0;
 | 
|---|
 | 76 |   delta_elapsed_time = 0;
 | 
|---|
| [2255] | 77 |   cur_pid = getpid();
 | 
|---|
| [2101] | 78 |   Update();
 | 
|---|
 | 79 |   
 | 
|---|
 | 80 | }
 | 
|---|
| [2212] | 81 | /*!
 | 
|---|
 | 82 |    Destructor.
 | 
|---|
 | 83 | */
 | 
|---|
| [2101] | 84 | ResourceUsage::~ResourceUsage()
 | 
|---|
 | 85 | {
 | 
|---|
 | 86 | }
 | 
|---|
 | 87 | 
 | 
|---|
 | 88 | inline uint_8 s_timeval2msec(struct timeval & tv)
 | 
|---|
 | 89 | { 
 | 
|---|
 | 90 |   uint_8 ret = tv.tv_sec; ret *= 1000; 
 | 
|---|
 | 91 |   ret += tv.tv_usec/1000; return(ret); 
 | 
|---|
 | 92 | }
 | 
|---|
 | 93 | 
 | 
|---|
| [2212] | 94 | /*!
 | 
|---|
 | 95 |   Update the CPU and memory usage information.
 | 
|---|
 | 96 | */
 | 
|---|
| [2101] | 97 | int ResourceUsage::Update()
 | 
|---|
 | 98 | {
 | 
|---|
 | 99 |   struct rusage rsu;
 | 
|---|
| [2487] | 100 |   int rc;
 | 
|---|
 | 101 |   if ((procgrp == RU_Self) || (procgrp == RU_All)) 
 | 
|---|
 | 102 |     rc = getrusage(RUSAGE_SELF, &rsu);
 | 
|---|
 | 103 |   else 
 | 
|---|
 | 104 |     rc = getrusage(RUSAGE_CHILDREN, &rsu);
 | 
|---|
 | 105 | 
 | 
|---|
| [2101] | 106 |   delta_tottm = cur_tottm;
 | 
|---|
 | 107 |   delta_rss = cur_rss;
 | 
|---|
 | 108 |   cur_usrtm = s_timeval2msec(rsu.ru_utime);
 | 
|---|
 | 109 |   cur_systm = s_timeval2msec(rsu.ru_stime);
 | 
|---|
| [2487] | 110 |   if (procgrp == RU_All) {
 | 
|---|
 | 111 |     struct rusage rsuch;
 | 
|---|
 | 112 |     rc = getrusage(RUSAGE_CHILDREN, &rsuch);
 | 
|---|
 | 113 |     cur_usrtm += s_timeval2msec(rsuch.ru_utime);
 | 
|---|
 | 114 |     cur_systm += s_timeval2msec(rsuch.ru_stime);    
 | 
|---|
 | 115 |   }
 | 
|---|
| [2101] | 116 |   cur_tottm = cur_usrtm+cur_systm;
 | 
|---|
| [2255] | 117 |   delta_tottm = cur_tottm-delta_tottm;
 | 
|---|
 | 118 | 
 | 
|---|
 | 119 | #if defined(Linux)
 | 
|---|
 | 120 |   // Recuperation de la place en memoire ss Linux 
 | 
|---|
 | 121 |   ReadLinuxMem();
 | 
|---|
 | 122 | #else
 | 
|---|
| [2101] | 123 |   cur_rss = rsu.ru_maxrss;
 | 
|---|
 | 124 |   cur_datasz = rsu.ru_idrss;
 | 
|---|
 | 125 |   cur_stack = rsu.ru_isrss;
 | 
|---|
| [2255] | 126 | #endif
 | 
|---|
 | 127 | 
 | 
|---|
| [2101] | 128 |   delta_rss = cur_rss-delta_rss;
 | 
|---|
 | 129 |   delta_elapsed_time = elapsed_time;
 | 
|---|
 | 130 |   time_t tm = time(NULL);
 | 
|---|
 | 131 |   if (elapsed_time == 0) t0_time = tm;
 | 
|---|
 | 132 |   elapsed_time = (tm - t0_time)*1000;
 | 
|---|
 | 133 |   if (elapsed_time < 1) elapsed_time = 1;
 | 
|---|
 | 134 |   delta_elapsed_time = elapsed_time-delta_elapsed_time;
 | 
|---|
 | 135 |   return(rc);
 | 
|---|
 | 136 | }
 | 
|---|
 | 137 | 
 | 
|---|
| [2212] | 138 | /*!
 | 
|---|
 | 139 |    Prints the CPU and memory usage information.
 | 
|---|
 | 140 |    \param os : The output stream
 | 
|---|
 | 141 |    \param lp : The print level (0 .. 2)
 | 
|---|
 | 142 |    \param upd : if \c true , the Update method is called.
 | 
|---|
 | 143 | */
 | 
|---|
| [2101] | 144 | void ResourceUsage::Print(ostream& os, int lp, bool upd) 
 | 
|---|
 | 145 | {
 | 
|---|
 | 146 |   if (upd) Update();
 | 
|---|
 | 147 |   os << " --------------- ResourceUsage::Print(lp=" << lp 
 | 
|---|
 | 148 |      <<" ) --------------- " << endl;
 | 
|---|
| [2487] | 149 |   int load = (int)(getAverageCPULoad()*100.);
 | 
|---|
| [2101] | 150 |   os << " CPU-Usage= " << getCPUTime() << " Elapsed= " << getElapsedTime()
 | 
|---|
 | 151 |      << " msec - Load= " << load << " %" << endl;
 | 
|---|
 | 152 |   long fracmem = getMemorySize()*100/getMaxMemorySize();
 | 
|---|
 | 153 |   os << " MemoryUsage= " << getMemorySize() << " /Max= " << getMaxMemorySize() 
 | 
|---|
 | 154 |      << " kbytes (" << fracmem << " %)" << endl;
 | 
|---|
 | 155 |   if (lp < 1) return;
 | 
|---|
 | 156 |   os << " CPU-Usage= " << cur_tottm << "ms (usr,sys)=(" 
 | 
|---|
 | 157 |      << cur_usrtm << "," << cur_systm << ")" << endl;
 | 
|---|
 | 158 |   os << "  DataSize=" << cur_datasz << " /Max " << max_datasz 
 | 
|---|
 | 159 |      << " kbytes" << endl;
 | 
|---|
 | 160 |   os << " StackSize=" << cur_stack  << " /Max " << max_stack 
 | 
|---|
 | 161 |      << " kbytes" << endl;
 | 
|---|
 | 162 |   os << "   ResSize=" << cur_rss  << " /Max " << max_rss 
 | 
|---|
 | 163 |      << " kbytes" << endl;
 | 
|---|
 | 164 | }
 | 
|---|
| [2255] | 165 | /*!
 | 
|---|
 | 166 |      Recuperation de la place en memoire ss Linux 
 | 
|---|
 | 167 |      ecrit d'apres les sources du code de top 
 | 
|---|
 | 168 |      O. Perdereau LAL Orsay 11/2002
 | 
|---|
 | 169 | 
 | 
|---|
 | 170 | */  
 | 
|---|
 | 171 | void ResourceUsage::ReadLinuxMem(){ 
 | 
|---|
 | 172 | 
 | 
|---|
 | 173 | #if defined(Linux)
 | 
|---|
 | 174 | 
 | 
|---|
 | 175 |   char flnm[120];
 | 
|---|
 | 176 |   
 | 
|---|
 | 177 |   sprintf(flnm,"/proc/%d/statm",(int)cur_pid);
 | 
|---|
 | 178 |   ifstream fich(flnm) ;
 | 
|---|
 | 179 | 
 | 
|---|
 | 180 |  
 | 
|---|
 | 181 |   long lia,lib,lic,lid,lie,lif,lig;
 | 
|---|
 | 182 |   
 | 
|---|
 | 183 |   fich >> lia >> lib >> lic >> lid >> lie >> lif >> lig ;
 | 
|---|
 | 184 | 
 | 
|---|
 | 185 |   cur_rss = lia*4; // les valeurs sont en pages de 4 k 
 | 
|---|
 | 186 |   cur_datasz = lib*4;
 | 
|---|
 | 187 |   cur_stack = lic*4;
 | 
|---|
 | 188 | 
 | 
|---|
 | 189 | #endif
 | 
|---|
 | 190 | 
 | 
|---|
 | 191 | }
 | 
|---|
 | 192 | 
 | 
|---|
 | 193 | 
 | 
|---|
 | 194 | /*! 
 | 
|---|
 | 195 |    Recuperation de la memoire dispo ss Linux 
 | 
|---|
 | 196 |    ecrit d'apres les sources du code de top 
 | 
|---|
 | 197 |    O. Perdereau LAL Orsay 11/2002
 | 
|---|
 | 198 | */
 | 
|---|
 | 199 | void ResourceUsage::ReadLinuxTotMem(){
 | 
|---|
 | 200 | #if defined(Linux)
 | 
|---|
 | 201 | 
 | 
|---|
 | 202 |   char flnm[]="/proc/meminfo";
 | 
|---|
 | 203 |   char buff[512];
 | 
|---|
 | 204 |   ifstream fich(flnm) ;
 | 
|---|
 | 205 | 
 | 
|---|
 | 206 |   fich.getline(buff,200); // on saute une ligne 
 | 
|---|
 | 207 | 
 | 
|---|
 | 208 |   string tst;
 | 
|---|
 | 209 |   long lia,lib,lic,lid,lie,lif;
 | 
|---|
 | 210 |   fich >> tst >> lia >> lib >> lic >> lid >> lie >> lif;
 | 
|---|
 | 211 | 
 | 
|---|
 | 212 |   max_rss = lia/1024; // conversion  en kbytes  
 | 
|---|
 | 213 | 
 | 
|---|
 | 214 | #endif
 | 
|---|
 | 215 | 
 | 
|---|
 | 216 | }
 | 
|---|