diff options
author | Hisham Muhammad <hisham@gobolinux.org> | 2008-03-09 08:02:22 +0000 |
---|---|---|
committer | Hisham Muhammad <hisham@gobolinux.org> | 2008-03-09 08:02:22 +0000 |
commit | 12f4f09e6ed288bdedc86e4ef22f3cc34f0e787a (patch) | |
tree | 0b3ce5d14fc72ae391378fa178a0a18b69298664 /ProcessList.c | |
parent | 460608d6e215dee3d3af822d974f3a36e5f73d3c (diff) |
Add support for Linux per-process IO statistics,
enabled with the --enable-taskstats flag, which
requires a kernel compiled with taskstats support.
Thanks to Tobias Oetiker!
Diffstat (limited to 'ProcessList.c')
-rw-r--r-- | ProcessList.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/ProcessList.c b/ProcessList.c index 04ac6f3e..e0d0939c 100644 --- a/ProcessList.c +++ b/ProcessList.c @@ -499,6 +499,50 @@ bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* dirname, return true; } +#ifdef HAVE_TASKSTATS +void ProcessList_readIoFile(ProcessList* this, Process* proc, char* dirname, char* name) { + char iofilename[MAX_NAME+1]; + iofilename[MAX_NAME] = '\0'; + + char buffer[256]; + buffer[255] = '\0'; + + snprintf(iofilename, MAX_NAME, "%s/%s/io", dirname, name); + FILE* io = ProcessList_fopen(this, iofilename, "r"); + if (io) { + struct timeval tv; + gettimeofday(&tv,NULL); + unsigned long long now = tv.tv_sec*1000+tv.tv_usec/1000; + + unsigned long long last_read = proc->io_read_bytes; + unsigned long long last_write = proc->io_write_bytes; + while (!feof(io)) { + char* ok = fgets(buffer, 255, io); + if (!ok) + break; + if (ProcessList_read(this, buffer, "rchar: %llu", &proc->io_rchar)) continue; + if (ProcessList_read(this, buffer, "wchar: %llu", &proc->io_wchar)) continue; + if (ProcessList_read(this, buffer, "syscr: %llu", &proc->io_syscr)) continue; + if (ProcessList_read(this, buffer, "syscw: %llu", &proc->io_syscw)) continue; + if (ProcessList_read(this, buffer, "read_bytes: %llu", &proc->io_read_bytes)) { + proc->io_rate_read_bps = + ((double)(proc->io_read_bytes - last_read))/(((double)(now - proc->io_rate_read_time))/1000); + proc->io_rate_read_time = now; + continue; + } + if (ProcessList_read(this, buffer, "write_bytes: %llu", &proc->io_write_bytes)) { + proc->io_rate_write_bps = + ((double)(proc->io_write_bytes - last_write))/(((double)(now - proc->io_rate_write_time))/1000); + proc->io_rate_write_time = now; + continue; + } + ProcessList_read(this, buffer, "cancelled_write_bytes: %llu", &proc->io_cancelled_write_bytes); + } + fclose(io); + } +} +#endif + bool ProcessList_processEntries(ProcessList* this, char* dirname, Process* parent, float period) { DIR* dir; struct dirent* entry; @@ -547,6 +591,10 @@ bool ProcessList_processEntries(ProcessList* this, char* dirname, Process* paren } } + #ifdef HAVE_TASKSTATS + ProcessList_readIoFile(this, process, dirname, name); + #endif + if (showUserlandThreads && (!parent || pid != parent->pid)) { char subdirname[MAX_NAME+1]; snprintf(subdirname, MAX_NAME, "%s/%s/task", dirname, name); |