summaryrefslogtreecommitdiffstats
path: root/darwin
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2016-02-18 14:57:09 -0200
committerHisham Muhammad <hisham@gobolinux.org>2016-02-18 14:57:09 -0200
commit5ee6715843902da1aa40782a9d00f41ca855a2ee (patch)
tree82175584a26771bdb0e084a684450cb8c4f2c2e7 /darwin
parentc18309466d0974fd839c5b8c61edc590447092d4 (diff)
Scan threads for process state information.
Based on: http://stackoverflow.com/questions/6788274/ios-mac-cpu-usage-for-thread and https://github.com/max-horvath/htop-osx/blob/e86692e869e30b0bc7264b3675d2a4014866ef46/ProcessList.c This should be a fix for #361.
Diffstat (limited to 'darwin')
-rw-r--r--darwin/DarwinProcess.c73
-rw-r--r--darwin/DarwinProcess.h2
-rw-r--r--darwin/DarwinProcessList.c4
3 files changed, 69 insertions, 10 deletions
diff --git a/darwin/DarwinProcess.c b/darwin/DarwinProcess.c
index c88ee975..62d3f198 100644
--- a/darwin/DarwinProcess.c
+++ b/darwin/DarwinProcess.c
@@ -13,6 +13,8 @@ in the source distribution for its full text.
#include <string.h>
#include <stdio.h>
+#include <mach/mach.h>
+
/*{
#include "Settings.h"
#include "DarwinProcessList.h"
@@ -296,15 +298,7 @@ void DarwinProcess_setFromKInfoProc(Process *proc, struct kinfo_proc *ps, time_t
proc->nice = ep->p_nice;
proc->priority = ep->p_priority;
- /* Set the state */
- switch(ep->p_stat) {
- case SIDL: proc->state = 'I'; break;
- case SRUN: proc->state = 'R'; break;
- case SSLEEP: proc->state = 'S'; break;
- case SSTOP: proc->state = 'T'; break;
- case SZOMB: proc->state = 'Z'; break;
- default: proc->state = '?'; break;
- }
+ proc->state = (ep->p_stat == SZOMB) ? 'Z' : '?';
/* Make sure the updated flag is set */
proc->updated = true;
@@ -343,3 +337,64 @@ void DarwinProcess_setFromLibprocPidinfo(DarwinProcess *proc, DarwinProcessList
dpl->super.runningTasks += pti.pti_numrunning;
}
}
+
+/*
+ * Scan threads for process state information.
+ * Based on: http://stackoverflow.com/questions/6788274/ios-mac-cpu-usage-for-thread
+ * and https://github.com/max-horvath/htop-osx/blob/e86692e869e30b0bc7264b3675d2a4014866ef46/ProcessList.c
+ */
+void DarwinProcess_scanThreads(DarwinProcess *dp) {
+ Process* proc = (Process*) dp;
+ kern_return_t ret;
+
+ if (proc->state == 'Z') {
+ return;
+ }
+
+ task_t port;
+ ret = task_for_pid(mach_task_self(), proc->pid, &port);
+ if (ret != KERN_SUCCESS) {
+ return;
+ }
+
+ task_info_data_t tinfo;
+ mach_msg_type_number_t task_info_count = TASK_INFO_MAX;
+ ret = task_info(port, TASK_BASIC_INFO, (task_info_t) tinfo, &task_info_count);
+ if (ret != KERN_SUCCESS) {
+ return;
+ }
+
+ thread_array_t thread_list;
+ mach_msg_type_number_t thread_count;
+ ret = task_threads(port, &thread_list, &thread_count);
+ if (ret != KERN_SUCCESS) {
+ mach_port_deallocate(mach_task_self(), port);
+ return;
+ }
+
+ integer_t run_state = 999;
+ for (unsigned int i = 0; i < thread_count; i++) {
+ thread_info_data_t thinfo;
+ mach_msg_type_number_t thread_info_count = THREAD_BASIC_INFO_COUNT;
+ ret = thread_info(thread_list[i], THREAD_BASIC_INFO, (thread_info_t)thinfo, &thread_info_count);
+ if (ret == KERN_SUCCESS) {
+ thread_basic_info_t basic_info_th = (thread_basic_info_t) thinfo;
+ if (basic_info_th->run_state < run_state) {
+ run_state = basic_info_th->run_state;
+ }
+ mach_port_deallocate(mach_task_self(), thread_list[i]);
+ }
+ }
+ vm_deallocate(mach_task_self(), (vm_address_t) thread_list, sizeof(thread_port_array_t) * thread_count);
+ mach_port_deallocate(mach_task_self(), port);
+
+ char state = '?';
+ switch (run_state) {
+ case TH_STATE_RUNNING: state = 'R'; break;
+ case TH_STATE_STOPPED: state = 'S'; break;
+ case TH_STATE_WAITING: state = 'W'; break;
+ case TH_STATE_UNINTERRUPTIBLE: state = 'U'; break;
+ case TH_STATE_HALTED: state = 'H'; break;
+ }
+ proc->state = state;
+}
diff --git a/darwin/DarwinProcess.h b/darwin/DarwinProcess.h
index c479acfd..4739c9d6 100644
--- a/darwin/DarwinProcess.h
+++ b/darwin/DarwinProcess.h
@@ -38,4 +38,6 @@ void DarwinProcess_setFromKInfoProc(Process *proc, struct kinfo_proc *ps, time_t
void DarwinProcess_setFromLibprocPidinfo(DarwinProcess *proc, DarwinProcessList *dpl);
+void DarwinProcess_scanThreads(DarwinProcess *dp);
+
#endif
diff --git a/darwin/DarwinProcessList.c b/darwin/DarwinProcessList.c
index 7ea89d9f..7492f822 100644
--- a/darwin/DarwinProcessList.c
+++ b/darwin/DarwinProcessList.c
@@ -168,8 +168,10 @@ void ProcessList_goThroughEntries(ProcessList* super) {
for(size_t i = 0; i < count; ++i) {
proc = (DarwinProcess *)ProcessList_getProcess(super, ps[i].kp_proc.p_pid, &preExisting, (Process_New)DarwinProcess_new);
- DarwinProcess_setFromKInfoProc(&proc->super, ps + i, tv.tv_sec, preExisting);
+ DarwinProcess_setFromKInfoProc(&proc->super, &ps[i], tv.tv_sec, preExisting);
DarwinProcess_setFromLibprocPidinfo(proc, dpl);
+
+ DarwinProcess_scanThreads(proc);
super->totalTasks += 1;

© 2014-2024 Faster IT GmbH | imprint | privacy policy