CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2/src/EventFilter/Processor/src/procUtils.cc

Go to the documentation of this file.
00001     /*
00002  * Displays linux /proc/pid/stat in human-readable format
00003  *
00004  * Build: gcc -o procstat procstat.c
00005  * Usage: procstat pid
00006  *        cat /proc/pid/stat | procstat
00007  *
00008  * Homepage: https://www.brokestream.com/procstat.html
00009  * Version : 2009-03-05
00010  *
00011  * Ivan Tikhonov, https://www.brokestream.com, kefeer@netangels.ru
00012  *
00013  * 2007-09-19 changed HZ=100 error to warning
00014  *
00015  * 2009-03-05 tickspersec are taken from sysconf (Sabuj Pattanayek)
00016  *
00017  */
00018 
00019 
00020 /* Copyright (C) 2009 Ivan Tikhonov
00021 
00022   This software is provided 'as-is', without any express or implied
00023   warranty.  In no event will the authors be held liable for any damages
00024   arising from the use of this software.
00025 
00026   Permission is granted to anyone to use this software for any purpose,
00027   including commercial applications, and to alter it and redistribute it
00028   freely, subject to the following restrictions:
00029 
00030   1. The origin of this software must not be misrepresented; you must not
00031      claim that you wrote the original software. If you use this software
00032      in a product, an acknowledgment in the product documentation would be
00033      appreciated but is not required.
00034   2. Altered source versions must be plainly marked as such, and must not be
00035      misrepresented as being the original software.
00036   3. This notice may not be removed or altered from any source distribution.
00037 
00038   Ivan Tikhonov, kefeer@brokestream.com
00039 
00040 */
00041 
00042 
00043 #define FSHIFT          16              /* nr of bits of precision */
00044 #define FIXED_1         (1<<FSHIFT)     /* 1.0 as fixed-point */
00045 #define LOAD_INT(x) ((x) >> FSHIFT)
00046 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
00047 
00048 #ifdef linux
00049 #include <sys/sysinfo.h>
00050 #endif
00051 #include <errno.h>
00052 #include <iostream>
00053 #include <iomanip>
00054 
00055 #include <stdio.h>
00056 #include <unistd.h>
00057 #include <time.h>
00058 #ifdef linux
00059 #include <linux/limits.h>
00060 #endif
00061 #include <sys/times.h>
00062 #include <sstream>
00063 #include "procUtils.h"
00064 
00065 namespace evf{
00066   namespace utils{
00067     
00068 
00069 
00070 
00071     typedef long long int num;
00072 
00073     num pid;
00074     char tcomm[FILENAME_MAX];
00075     char state;
00076     
00077     num ppid;
00078     num pgid;
00079     num sid;
00080     num tty_nr;
00081     num tty_pgrp;
00082     
00083     num flags;
00084     num min_flt;
00085     num cmin_flt;
00086     num maj_flt;
00087     num cmaj_flt;
00088     num utime;
00089     num stimev;
00090     
00091     num cutime;
00092     num cstime;
00093     num priority;
00094     num nicev;
00095     num num_threads;
00096     num it_real_value;
00097     
00098     unsigned long long start_time;
00099     
00100     num vsize;
00101     num rss;
00102     num rsslim;
00103     num start_code;
00104     num end_code;
00105     num start_stack;
00106     num esp;
00107     num eip;
00108     
00109     num pending;
00110     num blocked;
00111     num sigign;
00112     num sigcatch;
00113     num wchan;
00114     num zero1;
00115     num zero2;
00116     num exit_signal;
00117     num cpu;
00118     num rt_priority;
00119     num policy;
00120     
00121     long tickspersec;
00122     char obuf[4096];
00123     FILE *input;
00124 
00125     void readone(num *x) { fscanf(input, "%lld ", x); }
00126     void readunsigned(unsigned long long *x) { fscanf(input, "%llu ", x); }
00127     void readstr(char *x) {  fscanf(input, "%s ", x);}
00128     void readchar(char *x) {  fscanf(input, "%c ", x);}
00129     
00130     void printone(const char *name, num x) {  sprintf(obuf,"%20s: %lld\n", name, x);}
00131     void printonex(const char *name, num x) {  sprintf(obuf,"%20s: %016llx\n", name, x);}
00132     void printunsigned(const char *name, unsigned long long x) {  sprintf(obuf,"%20s: %llu\n", name, x);}
00133     void printchar(const char *name, char x) {  sprintf(obuf,"%20s: %c\n", name, x);}
00134     void printstr(const char *name, char *x) {  sprintf(obuf,"%20s: %s\n", name, x);}
00135     void printtime(const char *name, num x) {  sprintf(obuf,"%20s: %f\n", name, (((double)x) / tickspersec));}
00136     
00137     int gettimesinceboot() {
00138       FILE *procuptime;
00139       int sec, ssec;
00140       
00141       procuptime = fopen("/proc/uptime", "r");
00142       fscanf(procuptime, "%d.%ds", &sec, &ssec);
00143       fclose(procuptime);
00144       return (sec*tickspersec)+ssec;
00145     }
00146 
00147     void printtimediff(const char *name, num x) {
00148       int sinceboot = gettimesinceboot();
00149       int running = sinceboot - x;
00150       time_t rt = time(NULL) - (running / tickspersec);
00151       char buf[1024];
00152       
00153       strftime(buf, sizeof(buf), "%m.%d %H:%M", localtime(&rt));
00154       sprintf(obuf,"%20s: %s (%lu.%lus)\n", name, buf, running / tickspersec, running % tickspersec);
00155     }
00156    
00157     void procCpuStat(unsigned long long &idleJiffies,unsigned long long &allJiffies) {
00158       //read one
00159       if (input==NULL)
00160         input = fopen("/proc/stat", "r");
00161       if (input==NULL) return;
00162       char cpu[10];
00163       readstr(cpu);
00164       int count=0;
00165       long long last=0;
00166       do {
00167         readone(&last);
00168         if (count==3) idleJiffies+=last;
00169         allJiffies+=last;
00170       }
00171       while (last && count++<20);
00172       fclose(input);
00173       input=NULL;
00174     }
00175 
00176     void procStat(std::ostringstream *out) {
00177       tickspersec = sysconf(_SC_CLK_TCK);
00178       input = NULL;
00179       
00180       std::ostringstream ost; 
00181       ost << "/proc/" << getpid() << "/stat";
00182       input = fopen(ost.str().c_str(), "r");
00183       
00184 
00185       readone(&pid);
00186       readstr(tcomm);
00187       readchar(&state);
00188       readone(&ppid);
00189       readone(&pgid);
00190       readone(&sid);
00191       readone(&tty_nr);
00192       readone(&tty_pgrp);
00193       readone(&flags);
00194       readone(&min_flt);
00195       readone(&cmin_flt);
00196       readone(&maj_flt);
00197       readone(&cmaj_flt);
00198       readone(&utime);
00199       readone(&stimev);
00200       readone(&cutime);
00201       readone(&cstime);
00202       readone(&priority);
00203       readone(&nicev);
00204       readone(&num_threads);
00205       readone(&it_real_value);
00206       readunsigned(&start_time);
00207       readone(&vsize);
00208       readone(&rss);
00209       readone(&rsslim);
00210       readone(&start_code);
00211       readone(&end_code);
00212       readone(&start_stack);
00213       readone(&esp);
00214       readone(&eip);
00215       readone(&pending);
00216       readone(&blocked);
00217       readone(&sigign);
00218       readone(&sigcatch);
00219       readone(&wchan);
00220       readone(&zero1);
00221       readone(&zero2);
00222       readone(&exit_signal);
00223       readone(&cpu);
00224       readone(&rt_priority);
00225       readone(&policy);
00226       
00227       {
00228         printone("pid", pid); *out << obuf;
00229         printstr("tcomm", tcomm); *out << obuf;
00230         printchar("state", state); *out << obuf;
00231         printone("ppid", ppid); *out << obuf;
00232         printone("pgid", pgid); *out << obuf;
00233         printone("sid", sid); *out << obuf;
00234         printone("tty_nr", tty_nr); *out << obuf;
00235         printone("tty_pgrp", tty_pgrp); *out << obuf;
00236         printone("flags", flags); *out << obuf;
00237         printone("min_flt", min_flt); *out << obuf;
00238         printone("cmin_flt", cmin_flt); *out << obuf;
00239         printone("maj_flt", maj_flt); *out << obuf;
00240         printone("cmaj_flt", cmaj_flt); *out << obuf;
00241         printtime("utime", utime); *out << obuf;
00242         printtime("stime", stimev); *out << obuf;
00243         printtime("cutime", cutime); *out << obuf;
00244         printtime("cstime", cstime); *out << obuf;
00245         printone("priority", priority); *out << obuf;
00246         printone("nice", nicev); *out << obuf;
00247         printone("num_threads", num_threads); *out << obuf;
00248         printtime("it_real_value", it_real_value); *out << obuf;
00249         printtimediff("start_time", start_time); *out << obuf;
00250         printone("vsize", vsize); *out << obuf;
00251         printone("rss", rss); *out << obuf;
00252         printone("rsslim", rsslim); *out << obuf;
00253         printone("start_code", start_code); *out << obuf;
00254         printone("end_code", end_code); *out << obuf;
00255         printone("start_stack", start_stack); *out << obuf;
00256         printone("esp", esp); *out << obuf;
00257         printone("eip", eip); *out << obuf;
00258         printonex("pending", pending); *out << obuf;
00259         printonex("blocked", blocked); *out << obuf;
00260         printonex("sigign", sigign); *out << obuf;
00261         printonex("sigcatch", sigcatch); *out << obuf;
00262         printone("wchan", wchan); *out << obuf;
00263         printone("zero1", zero1); *out << obuf;
00264         printone("zero2", zero2); *out << obuf;
00265         printonex("exit_signal", exit_signal); *out << obuf;
00266         printone("cpu", cpu); *out << obuf;
00267         printone("rt_priority", rt_priority); *out << obuf;
00268         printone("policy", policy); *out << obuf;
00269       }
00270       fclose(input);
00271     }
00272 
00273 
00274 
00275 
00276 
00277     //Derived from:
00278     /* vi: set sw=4 ts=4: */
00279     /*
00280      * Mini uptime implementation for busybox
00281      *
00282      * Copyright (C) 1999,2000 by Lineo, inc.
00283      * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
00284      *
00285      * This program is free software; you can redistribute it and/or modify
00286      * it under the terms of the GNU General Public License as published by
00287      * the Free Software Foundation; either version 2 of the License, or
00288      * (at your option) any later version.
00289      *
00290      * This program is distributed in the hope that it will be useful,
00291      * but WITHOUT ANY WARRANTY; without even the implied warranty of
00292      * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00293      * General Public License for more details.
00294      *
00295      * You should have received a copy of the GNU General Public License
00296      * along with this program; if not, write to the Free Software
00297      * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00298      *
00299      */
00300 
00301     /* This version of uptime doesn't display the number of users on the system,
00302      * since busybox init doesn't mess with utmp.  For folks using utmp that are
00303      * just dying to have # of users reported, feel free to write it as some type
00304      * of BB_FEATURE_UMTP_SUPPORT #define
00305      */
00306 
00307 
00308 
00309     void uptime(std::ostringstream *out)
00310     {
00311 #ifdef linux
00312       int updays, uphours, upminutes;
00313       struct sysinfo info;
00314       struct tm *current_time;
00315       time_t current_secs;
00316 
00317       time(&current_secs);
00318       current_time = localtime(&current_secs);
00319 
00320       sysinfo(&info);
00321 
00322       *out << std::setw(2) 
00323            << (current_time->tm_hour%12 ? current_time->tm_hour%12 : 12)
00324            << ":"
00325            << current_time->tm_min
00326            << (current_time->tm_hour > 11 ? " pm, " : " am, ")
00327            << " up ";
00328       updays = (int) info.uptime / (60*60*24);
00329       if (updays)
00330         *out <<  updays << " day" << ((updays != 1) ? "s " : " ");
00331       upminutes = (int) info.uptime / 60;
00332       uphours = (upminutes / 60) % 24;
00333       upminutes %= 60;
00334       if(uphours)
00335         *out << std::setw(2) << uphours << ":" << upminutes;
00336       else
00337         *out << upminutes << " minutes ";
00338       
00339       *out << " - load average "
00340            << LOAD_INT(info.loads[0]) << " " 
00341            << LOAD_FRAC(info.loads[0]) << " " 
00342            << LOAD_INT(info.loads[1]) << " " 
00343            << LOAD_FRAC(info.loads[1]) << " " 
00344            << LOAD_INT(info.loads[2]) << " " 
00345            << LOAD_FRAC(info.loads[2]) << " ";
00346       *out << " used memory " << std::setw(3) 
00347            << (float(info.totalram-info.freeram)/float(info.totalram))*100 << "%";
00348 #else
00349       // FIXME: one could probably use `clock_get_uptime` and similar on 
00350       // macosx to obtain at least part of the information.
00351       *out << "Unable to retrieve uptime information on this platform.";
00352 #endif
00353     }
00354     void mDiv(std::ostringstream *out, std::string name){
00355       *out << "<div id=\"" << name << "\">";
00356     }
00357     void cDiv(std::ostringstream *out){
00358       *out << "</div>";
00359     } 
00360     void mDiv(std::ostringstream *out, std::string name, std::string value){
00361       mDiv(out,name);
00362       *out << value;
00363       cDiv(out);
00364     }
00365     void mDiv(std::ostringstream *out, std::string name, unsigned int value){
00366       mDiv(out,name);
00367       *out << value;
00368       cDiv(out);
00369     } 
00370   } // namespace utils
00371 } //namespace evf