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
32 inits cpudata, inptr, outptr
33 retrieves lastProcessorInfo for refresh method to go to town.
35 if cannot get processor info, returns nil.
37 - (CPUInfo *) initWithCapacity:(unsigned)numItems
43 //We could get the number of processors the same way that we get the CPU usage info, but that allocates memory.
44 /* enum { miblen = 2U };
45 int mib[miblen] = { CTL_HW, HW_NCPU };
46 size_t sizeOfNumCPUs = sizeof(numCPUs);
47 int status = sysctl(mib, miblen,
48 &numCPUs, &sizeOfNumCPUs,
49 */ /*newp*/ // NULL, /*newlen*/ 0U);
51 numCPUs = 1; // TODO we're going to assume one CPU for the moment.
52 // NSLog(@"%s error status, assuming one CPU", _cmd);
63 cpudata = calloc(numItems, sizeof(CPUData));
64 if (cpudata == NULL) {
65 NSLog (@"%s Failed to allocate buffer for CPUInfo", _cmd);
68 // Set up our data structure ptrs
72 // set the lastProcessorInfo array so we can get to work when we call refresh:
73 natural_t numProcessors_nobodyCares = 0U;
74 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);
75 if(err != KERN_SUCCESS) {
76 NSLog(@"%s failed to get cpu statistics", _cmd);
78 // if we can't get this info, then we're toast. Exit gracefully.
89 lastProcessorInfo and numLastProcessorInfo contain valid data from prior refresh of CPU info
91 retrieves current data
92 calculates avg cpu load over last period
93 updates cpudata array with info
94 deallocates old numLastProcInfo and lastProcessorInfo and set ptrs to new data
98 processor_info_array_t processorInfo;
99 natural_t numProcessors_nobodyCares = 0U;
100 mach_msg_type_number_t numProcessorInfo;
102 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);
103 if(err != KERN_SUCCESS) {
104 NSLog(@"%s failed to get cpu statistics", _cmd);
108 TODO make this multicore. First, we're gonna need a multicore machine to test it on.
110 // for(unsigned i = 0U; i < numCPUs; ++i)
112 unsigned int inUse, total, user, sys, nice, idle;
114 user = processorInfo[CPU_STATE_USER] - lastProcessorInfo[CPU_STATE_USER];
115 sys = processorInfo[CPU_STATE_SYSTEM] - lastProcessorInfo[CPU_STATE_SYSTEM];
116 nice = processorInfo[CPU_STATE_NICE] - lastProcessorInfo[CPU_STATE_NICE];
117 idle = processorInfo[CPU_STATE_IDLE] - lastProcessorInfo[CPU_STATE_IDLE];
119 inUse = user + sys + nice;
120 total = inUse + idle;
122 cpudata[inptr].user = (double)user / (double)total;
123 cpudata[inptr].sys = (double)sys / (double)total;
124 cpudata[inptr].nice = (double)nice / (double)total;
125 cpudata[inptr].idle = (double)idle / (double)total;
128 // deallocate the last one, since we don't want memory leaks.
130 TODO refresh: test in Shark / malloc debug: this DOES leak if we take this dealloc out, right?
132 if(lastProcessorInfo) {
133 size_t lastProcessorInfoSize = sizeof(integer_t) * numLastProcessorInfo;
134 vm_deallocate(mach_task_self(), (vm_address_t)lastProcessorInfo, lastProcessorInfoSize);
137 lastProcessorInfo = processorInfo;
138 numLastProcessorInfo = numProcessorInfo;
140 if (++inptr >= size) // advance our data ptr
151 - (BOOL)getNext:(CPUDataPtr)ptr
155 *ptr = cpudata[outptr++];
164 - (void)getCurrent:(CPUDataPtr)ptr
166 *ptr = cpudata[inptr ? inptr - 1 : size - 1];
170 - (void)getLast:(CPUDataPtr)ptr
172 *ptr = cpudata[inptr > 1 ? inptr - 2 : size + inptr - 2];