diff --git a/darwin/DarwinProcessList.c b/darwin/DarwinProcessList.c index 6187d346..1e9bd148 100644 --- a/darwin/DarwinProcessList.c +++ b/darwin/DarwinProcessList.c @@ -14,6 +14,8 @@ in the source distribution for its full text. #include #include #include +#include +#include /*{ #include @@ -22,8 +24,8 @@ in the source distribution for its full text. typedef struct DarwinProcessList_ { ProcessList super; - host_basic_info_data_t prev_hinfo; - processor_info_data_t prev_cpus; + host_basic_info_data_t host_info; + processor_cpu_load_info_t cpu_load; } DarwinProcessList; }*/ @@ -37,10 +39,17 @@ void ProcessList_getHostInfo(host_basic_info_data_t *p) { } } -unsigned ProcessList_getCPUInfo(processor_info_data_t *p) { - mach_msg_type_number_t info_size = PROCESSOR_CPU_LOAD_INFO_COUNT; +unsigned ProcessList_updateCPULoadInfo(processor_cpu_load_info_t *p) { + mach_msg_type_number_t info_size = sizeof(processor_cpu_load_info_t); unsigned cpu_count; + if(NULL != p) { + if(0 != munmap(*p, vm_page_size)) { + fprintf(stderr, "Unable to free old CPU load information\n"); + exit(8); + } + } + if(0 != host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &cpu_count, (processor_info_array_t *)p, &info_size)) { fprintf(stderr, "Unable to retrieve CPU info\n"); exit(4); @@ -86,8 +95,9 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList, ui ProcessList_init(&this->super, Class(Process), usersTable, pidWhiteList, userId); /* Initialize the previous information */ - this->super.cpuCount = ProcessList_getCPUInfo(&this->prev_cpus); - ProcessList_getHostInfo(&this->prev_hinfo); + this->cpu_load = NULL; + this->super.cpuCount = ProcessList_updateCPULoadInfo(&this->cpu_load); + ProcessList_getHostInfo(&this->host_info); return &this->super; } @@ -107,6 +117,9 @@ void ProcessList_goThroughEntries(ProcessList* super) { gettimeofday(&tv, NULL); /* Start processing time */ + /* Update the global data (CPU times) */ + ProcessList_updateCPULoadInfo(&dpl->cpu_load); + /* We use kinfo_procs for initial data since : * * 1) They always succeed. @@ -120,7 +133,7 @@ void ProcessList_goThroughEntries(ProcessList* super) { proc = ProcessList_getProcess(super, ps[i].kp_proc.p_pid, &preExisting, DarwinProcess_new); DarwinProcess_setFromKInfoProc(proc, ps + i, tv.tv_sec, preExisting); - DarwinProcess_setFromLibprocPidinfo(proc, dpl->prev_hinfo.max_mem, preExisting); + DarwinProcess_setFromLibprocPidinfo(proc, dpl->host_info.max_mem, preExisting); if(!preExisting) { proc->user = UsersTable_getRef(super->usersTable, proc->st_uid); diff --git a/darwin/DarwinProcessList.h b/darwin/DarwinProcessList.h index 6a4bb094..065e8fbf 100644 --- a/darwin/DarwinProcessList.h +++ b/darwin/DarwinProcessList.h @@ -15,17 +15,14 @@ in the source distribution for its full text. typedef struct DarwinProcessList_ { ProcessList super; - host_basic_info_data_t prev_hinfo; - vm_statistics64_data_t prev_vminfo; - processor_info_data_t prev_cpus; + host_basic_info_data_t host_info; + processor_cpu_load_info_t cpu_load; } DarwinProcessList; void ProcessList_getHostInfo(host_basic_info_data_t *p); -void ProcessList_getVMInfo(vm_statistics64_data_t *p); - -unsigned ProcessList_getCPUInfo(processor_info_data_t *p); +unsigned ProcessList_updateCPULoadInfo(processor_cpu_load_info_t *p); struct kinfo_proc *ProcessList_getKInfoProcs(size_t *count); diff --git a/darwin/Platform.c b/darwin/Platform.c index a1a3471e..1d43eaa8 100644 --- a/darwin/Platform.c +++ b/darwin/Platform.c @@ -15,6 +15,7 @@ in the source distribution for its full text. #include "ClockMeter.h" #include "HostnameMeter.h" #include "UptimeMeter.h" +#include "DarwinProcessList.h" #include @@ -131,10 +132,31 @@ void Process_setupColumnWidths() { } } -double Platform_setCPUValues(Meter* this, int cpu) { - DarwinProcessList *dpl = (DarwinProcessList *)this->pl; +double Platform_setCPUValues(Meter* mtr, int cpu) { + /* All just from CPUMeter.c */ + static const int CPU_METER_NICE = 0; + static const int CPU_METER_NORMAL = 1; + static const int CPU_METER_KERNEL = 2; - return 0.0; + DarwinProcessList *dpl = (DarwinProcessList *)mtr->pl; + processor_cpu_load_info_t ticks = &dpl->cpu_load[cpu-1]; + double total = 0; + + /* Take the sums */ + for(size_t i = 0; i < CPU_STATE_MAX; ++i) { + total += (double)ticks->cpu_ticks[i]; + } + + mtr->values[CPU_METER_NICE] = (double)ticks->cpu_ticks[CPU_STATE_NICE] * 100.0 / total; + mtr->values[CPU_METER_NORMAL] = (double)ticks->cpu_ticks[CPU_STATE_USER] * 100.0 / total; + mtr->values[CPU_METER_KERNEL] = (double)ticks->cpu_ticks[CPU_STATE_SYSTEM] * 100.0 / total; + + Meter_setItems(mtr, 3); + + /* Convert to percent and return */ + total = mtr->values[CPU_METER_NICE] + mtr->values[CPU_METER_NORMAL] + mtr->values[CPU_METER_KERNEL]; + + return MIN(100.0, MAX(0.0, total)); } void Platform_setMemoryValues(Meter* this) { diff --git a/darwin/Platform.h b/darwin/Platform.h index 7da13321..31e68685 100644 --- a/darwin/Platform.h +++ b/darwin/Platform.h @@ -34,7 +34,7 @@ int Platform_getMaxPid(); void Process_setupColumnWidths(); -double Platform_setCPUValues(Meter* this, int cpu); +double Platform_setCPUValues(Meter* mtr, int cpu); void Platform_setMemoryValues(Meter* this);