| 1 | #include "sopnamsp.h"
 | 
|---|
| 2 | #include "resusage.h"
 | 
|---|
| 3 | 
 | 
|---|
| 4 | #include <typeinfo>
 | 
|---|
| 5 | #include <sys/types.h>
 | 
|---|
| 6 | #include <sys/time.h>
 | 
|---|
| 7 | #include <sys/stat.h>
 | 
|---|
| 8 | #include <sys/resource.h>
 | 
|---|
| 9 | #include <unistd.h>
 | 
|---|
| 10 | #include <time.h>
 | 
|---|
| 11 | #include <fcntl.h>
 | 
|---|
| 12 | #include <fstream>
 | 
|---|
| 13 | #include <stdio.h>
 | 
|---|
| 14 | #include <string>
 | 
|---|
| 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. 
 | 
|---|
| 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
 | 
|---|
| 36 | */
 | 
|---|
| 37 | /*!
 | 
|---|
| 38 |   Constructor. the \b Update() method is called.
 | 
|---|
| 39 |   \param pg: Process group RU_Self or RU_Children or RU_All
 | 
|---|
| 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
 | 
|---|
| 43 | */
 | 
|---|
| 44 | ResourceUsage::ResourceUsage(RU_ProcGrp pg)
 | 
|---|
| 45 | {
 | 
|---|
| 46 |   procgrp = pg;
 | 
|---|
| 47 |   struct rlimit rl;
 | 
|---|
| 48 |   getrlimit(RLIMIT_DATA, &rl);
 | 
|---|
| 49 |   max_datasz = rl.rlim_cur/1024;
 | 
|---|
| 50 | #if defined(SunOS)
 | 
|---|
| 51 |   // Max resident size ne semble pas etre defini sur SunOS
 | 
|---|
| 52 |   max_rss = max_datasz; 
 | 
|---|
| 53 | #else
 | 
|---|
| 54 |   getrlimit(RLIMIT_RSS, &rl);
 | 
|---|
| 55 |   max_rss = rl.rlim_cur/1024;
 | 
|---|
| 56 | #endif
 | 
|---|
| 57 |   getrlimit(RLIMIT_STACK, &rl);
 | 
|---|
| 58 |   max_stack = rl.rlim_cur/1024;
 | 
|---|
| 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
 | 
|---|
| 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;
 | 
|---|
| 77 |   cur_pid = getpid();
 | 
|---|
| 78 |   Update();
 | 
|---|
| 79 |   
 | 
|---|
| 80 | }
 | 
|---|
| 81 | /*!
 | 
|---|
| 82 |    Destructor.
 | 
|---|
| 83 | */
 | 
|---|
| 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 | 
 | 
|---|
| 94 | /*!
 | 
|---|
| 95 |   Update the CPU and memory usage information.
 | 
|---|
| 96 | */
 | 
|---|
| 97 | int ResourceUsage::Update()
 | 
|---|
| 98 | {
 | 
|---|
| 99 |   struct rusage rsu;
 | 
|---|
| 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 | 
 | 
|---|
| 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);
 | 
|---|
| 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 |   }
 | 
|---|
| 116 |   cur_tottm = cur_usrtm+cur_systm;
 | 
|---|
| 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
 | 
|---|
| 123 |   cur_rss = rsu.ru_maxrss;
 | 
|---|
| 124 |   cur_datasz = rsu.ru_idrss;
 | 
|---|
| 125 |   cur_stack = rsu.ru_isrss;
 | 
|---|
| 126 | #endif
 | 
|---|
| 127 | 
 | 
|---|
| 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 | 
 | 
|---|
| 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 | */
 | 
|---|
| 144 | void ResourceUsage::Print(ostream& os, int lp, bool upd) 
 | 
|---|
| 145 | {
 | 
|---|
| 146 |   if (upd) Update();
 | 
|---|
| 147 |   os << " --------------- ResourceUsage::Print(lp=" << lp 
 | 
|---|
| 148 |      <<" ) --------------- " << endl;
 | 
|---|
| 149 |   int load = (int)(getAverageCPULoad()*100.);
 | 
|---|
| 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 | }
 | 
|---|
| 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,500); // 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 | }
 | 
|---|