0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-11-30 00:56:44 +01:00
mongodb/util/processinfo_linux2.cpp
2011-01-04 00:40:41 -05:00

243 lines
8.0 KiB
C++

// processinfo_linux2.cpp
/* Copyright 2009 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "processinfo.h"
#include <iostream>
#include <stdio.h>
#include <malloc.h>
#include <db/jsobj.h>
#include <unistd.h>
#include <sys/mman.h>
using namespace std;
#define KLONG long
#define KLF "l"
namespace mongo {
class LinuxProc {
public:
LinuxProc( pid_t pid = getpid() ) {
char name[128];
sprintf( name , "/proc/%d/stat" , pid );
FILE * f = fopen( name , "r");
if ( ! f ) {
stringstream ss;
ss << "couldn't open [" << name << "] " << errnoWithDescription();
string s = ss.str();
// help the assert# control uasserted( 13538 , s.c_str() );
msgassertedNoTrace( 13538 , s.c_str() );
}
int found = fscanf(f,
"%d %s %c "
"%d %d %d %d %d "
"%lu %lu %lu %lu %lu "
"%lu %lu %ld %ld " /* utime stime cutime cstime */
"%ld %ld "
"%ld "
"%ld "
"%lu " /* start_time */
"%lu "
"%ld " // rss
"%lu %"KLF"u %"KLF"u %"KLF"u %"KLF"u %"KLF"u "
/*
"%*s %*s %*s %*s "
"%"KLF"u %*lu %*lu "
"%d %d "
"%lu %lu"
*/
,
&_pid,
_comm,
&_state,
&_ppid, &_pgrp, &_session, &_tty, &_tpgid,
&_flags, &_min_flt, &_cmin_flt, &_maj_flt, &_cmaj_flt,
&_utime, &_stime, &_cutime, &_cstime,
&_priority, &_nice,
&_alarm,
&_nlwp,
&_start_time,
&_vsize,
&_rss,
&_rss_rlim, &_start_code, &_end_code, &_start_stack, &_kstk_esp, &_kstk_eip
/*
&_wchan,
&_exit_signal, &_processor,
&_rtprio, &_sched
*/
);
if ( found == 0 ) {
cout << "system error: reading proc info" << endl;
}
fclose( f );
}
unsigned long getVirtualMemorySize() {
return _vsize;
}
unsigned long getResidentSize() {
return (unsigned long)_rss * 4 * 1024;
}
int _pid;
// The process ID.
char _comm[128];
// The filename of the executable, in parentheses. This is visible whether or not the executable is swapped out.
char _state;
//One character from the string "RSDZTW" where R is running, S is sleeping in an interruptible wait, D is waiting in uninterruptible
// disk sleep, Z is zombie, T is traced or stopped (on a signal), and W is paging.
int _ppid;
// The PID of the parent.
int _pgrp;
// The process group ID of the process.
int _session;
// The session ID of the process.
int _tty;
// The tty the process uses.
int _tpgid;
// The process group ID of the process which currently owns the tty that the process is connected to.
unsigned long _flags; // %lu
// The kernel flags word of the process. For bit meanings, see the PF_* defines in <linux/sched.h>. Details depend on the kernel version.
unsigned long _min_flt; // %lu
// The number of minor faults the process has made which have not required loading a memory page from disk.
unsigned long _cmin_flt; // %lu
// The number of minor faults that the process
unsigned long _maj_flt; // %lu
// The number of major faults the process has made which have required loading a memory page from disk.
unsigned long _cmaj_flt; // %lu
// The number of major faults that the process
unsigned long _utime; // %lu
// The number of jiffies that this process has been scheduled in user mode.
unsigned long _stime; // %lu
// The number of jiffies that this process has been scheduled in kernel mode.
long _cutime; // %ld
// The number of jiffies that this removed field.
long _cstime; // %ld
long _priority;
long _nice;
long _nlwp; // %ld
// The time in jiffies before the next SIGALRM is sent to the process due to an interval timer.
unsigned long _alarm;
unsigned long _start_time; // %lu
// The time in jiffies the process started after system boot.
unsigned long _vsize; // %lu
// Virtual memory size in bytes.
long _rss; // %ld
// Resident Set Size: number of pages the process has in real memory, minus 3 for administrative purposes. This is just the pages which
// count towards text, data, or stack space. This does not include pages which have not been demand-loaded in, or which are swapped out
unsigned long _rss_rlim; // %lu
// Current limit in bytes on the rss of the process (usually 4294967295 on i386).
unsigned long _start_code; // %lu
// The address above which program text can run.
unsigned long _end_code; // %lu
// The address below which program text can run.
unsigned long _start_stack; // %lu
// The address of the start of the stack.
unsigned long _kstk_esp; // %lu
// The current value of esp (stack pointer), as found in the kernel stack page for the process.
unsigned long _kstk_eip; // %lu
// The current EIP (instruction pointer).
};
ProcessInfo::ProcessInfo( pid_t pid ) : _pid( pid ) {
}
ProcessInfo::~ProcessInfo() {
}
bool ProcessInfo::supported() {
return true;
}
int ProcessInfo::getVirtualMemorySize() {
LinuxProc p(_pid);
return (int)( p.getVirtualMemorySize() / ( 1024.0 * 1024 ) );
}
int ProcessInfo::getResidentSize() {
LinuxProc p(_pid);
return (int)( p.getResidentSize() / ( 1024.0 * 1024 ) );
}
void ProcessInfo::getExtraInfo(BSONObjBuilder& info) {
struct mallinfo malloc_info = mallinfo(); // structure has same name as function that returns it. (see malloc.h)
info.append("heap_usage_bytes", malloc_info.uordblks);
LinuxProc p(_pid);
info.append("page_faults", (int)p._maj_flt);
}
bool ProcessInfo::blockCheckSupported() {
return true;
}
bool ProcessInfo::blockInMemory( char * start ) {
static long pageSize = 0;
if ( pageSize == 0 ) {
pageSize = sysconf( _SC_PAGESIZE );
}
start = start - ( (unsigned long long)start % pageSize );
unsigned char x = 0;
if ( mincore( start , 128 , &x ) ) {
log() << "mincore failed: " << errnoWithDescription() << endl;
return 1;
}
return x & 0x1;
}
}