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