File indexing completed on 2024-04-06 12:13:05
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <cstring>
0018 #include <cassert>
0019 #include <iostream>
0020 #ifdef __linux__
0021 #include <malloc.h>
0022 #endif
0023 #include <sstream>
0024
0025 #include <string>
0026
0027 #include <fcntl.h>
0028 #include <unistd.h>
0029
0030 #include "FWCore/Services/plugins/ProcInfoFetcher.h"
0031 #include "FWCore/Utilities/interface/EDMException.h"
0032 #include "FWCore/Utilities/interface/get_underlying_safe.h"
0033 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 namespace {
0044 struct linux_proc {
0045 int pid;
0046 std::string comm;
0047 char state;
0048 int ppid;
0049 int pgrp;
0050 int session;
0051 int tty;
0052 int tpgid;
0053 unsigned int flags;
0054 unsigned long minflt;
0055 unsigned long cminflt;
0056 unsigned long majflt;
0057 unsigned long cmajflt;
0058 unsigned long utime;
0059 unsigned long stime;
0060 long cutime;
0061 long cstime;
0062 long priority;
0063 long nice;
0064 long num_threads;
0065 long itrealvalue;
0066 unsigned long long starttime;
0067 unsigned long vsize;
0068 long rss;
0069 unsigned long rlim;
0070 unsigned long startcode;
0071 unsigned long endcode;
0072 unsigned long startstack;
0073 unsigned long kstkesp;
0074 unsigned long kstkeip;
0075 unsigned long signal;
0076 unsigned long blocked;
0077 unsigned long sigignore;
0078 unsigned long sigcatch;
0079 unsigned long wchan;
0080 };
0081
0082 class Fetcher {
0083 public:
0084 friend Fetcher& operator>>(Fetcher&, int&);
0085 friend Fetcher& operator>>(Fetcher&, long&);
0086 friend Fetcher& operator>>(Fetcher&, unsigned int&);
0087 friend Fetcher& operator>>(Fetcher&, unsigned long&);
0088 friend Fetcher& operator>>(Fetcher&, unsigned long long&);
0089 friend Fetcher& operator>>(Fetcher&, char&);
0090 friend Fetcher& operator>>(Fetcher&, std::string&);
0091
0092 explicit Fetcher(char* buffer) : buffer_(buffer), save_(nullptr), delims_(" \t\n\f\v\r") {}
0093
0094 private:
0095 int getInt() {
0096 const char* t = getItem();
0097
0098 return std::stoi(t);
0099 }
0100 long getLong() {
0101 const char* t = getItem();
0102
0103 return std::stol(t);
0104 }
0105 unsigned int getUInt() {
0106 const char* t = getItem();
0107
0108 return std::stoul(t);
0109 }
0110 unsigned long getULong() {
0111 const char* t = getItem();
0112
0113 return std::stoul(t);
0114 }
0115 unsigned long long getULongLong() {
0116 const char* t = getItem();
0117
0118 return std::stoull(t);
0119 }
0120 char getChar() { return *getItem(); }
0121 std::string getString() { return std::string(getItem()); }
0122 char* getItem() {
0123 char* item = strtok_r(buffer_, delims_, &save());
0124 assert(item);
0125 buffer_ = nullptr;
0126 return item;
0127 }
0128
0129 char const* save() const { return get_underlying_safe(save_); }
0130 char*& save() { return get_underlying_safe(save_); }
0131
0132 edm::propagate_const<char*> buffer_;
0133 edm::propagate_const<char*> save_;
0134 char const* const delims_;
0135 };
0136
0137 Fetcher& operator>>(Fetcher& iFetch, int& oValue) {
0138 oValue = iFetch.getInt();
0139 return iFetch;
0140 }
0141 Fetcher& operator>>(Fetcher& iFetch, long& oValue) {
0142 oValue = iFetch.getLong();
0143 return iFetch;
0144 }
0145 Fetcher& operator>>(Fetcher& iFetch, unsigned int& oValue) {
0146 oValue = iFetch.getUInt();
0147 return iFetch;
0148 }
0149 Fetcher& operator>>(Fetcher& iFetch, unsigned long& oValue) {
0150 oValue = iFetch.getULong();
0151 return iFetch;
0152 }
0153 Fetcher& operator>>(Fetcher& iFetch, unsigned long long& oValue) {
0154 oValue = iFetch.getULongLong();
0155 return iFetch;
0156 }
0157 Fetcher& operator>>(Fetcher& iFetch, char& oValue) {
0158 oValue = iFetch.getChar();
0159 return iFetch;
0160 }
0161 Fetcher& operator>>(Fetcher& iFetch, std::string& oValue) {
0162 oValue = iFetch.getString();
0163 return iFetch;
0164 }
0165 }
0166
0167 namespace edm {
0168 namespace service {
0169
0170 ProcInfoFetcher::ProcInfoFetcher() : pg_size_(sysconf(_SC_PAGESIZE)) {
0171 #ifdef __linux__
0172 std::ostringstream ost;
0173 ost << "/proc/" << getpid() << "/stat";
0174
0175 if ((fd_ = open(ost.str().c_str(), O_RDONLY)) < 0) {
0176 throw Exception(errors::Configuration) << "Failed to open " << ost.str() << std::endl;
0177 }
0178 #endif
0179 }
0180 ProcInfoFetcher::~ProcInfoFetcher() {
0181 #ifdef LINUX
0182 close(fd_);
0183 #endif
0184 }
0185 ProcInfo ProcInfoFetcher::fetch() const {
0186 ProcInfo ret;
0187
0188 #ifdef __linux__
0189 double pr_size = 0.0, pr_rssize = 0.0;
0190
0191 linux_proc pinfo;
0192 int cnt;
0193
0194 lseek(fd_, 0, SEEK_SET);
0195
0196 if ((cnt = read(fd_, buf_, sizeof(buf_) - 1)) < 0) {
0197 perror("Read of Proc file failed:");
0198 return ProcInfo();
0199 }
0200
0201 if (cnt > 0) {
0202 buf_[cnt] = '\0';
0203
0204 try {
0205 Fetcher fetcher(buf_);
0206 fetcher >> pinfo.pid >> pinfo.comm >> pinfo.state >> pinfo.ppid >> pinfo.pgrp >> pinfo.session >> pinfo.tty >>
0207 pinfo.tpgid >> pinfo.flags >> pinfo.minflt >> pinfo.cminflt >> pinfo.majflt >> pinfo.cmajflt >>
0208 pinfo.utime >> pinfo.stime >> pinfo.cutime >> pinfo.cstime >> pinfo.priority >> pinfo.nice >>
0209 pinfo.num_threads >> pinfo.itrealvalue >> pinfo.starttime >> pinfo.vsize >> pinfo.rss >> pinfo.rlim >>
0210 pinfo.startcode >> pinfo.endcode >> pinfo.startstack >> pinfo.kstkesp >> pinfo.kstkeip >> pinfo.signal >>
0211 pinfo.blocked >> pinfo.sigignore >> pinfo.sigcatch >> pinfo.wchan;
0212 } catch (const std::exception& iE) {
0213 LogWarning("ProcInfoFetcher") << "Parsing of Prof file failed:" << iE.what() << std::endl;
0214 return ProcInfo();
0215 }
0216
0217
0218 pr_size = (double)pinfo.vsize;
0219 pr_rssize = (double)pinfo.rss;
0220
0221 ret.vsize = pr_size / (1024.0 * 1024.0);
0222 ret.rss = (pr_rssize * pg_size_) / (1024.0 * 1024.0);
0223 }
0224 #else
0225 ret.vsize = 0;
0226 ret.rss = 0;
0227 #endif
0228 return ret;
0229 }
0230 }
0231 }