diff -ru --exclude=config.h htop-0.9/configure.ac htop-0.9-patched/configure.ac --- htop-0.9/configure.ac 2010-11-23 16:56:32.000000000 +0100 +++ htop-0.9-patched/configure.ac 2011-03-09 16:58:38.471801331 +0100 @@ -18,11 +18,13 @@ # Checks for libraries. AC_CHECK_LIB([m], [ceil], [], [missing_libraries="$missing_libraries libm"]) +AC_CHECK_LIB([pagemap], [init_pgmap_table], [], [], []) +AC_CHECK_LIB([pthread], [pthread_create], [], [], []) # Checks for header files. AC_HEADER_DIRENT AC_HEADER_STDC -AC_CHECK_HEADERS([stdlib.h string.h strings.h sys/param.h sys/time.h unistd.h curses.h],[:],[ +AC_CHECK_HEADERS([stdlib.h string.h strings.h sys/param.h sys/time.h unistd.h curses.h pthread.h],[:],[ missing_headers="$missing_headers $ac_header" ]) diff -ru --exclude=config.h htop-0.9/htop.1 htop-0.9-patched/htop.1 --- htop-0.9/htop.1 2010-11-23 17:34:04.000000000 +0100 +++ htop-0.9-patched/htop.1 2011-03-09 16:44:07.065449472 +0100 @@ -25,6 +25,9 @@ \fB\-u USERNAME\fR Show only processes of a given user .TP +\fB\-p\fR +Start working thread for pagemap memory stats +.TP \fB\-\-sort\-key COLUMN\fR Sort by this column (use --sort-key help for a column list) .PP diff -ru --exclude=config.h htop-0.9/htop.1.in htop-0.9-patched/htop.1.in --- htop-0.9/htop.1.in 2010-06-17 21:03:41.000000000 +0200 +++ htop-0.9-patched/htop.1.in 2011-03-09 16:44:07.066449478 +0100 @@ -25,6 +25,9 @@ \fB\-u USERNAME\fR Show only processes of a given user .TP +\fB\-p\fR +Start working thread for pagemap memory stats +.TP \fB\-\-sort\-key COLUMN\fR Sort by this column (use --sort-key help for a column list) .PP diff -ru --exclude=config.h htop-0.9/htop.c htop-0.9-patched/htop.c --- htop-0.9/htop.c 2010-11-24 19:45:38.000000000 +0100 +++ htop-0.9-patched/htop.c 2011-03-09 16:44:07.067449482 +0100 @@ -13,6 +13,7 @@ #include #include #include +#include #include "ProcessList.h" #include "CRT.h" @@ -52,6 +53,9 @@ "-C --no-color Use a monochrome color scheme\n" "-d --delay=DELAY Set the delay between updates, in tenths of seconds\n" "-h --help Print this help screen\n" +#ifdef HAVE_LIBPAGEMAP + "-p --pagemap Count memory stats from pagemap kernel interface\n" +#endif "-s --sort-key=COLUMN Sort by COLUMN (try --sort-key=help for a list)\n" "-u --user=USERNAME Show only processes of a given user\n" "-v --version Print version info\n" @@ -244,12 +248,23 @@ ProcessList_printHeader(pl, Panel_getHeader(panel)); } +#ifdef HAVE_LIBPAGEMAP +static void * pagemapCnt(ProcessList * pl) { + while(1) { + pl->pagemap_table = init_pgmap_table(pl->pagemap_table); + open_pgmap_table(pl->pagemap_table,0); + } + return; +} +#endif + int main(int argc, char** argv) { int delay = -1; bool userOnly = false; uid_t userId = 0; int usecolors = 1; + int pagemap_enable = 0; int opt, opti=0; static struct option long_opts[] = @@ -261,6 +276,9 @@ {"user", required_argument, 0, 'u'}, {"no-color", no_argument, 0, 'C'}, {"no-colour",no_argument, 0, 'C'}, +#ifdef HAVE_LIBPAGEMAP + {"pagemap", no_argument, 0, 'p'}, +#endif {0,0,0,0} }; int sortKey = 0; @@ -272,7 +290,7 @@ setlocale(LC_CTYPE, getenv("LC_ALL")); /* Parse arguments */ - while ((opt = getopt_long_only(argc, argv, "hvCs:d:u:", long_opts, &opti))) { + while ((opt = getopt_long_only(argc, argv, "hpvCs:d:u:", long_opts, &opti))) { if (opt == EOF) break; switch (opt) { case 'h': @@ -305,6 +323,11 @@ case 'C': usecolors=0; break; +#ifdef HAVE_LIBPAGEMAP + case 'p': + pagemap_enable=1; + break; +#endif } } @@ -379,6 +402,18 @@ int ch = 0; int closeTimeout = 0; +#ifdef HAVE_LIBPAGEMAP + // declare threading stuff + static pthread_t libpagemap_thread; + static pthread_attr_t t_attr; + if (pagemap_enable) { + // start thread + pthread_attr_init(&t_attr); + pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED); + pthread_create(&libpagemap_thread, &t_attr, (void * (*)(void *)) &pagemapCnt, (void *) pl); + } +#endif + while (!quit) { gettimeofday(&tv, NULL); newTime = ((double)tv.tv_sec * 10) + ((double)tv.tv_usec / 100000); @@ -817,6 +852,12 @@ if (settings->changed) Settings_write(settings); Header_delete(header); +#ifdef HAVE_LIBPAGEMAP + if (pagemap_enable) { + pthread_cancel(libpagemap_thread); + free_pgmap_table(pl->pagemap_table); + } +#endif ProcessList_delete(pl); FunctionBar_delete((Object*)searchBar); FunctionBar_delete((Object*)defaultBar); diff -ru --exclude=config.h htop-0.9/htop.h htop-0.9-patched/htop.h --- htop-0.9/htop.h 2010-11-24 19:45:40.000000000 +0100 +++ htop-0.9-patched/htop.h 2011-03-09 16:48:37.672644570 +0100 @@ -17,6 +17,9 @@ #include #include #include +#ifdef HAVE_LIBPAGEMAP +#include +#endif #include "ProcessList.h" #include "CRT.h" diff -ru --exclude=config.h htop-0.9/Process.c htop-0.9-patched/Process.c --- htop-0.9/Process.c 2010-11-23 16:56:32.000000000 +0100 +++ htop-0.9-patched/Process.c 2011-03-09 16:44:07.069449489 +0100 @@ -72,6 +72,9 @@ #ifdef HAVE_CGROUP CGROUP, #endif + #ifdef HAVE_LIBPAGEMAP + M_USS, M_PSS, M_SWAP, + #endif LAST_PROCESSFIELD } ProcessField; @@ -115,7 +118,7 @@ #ifdef DEBUG long int itrealvalue; unsigned long int vsize; - long int rss; + long 1nt rss; unsigned long int rlim; unsigned long int startcode; unsigned long int endcode; @@ -139,6 +142,9 @@ int m_drs; int m_lrs; int m_dt; + unsigned int m_uss; + unsigned int m_pss; + unsigned int m_swap; uid_t st_uid; float percent_cpu; float percent_mem; @@ -198,6 +204,9 @@ #ifdef HAVE_CGROUP "CGROUP", #endif +#ifdef HAVE_LIBPAGEMAP + "M_USS", "M_PSS", "M_SWAP", +#endif "*** report bug! ***" }; @@ -223,6 +232,9 @@ #ifdef HAVE_CGROUP " CGROUP ", #endif +#ifdef HAVE_LIBPAGEMAP + " USS ", " PSS ", " SWAP ", +#endif "*** report bug! ***" }; @@ -393,6 +405,32 @@ case M_SIZE: Process_printLargeNumber(this, str, this->m_size * PAGE_SIZE_KB); return; case M_RESIDENT: Process_printLargeNumber(this, str, this->m_resident * PAGE_SIZE_KB); return; case M_SHARE: Process_printLargeNumber(this, str, this->m_share * PAGE_SIZE_KB); return; + #ifdef HAVE_LIBPAGEMAP + case M_USS: + if (Process_getuid == 0 && this->pl->pagemap_table != NULL) { + Process_printLargeNumber(this, str, this->m_uss * PAGE_SIZE_KB); + return; + } else { + snprintf(buffer, n, " - "); + } + break; + case M_PSS: + if (Process_getuid == 0 && this->pl->pagemap_table != NULL) { + Process_printLargeNumber(this, str, this->m_pss * PAGE_SIZE_KB); + return; + } else { + snprintf(buffer, n, " - "); + } + break; + case M_SWAP: + if ((Process_getuid == 0 || Process_getuid == this->st_uid) && this->pl->pagemap_table != NULL) { + Process_printLargeNumber(this, str, this->m_swap * PAGE_SIZE_KB); + return; + } else { + snprintf(buffer, n, " - "); + } + break; + #endif case ST_UID: snprintf(buffer, n, "%4d ", this->st_uid); break; case USER: { if (Process_getuid != (int) this->st_uid) @@ -583,6 +621,14 @@ return (p2->m_resident - p1->m_resident); case M_SHARE: return (p2->m_share - p1->m_share); + #ifdef HAVE_LIBPAGEMAP + case M_USS: + return (p2->m_uss - p1->m_uss); + case M_PSS: + return (p2->m_pss - p1->m_pss); + case M_SWAP: + return (p2->m_swap - p1->m_swap); + #endif case PERCENT_CPU: return (p2->percent_cpu > p1->percent_cpu ? 1 : -1); case PERCENT_MEM: diff -ru --exclude=config.h htop-0.9/Process.h htop-0.9-patched/Process.h --- htop-0.9/Process.h 2010-11-23 16:56:32.000000000 +0100 +++ htop-0.9-patched/Process.h 2011-03-09 16:44:07.070449492 +0100 @@ -74,6 +74,9 @@ #ifdef HAVE_CGROUP CGROUP, #endif + #ifdef HAVE_LIBPAGEMAP + M_USS, M_PSS, M_SWAP, + #endif LAST_PROCESSFIELD } ProcessField; @@ -117,7 +120,7 @@ #ifdef DEBUG long int itrealvalue; unsigned long int vsize; - long int rss; + long 1nt rss; unsigned long int rlim; unsigned long int startcode; unsigned long int endcode; @@ -141,6 +144,9 @@ int m_drs; int m_lrs; int m_dt; + unsigned int m_uss; + unsigned int m_pss; + unsigned int m_swap; uid_t st_uid; float percent_cpu; float percent_mem; diff -ru --exclude=config.h htop-0.9/ProcessList.c htop-0.9-patched/ProcessList.c --- htop-0.9/ProcessList.c 2010-11-26 17:50:25.000000000 +0100 +++ htop-0.9-patched/ProcessList.c 2011-03-09 16:44:07.071449495 +0100 @@ -10,6 +10,9 @@ #include "config.h" #endif +#ifdef HAVE_LIBPAGEMAP +#include "libpagemap.h" +#endif #include "ProcessList.h" #include "Process.h" #include "Vector.h" @@ -28,6 +31,7 @@ #include #include #include +#include #include "debug.h" #include @@ -125,6 +129,10 @@ bool highlightThreads; bool detailedCPUTime; +#ifdef HAVE_LIBPAGEMAP + pagemap_tbl * pagemap_table; +#endif + } ProcessList; }*/ @@ -177,6 +185,9 @@ this->highlightBaseName = false; this->highlightMegabytes = false; this->detailedCPUTime = false; +#ifdef HAVE_LIBPAGEMAP + this->pagemap_table = NULL; +#endif return this; } @@ -429,6 +440,29 @@ return (num == 7); } +#ifdef HAVE_LIBPAGEMAP + +static bool ProcessList_readPagemap(ProcessList* plist ,Process* process, const char * name) { + + process_pagemap_t* p = NULL; + int pid = 0; + + pid = atoi(name); + + if ((p = get_single_pgmap(plist->pagemap_table,pid)) == NULL) { + process->m_uss = 0; + process->m_pss = 0; + process->m_swap = 0; + } else { + process->m_uss = p->uss; + process->m_pss = p->pss; + process->m_swap = p->swap; + } + return true; +} + +#endif + #ifdef HAVE_OPENVZ static void ProcessList_readOpenVZData(Process* process, const char* dirname, const char* name) { @@ -589,6 +623,11 @@ if (! ProcessList_readStatmFile(process, dirname, name)) goto errorReadingProcess; + #ifdef HAVE_LIBPAGEMAP + if (! ProcessList_readPagemap(this, process, name)) + goto errorReadingProcess; + #endif + process->show = ! ((hideKernelThreads && Process_isKernelThread(process)) || (hideUserlandThreads && Process_isUserlandThread(process))); char command[MAX_NAME+1]; diff -ru --exclude=config.h htop-0.9/ProcessList.h htop-0.9-patched/ProcessList.h --- htop-0.9/ProcessList.h 2010-11-26 17:51:25.000000000 +0100 +++ htop-0.9-patched/ProcessList.h 2011-03-09 16:44:07.072449499 +0100 @@ -14,6 +14,9 @@ #include "config.h" #endif +#ifdef HAVE_LIBPAGEMAP +#include "libpagemap.h" +#endif #include "Process.h" #include "Vector.h" #include "UsersTable.h" @@ -31,6 +34,7 @@ #include #include #include +#include #include "debug.h" #include @@ -125,6 +129,10 @@ bool highlightThreads; bool detailedCPUTime; +#ifdef HAVE_LIBPAGEMAP + pagemap_tbl * pagemap_table; +#endif + } ProcessList; ProcessList* ProcessList_new(UsersTable* usersTable); @@ -145,6 +153,10 @@ #endif +#ifdef HAVE_LIBPAGEMAP + +#endif + #ifdef HAVE_OPENVZ #endif