3 * Christopher Bowns, 2008
8 // Created by Peter Hosey on 2006-06-21.
9 // Copyright 2006 Peter Hosey. All rights reserved.
11 // Modified by Christopher Bowns, starting 2008-1-1.
19 #include <sys/types.h>
22 //sysctl and its parameters
23 #include <sys/sysctl.h>
25 #include <sys/errno.h>
28 @implementation CPUInfo
33 inits cpudata, inptr, outptr
34 retrieves lastProcessorInfo for refresh method to go to town.
36 if cannot get processor info, returns nil.
38 - (CPUInfo *) initWithCapacity:(unsigned)numItems
42 from Hosey's CPU Usage.app:
44 //We could get the number of processors the same way that we get the CPU usage info, but that allocates memory.
45 /* enum { miblen = 2U };
46 int mib[miblen] = { CTL_HW, HW_NCPU };
47 size_t sizeOfNumCPUs = sizeof(numCPUs);
48 int status = sysctl(mib, miblen,
49 &numCPUs, &sizeOfNumCPUs,
50 */ /*newp*/ // NULL, /*newlen*/ 0U);
52 numCPUs = 1; // TODO we're going to assume one CPU for the moment.
53 // NSLog(@"%s error status, assuming one CPU", _cmd);
64 cpudata = calloc(numItems, sizeof(CPUData));
65 if (cpudata == NULL) {
66 NSLog (@"%s Failed to allocate buffer for CPUInfo", _cmd);
69 // Set up our data structure ptrs
73 // set the lastProcessorInfo array so we can get to work when we call refresh:
74 natural_t numProcessors_nobodyCares = 0U;
75 kern_return_t err = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, (natural_t *)&numProcessors_nobodyCares, (processor_info_array_t *)&lastProcessorInfo, (mach_msg_type_number_t *)&numLastProcessorInfo);
76 if(err != KERN_SUCCESS) {
77 NSLog(@"%s failed to get cpu statistics", _cmd);
79 // if we can't get this info, then we're toast. Exit gracefully.
90 lastProcessorInfo and numLastProcessorInfo contain valid data from prior refresh of CPU info
92 retrieves current data
93 calculates avg cpu load over last period
94 updates cpudata array with info
95 deallocates old numLastProcInfo and lastProcessorInfo and set ptrs to new data
99 processor_info_array_t processorInfo;
100 natural_t numProcessors_nobodyCares = 0U;
101 mach_msg_type_number_t numProcessorInfo;
103 kern_return_t err = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, (natural_t *)&numProcessors_nobodyCares, (processor_info_array_t *)&processorInfo, (mach_msg_type_number_t *)&numProcessorInfo);
104 if(err != KERN_SUCCESS) {
105 NSLog(@"%s failed to get cpu statistics", _cmd);
109 TODO make this multicore. First, we're gonna need a multicore machine to test it on.
111 // for(unsigned i = 0U; i < numCPUs; ++i)
113 unsigned int inUse, total, user, sys, nice, idle;
115 user = processorInfo[CPU_STATE_USER] - lastProcessorInfo[CPU_STATE_USER];
116 sys = processorInfo[CPU_STATE_SYSTEM] - lastProcessorInfo[CPU_STATE_SYSTEM];
117 nice = processorInfo[CPU_STATE_NICE] - lastProcessorInfo[CPU_STATE_NICE];
118 idle = processorInfo[CPU_STATE_IDLE] - lastProcessorInfo[CPU_STATE_IDLE];
120 inUse = user + sys + nice;
121 total = inUse + idle;
123 cpudata[inptr].user = (double)user / (double)total;
124 cpudata[inptr].sys = (double)sys / (double)total;
125 cpudata[inptr].nice = (double)nice / (double)total;
126 cpudata[inptr].idle = (double)idle / (double)total;
129 // deallocate the last one, since we don't want memory leaks.
131 TODO refresh: test in Shark / malloc debug: this DOES leak if we take this dealloc out, right?
133 if(lastProcessorInfo) {
134 size_t lastProcessorInfoSize = sizeof(integer_t) * numLastProcessorInfo;
135 vm_deallocate(mach_task_self(), (vm_address_t)lastProcessorInfo, lastProcessorInfoSize);
138 lastProcessorInfo = processorInfo;
139 numLastProcessorInfo = numProcessorInfo;
141 if (++inptr >= size) // advance our data ptr
152 - (BOOL)getNext:(CPUDataPtr)ptr
156 *ptr = cpudata[outptr++];
165 - (void)getCurrent:(CPUDataPtr)ptr
167 *ptr = cpudata[inptr ? inptr - 1 : size - 1];
171 - (void)getLast:(CPUDataPtr)ptr
173 *ptr = cpudata[inptr > 1 ? inptr - 2 : size + inptr - 2];