Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <cstring>
00019 #include <cassert>
00020 #include <iostream>
00021 #ifdef __linux__
00022 #include <malloc.h>
00023 #endif
00024 #include <sstream>
00025
00026 #include <string>
00027 #include <boost/lexical_cast.hpp>
00028
00029 #include <fcntl.h>
00030 #include <unistd.h>
00031
00032 #include "FWCore/Services/src/ProcInfoFetcher.h"
00033 #include "FWCore/Utilities/interface/EDMException.h"
00034 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 namespace {
00046 struct linux_proc {
00047 int pid;
00048 std::string comm;
00049 char state;
00050 int ppid;
00051 int pgrp;
00052 int session;
00053 int tty;
00054 int tpgid;
00055 unsigned long flags;
00056 unsigned long minflt;
00057 unsigned long cminflt;
00058 unsigned long majflt;
00059 unsigned long cmajflt;
00060 unsigned long utime;
00061 unsigned long stime;
00062 long cutime;
00063 long cstime;
00064 long priority;
00065 long nice;
00066 long num_threads;
00067 long itrealvalue;
00068 int starttime;
00069 unsigned long vsize;
00070 long rss;
00071 unsigned long rlim;
00072 unsigned long startcode;
00073 unsigned long endcode;
00074 unsigned long startstack;
00075 unsigned long kstkesp;
00076 unsigned long kstkeip;
00077 unsigned long signal;
00078 unsigned long blocked;
00079 unsigned long sigignore;
00080 unsigned long sigcatch;
00081 unsigned long wchan;
00082 };
00083
00084 class Fetcher {
00085 public:
00086 friend Fetcher& operator>>(Fetcher&, int&);
00087 friend Fetcher& operator>>(Fetcher&, long&);
00088 friend Fetcher& operator>>(Fetcher&, unsigned int&);
00089 friend Fetcher& operator>>(Fetcher&, unsigned long&);
00090 friend Fetcher& operator>>(Fetcher&, char&);
00091 friend Fetcher& operator>>(Fetcher&, std::string&);
00092
00093 explicit Fetcher(char* buffer) :
00094 buffer_(buffer),
00095 save_(0),
00096 delims_(" \t\n\f\v\r") {
00097 }
00098 private:
00099 int getInt() {
00100 const char* t = getItem();
00101
00102 return boost::lexical_cast<int>(t);
00103 }
00104 long getLong() {
00105 const char* t = getItem();
00106
00107 return boost::lexical_cast<long>(t);
00108 }
00109 unsigned int getUInt() {
00110 const char* t = getItem();
00111
00112 return boost::lexical_cast<unsigned int>(t);
00113 }
00114 unsigned long getULong() {
00115 const char* t = getItem();
00116
00117 return boost::lexical_cast<unsigned long>(t);
00118 }
00119 char getChar() {
00120 return *getItem();
00121 }
00122 std::string getString() {
00123 return std::string(getItem());
00124 }
00125 char* getItem() {
00126 char* item = strtok_r(buffer_, delims_, &save_);
00127 assert(item);
00128 buffer_ = 0;
00129 return item;
00130 }
00131 char* buffer_;
00132 char* save_;
00133 char const* const delims_;
00134 };
00135
00136 Fetcher& operator>>(Fetcher& iFetch, int& oValue) {
00137 oValue = iFetch.getInt();
00138 return iFetch;
00139 }
00140 Fetcher& operator>>(Fetcher& iFetch, long& oValue) {
00141 oValue = iFetch.getLong();
00142 return iFetch;
00143 }
00144 Fetcher& operator>>(Fetcher& iFetch, unsigned int& oValue) {
00145 oValue = iFetch.getUInt();
00146 return iFetch;
00147 }
00148 Fetcher& operator>>(Fetcher& iFetch, unsigned long& oValue) {
00149 oValue = iFetch.getULong();
00150 return iFetch;
00151 }
00152 Fetcher& operator>>(Fetcher& iFetch, char& oValue) {
00153 oValue = iFetch.getChar();
00154 return iFetch;
00155 }
00156 Fetcher& operator>>(Fetcher& iFetch, std::string& oValue) {
00157 oValue = iFetch.getString();
00158 return iFetch;
00159 }
00160 }
00161
00162 namespace edm {
00163 namespace service {
00164
00165 ProcInfoFetcher::ProcInfoFetcher():
00166 pg_size_(sysconf(_SC_PAGESIZE)) {
00167 #ifdef __linux__
00168 std::ostringstream ost;
00169 ost << "/proc/" << getpid() << "/stat";
00170
00171 if((fd_ = open(ost.str().c_str(), O_RDONLY)) < 0) {
00172 throw Exception(errors::Configuration)
00173 << "Failed to open " << ost.str() << std::endl;
00174 }
00175 #endif
00176 }
00177 ProcInfoFetcher::~ProcInfoFetcher() {
00178 #ifdef LINUX
00179 close(fd_);
00180 #endif
00181 }
00182 ProcInfo ProcInfoFetcher::fetch() const {
00183 ProcInfo ret;
00184
00185 #ifdef __linux__
00186 double pr_size = 0.0, pr_rssize = 0.0;
00187
00188 linux_proc pinfo;
00189 int cnt;
00190
00191 lseek(fd_, 0, SEEK_SET);
00192
00193 if((cnt = read(fd_, buf_, sizeof(buf_) - 1)) < 0) {
00194 perror("Read of Proc file failed:");
00195 return ProcInfo();
00196 }
00197
00198 if(cnt > 0) {
00199 buf_[cnt] = '\0';
00200
00201
00202 try {
00203 Fetcher fetcher(buf_);
00204 fetcher >> pinfo.pid
00205 >> pinfo.comm
00206 >> pinfo.state
00207 >> pinfo.ppid
00208 >> pinfo.pgrp
00209 >> pinfo.session
00210 >> pinfo.tty
00211 >> pinfo.tpgid
00212 >> pinfo.flags
00213 >> pinfo.minflt
00214 >> pinfo.cminflt
00215 >> pinfo.majflt
00216 >> pinfo.cmajflt
00217 >> pinfo.utime
00218 >> pinfo.stime
00219 >> pinfo.cutime
00220 >> pinfo.cstime
00221 >> pinfo.priority
00222 >> pinfo.nice
00223 >> pinfo.num_threads
00224 >> pinfo.itrealvalue
00225 >> pinfo.starttime
00226 >> pinfo.vsize
00227 >> pinfo.rss
00228 >> pinfo.rlim
00229 >> pinfo.startcode
00230 >> pinfo.endcode
00231 >> pinfo.startstack
00232 >> pinfo.kstkesp
00233 >> pinfo.kstkeip
00234 >> pinfo.signal
00235 >> pinfo.blocked
00236 >> pinfo.sigignore
00237 >> pinfo.sigcatch
00238 >> pinfo.wchan;
00239 } catch (boost::bad_lexical_cast& iE) {
00240 LogWarning("ProcInfoFetcher")<<"Parsing of Prof file failed:"<<iE.what()<<std::endl;
00241 return ProcInfo();
00242 }
00243
00244
00245 pr_size = (double)pinfo.vsize;
00246 pr_rssize = (double)pinfo.rss;
00247
00248 ret.vsize = pr_size / (1024.0*1024.0);
00249 ret.rss = (pr_rssize * pg_size_) / (1024.0*1024.0);
00250 }
00251 #else
00252 ret.vsize = 0;
00253 ret.rss = 0;
00254 #endif
00255 return ret;
00256 }
00257 }
00258 }