File indexing completed on 2025-01-30 09:17:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <DDG4/Geant4DetectorConstruction.h>
0017 #include <unistd.h>
0018
0019
0020
0021
0022 namespace dd4hep {
0023
0024
0025 namespace sim {
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 class Geant4DetectorConstructionResources : public Geant4DetectorConstruction {
0036 public:
0037
0038
0039
0040
0041
0042
0043 class __attribute__((__packed__)) StatusProcess {
0044 public:
0045 char comm[399];
0046 char state;
0047 int umask;
0048 int tgid;
0049 int ngid;
0050 int pid;
0051 int ppid;
0052 int uid;
0053 int gid;
0054 int utrace;
0055 int fdSize;
0056 long vmPeak;
0057 long vmSize;
0058 long vmLock;
0059 long vmPin;
0060 long vmHWM;
0061 long vmRSS;
0062 long vmRSSano;
0063 long vmRSSfil;
0064 long vmRSSshm;
0065 long vmData;
0066 long vmStack;
0067 long vmExe;
0068 long vmLib;
0069 long vmPTE;
0070 long vmSwap;
0071
0072 StatusProcess() {}
0073 };
0074 std::unique_ptr<StatusProcess> snapshot;
0075 std::string when { "geometry|sensitives" };
0076
0077 void print_status(const char* tag, const StatusProcess& sp) const;
0078
0079 public:
0080
0081 Geant4DetectorConstructionResources(Geant4Context* ctxt, const std::string& nam);
0082
0083 virtual ~Geant4DetectorConstructionResources();
0084
0085 virtual void constructGeo(Geant4DetectorConstructionContext*) override;
0086
0087 virtual void constructSensitives(Geant4DetectorConstructionContext* ctxt) override;
0088 };
0089 }
0090 }
0091
0092
0093
0094 #include <DD4hep/InstanceCount.h>
0095 #include <DD4hep/Printout.h>
0096 #include <DD4hep/Plugins.h>
0097 #include <DD4hep/Detector.h>
0098
0099 #include <DDG4/Geant4Mapping.h>
0100 #include <DDG4/Geant4Kernel.h>
0101 #include <DDG4/Factories.h>
0102
0103 #include <stdexcept>
0104 #include <sys/types.h>
0105 #include <sys/stat.h>
0106 #include <fcntl.h>
0107
0108 using namespace dd4hep::sim;
0109
0110 DECLARE_GEANT4ACTION(Geant4DetectorConstructionResources)
0111
0112 namespace {
0113
0114 class SysFile {
0115 public:
0116 class FileDescriptor {
0117
0118 int m_fd;
0119
0120 public:
0121
0122 FileDescriptor(int value) : m_fd(value) {}
0123
0124 ~FileDescriptor();
0125
0126 int get() const { return m_fd; }
0127 };
0128
0129
0130 public:
0131
0132 std::string m_name;
0133
0134 SysFile(const char* name) : m_name(name) {}
0135
0136 SysFile(const std::string& name) : m_name(name) {}
0137
0138 ~SysFile() {}
0139
0140 int read(char* buffer, size_t len) const;
0141 };
0142
0143
0144 SysFile::FileDescriptor::~FileDescriptor() {
0145 if (m_fd > 0) ::close(m_fd);
0146 m_fd = 0;
0147 }
0148
0149
0150 int SysFile::read(char* buf, size_t siz) const {
0151 FileDescriptor fd(::open(m_name.c_str(),O_RDONLY));
0152 if( fd.get() < 0 ) {
0153 std::string err = "Failed to open "+m_name+" ";
0154 throw std::runtime_error(err+std::make_error_code(std::errc(errno)).message());
0155 }
0156 std::size_t tmp = 0;
0157 while ( tmp < siz ) {
0158 int sc = ::read(fd.get(),buf+tmp,siz-tmp);
0159 if ( sc > 0 ) {
0160 tmp += sc;
0161 }
0162 else if ( sc == 0 ) {
0163 buf[tmp] = 0;
0164 return tmp;
0165 }
0166 else if ( errno == EINTR ) {
0167 printf("EINTR~!!!!\n");
0168 continue;
0169 }
0170 else {
0171 break;
0172 }
0173 }
0174 if ( tmp != siz ) {
0175 std::string err = "Read of system file "+m_name+" failed:";
0176 throw std::runtime_error(err+std::make_error_code(std::errc(errno)).message());
0177 }
0178 return tmp;
0179 }
0180
0181 int read_info(Geant4DetectorConstructionResources::StatusProcess& proc, int proc_id) {
0182 char buff[2048], *ptr=buff;
0183 std::string fn = "/proc/"+std::to_string(proc_id)+"/status";
0184 int nitem=0, cnt=SysFile(fn.c_str()).read(buff,sizeof(buff));
0185 if(cnt>0) {
0186 int ival;
0187 long int lval;
0188
0189 while(ptr && ptr<(buff+cnt)) {
0190 char* p = ::strchr(ptr,'\t');
0191 char* end = ::strchr(ptr,'\n');
0192
0193 ptr = (end) ? end+1 : 0;
0194 if ( 0 == p ) continue;
0195 ++p;
0196 switch(++nitem) {
0197 case 1: ::sscanf(p,"%s",proc.comm); break;
0198 case 2: ::sscanf(p,"%d",&ival); proc.umask = ival; break;
0199 case 3: ::sscanf(p,"%c",&proc.state); break;
0200 case 4: ::sscanf(p,"%d",&ival); proc.tgid = ival; break;
0201 case 5: ::sscanf(p,"%d",&ival); proc.ngid = ival; break;
0202 case 6: ::sscanf(p,"%d",&ival); proc.pid = ival; break;
0203 case 7: ::sscanf(p,"%d",&ival); proc.ppid = ival; break;
0204 case 8: ::sscanf(p,"%d",&ival); proc.utrace = ival; break;
0205 case 9: ::sscanf(p,"%d",&ival); proc.uid = ival; break;
0206 case 10: ::sscanf(p,"%d",&ival); proc.gid = ival; break;
0207 case 11: ::sscanf(p,"%d",&ival); proc.fdSize = ival; break;
0208 case 17: ::sscanf(p,"%ld",&lval); proc.vmPeak = lval; break;
0209 case 18: ::sscanf(p,"%ld",&lval); proc.vmSize = lval; break;
0210 case 19: ::sscanf(p,"%ld",&lval); proc.vmLock = lval; break;
0211 case 20: ::sscanf(p,"%ld",&lval); proc.vmPin = lval; break;
0212 case 21: ::sscanf(p,"%ld",&lval); proc.vmHWM = lval; break;
0213 case 22: ::sscanf(p,"%ld",&lval); proc.vmRSS = lval; break;
0214 case 23: ::sscanf(p,"%ld",&lval); proc.vmRSSano= lval; break;
0215 case 24: ::sscanf(p,"%ld",&lval); proc.vmRSSfil= lval; break;
0216 case 25: ::sscanf(p,"%ld",&lval); proc.vmRSSshm= lval; break;
0217 case 26: ::sscanf(p,"%ld",&lval); proc.vmData = lval; break;
0218 case 27: ::sscanf(p,"%ld",&lval); proc.vmStack = lval; break;
0219 case 28: ::sscanf(p,"%ld",&lval); proc.vmExe = lval; break;
0220 case 29: ::sscanf(p,"%ld",&lval); proc.vmLib = lval; break;
0221 case 30: ::sscanf(p,"%ld",&lval); proc.vmPTE = lval; break;
0222 case 31: ::sscanf(p,"%ld",&lval); proc.vmSwap = lval; break;
0223 case 32: return 1;
0224 default: break;
0225 }
0226 }
0227 return 1;
0228 }
0229 return 0;
0230 }
0231 }
0232
0233
0234 Geant4DetectorConstructionResources::Geant4DetectorConstructionResources(Geant4Context* ctxt, const std::string& nam)
0235 : Geant4DetectorConstruction(ctxt,nam)
0236 {
0237 declareProperty("When", this->when);
0238 InstanceCount::increment(this);
0239 }
0240
0241
0242 Geant4DetectorConstructionResources::~Geant4DetectorConstructionResources() {
0243 InstanceCount::decrement(this);
0244 }
0245
0246
0247 void Geant4DetectorConstructionResources::constructGeo(Geant4DetectorConstructionContext*) {
0248 if ( this->when.find("geometry") != std::string::npos ) {
0249 this->snapshot = std::make_unique<StatusProcess>();
0250 read_info(*this->snapshot, ::getpid());
0251 this->print_status("ConstructGeo: ", *this->snapshot);
0252 }
0253 }
0254
0255 void Geant4DetectorConstructionResources::print_status(const char* tag, const StatusProcess& sp) const {
0256 this->always("%s Name: \t%s", tag, sp.comm);
0257 this->always("%s State: \t%c", tag, sp.state);
0258 this->always("%s Umask: \t%8d", tag, sp.umask);
0259 this->always("%s Tgid: \t%8d", tag, sp.tgid);
0260 this->always("%s Pid: \t%8d", tag, sp.pid);
0261 this->always("%s PPid: \t%8d", tag, sp.ppid);
0262 this->always("%s utrace: \t%8d", tag, sp.utrace);
0263 this->always("%s Uid: \t%8d", tag, sp.uid);
0264 this->always("%s Gid: \t%8d", tag, sp.gid);
0265 this->always("%s FDSize: \t%8d", tag, sp.fdSize);
0266 this->always("%s VmPeak: \t%8ld kB", tag, sp.vmPeak);
0267 this->always("%s VmSize: \t%8ld kB", tag, sp.vmSize);
0268 this->always("%s VmLck: \t%8ld kB", tag, sp.vmLock);
0269 this->always("%s VmHWM: \t%8ld kB", tag, sp.vmHWM);
0270 this->always("%s VmRSS: \t%8ld kB", tag, sp.vmRSS);
0271 this->always("%s VmRSS anon: \t%8ld kB", tag, sp.vmRSSano);
0272 this->always("%s VmRSS file: \t%8ld kB", tag, sp.vmRSSfil);
0273 this->always("%s VmRSS shm: \t%8ld kB", tag, sp.vmRSSshm);
0274 this->always("%s VmData: \t%8ld kB", tag, sp.vmData);
0275 this->always("%s VmStk: \t%8ld kB", tag, sp.vmStack);
0276 this->always("%s VmExe: \t%8ld kB", tag, sp.vmExe);
0277 this->always("%s VmLib: \t%8ld kB", tag, sp.vmLib);
0278 this->always("%s VmPTE: \t%8ld kB", tag, sp.vmPTE);
0279 }
0280
0281
0282 void Geant4DetectorConstructionResources::constructSensitives(Geant4DetectorConstructionContext*) {
0283 if ( this->when.find("sensitives") != std::string::npos ) {
0284 StatusProcess rd;
0285 read_info(rd, ::getpid());
0286 this->print_status("ConstructSD: ", rd);
0287 #if 0
0288 if ( snapshot ) {
0289 const auto& snap = *this->snapshot;
0290 this->always(" --> DIFFERENCE: FDSize: \t%8d", rd.fdSize - snap.fdSize);
0291 this->always(" --> DIFFERENCE: VmPeak: \t%8ld kB", rd.vmPeak - snap.vmPeak);
0292 this->always(" --> DIFFERENCE: VmSize: \t%8ld kB", rd.vmSize - snap.vmSize);
0293 this->always(" --> DIFFERENCE: VmLck: \t%8ld kB", rd.vmLock - snap.vmLock);
0294 this->always(" --> DIFFERENCE: VmHWM: \t%8ld kB", rd.vmHWM - snap.vmHWM);
0295 this->always(" --> DIFFERENCE: VmRSS: \t%8ld kB", rd.vmRSS - snap.vmRSS);
0296 this->always(" --> DIFFERENCE: VmRSS anon: \t%8ld kB", rd.vmRSSano - snap.vmRSSano);
0297 this->always(" --> DIFFERENCE: VmRSS file: \t%8ld kB", rd.vmRSSfil - snap.vmRSSfil);
0298 this->always(" --> DIFFERENCE: VmRSS shm: \t%8ld kB", rd.vmRSSshm - snap.vmRSSshm);
0299 this->always(" --> DIFFERENCE: VmData: \t%8ld kB", rd.vmData - snap.vmData);
0300 this->always(" --> DIFFERENCE: VmStk: \t%8ld kB", rd.vmStack - snap.vmStack);
0301 this->always(" --> DIFFERENCE: VmExe: \t%8ld kB", rd.vmExe - snap.vmExe);
0302 this->always(" --> DIFFERENCE: VmLib: \t%8ld kB", rd.vmLib - snap.vmLib);
0303 this->always(" --> DIFFERENCE: VmPTE: \t%8ld kB", rd.vmPTE - snap.vmPTE);
0304 }
0305 #endif
0306 }
0307 snapshot.reset();
0308 }