5 // Created by Peter Hosey on 2006-06-21.
6 // Copyright 2006 Peter Hosey. All rights reserved.
8 // Modified by Christopher Bowns, starting 2007-1-1.
16 #include <sys/types.h>
19 //sysctl and its parameters
20 #include <sys/sysctl.h>
22 #include <sys/errno.h>
25 @implementation CPUInfo
29 inits cpudata, inptr, outptr
30 retrieves lastProcessorInfo for refresh method to go to town.
32 if cannot get processor info, returns nil.
34 - (CPUInfo *) initWithCapacity:(unsigned)numItems
40 //We could get the number of processors the same way that we get the CPU usage info, but that allocates memory.
41 /* enum { miblen = 2U };
42 int mib[miblen] = { CTL_HW, HW_NCPU };
43 size_t sizeOfNumCPUs = sizeof(numCPUs);
44 int status = sysctl(mib, miblen,
45 &numCPUs, &sizeOfNumCPUs,
46 */ /*newp*/ // NULL, /*newlen*/ 0U);
48 numCPUs = 1; // TODO we're going to assume one CPU for the moment.
49 // NSLog(@"%s error status, assuming one CPU", _cmd);
60 cpudata = calloc(numItems, sizeof(CPUData));
61 if (cpudata == NULL) {
62 NSLog (@"%s Failed to allocate buffer for CPUInfo", _cmd);
65 // Set up our data structure ptrs
69 // set the lastProcessorInfo array so we can get to work when we call refresh:
70 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);
71 if(err != KERN_SUCCESS) {
72 NSLog(@"%s failed to get cpu statistics", _cmd);
74 // if we can't get this info, then we're toast. Exit gracefully.
85 lastProcessorInfo and numLastProcessorInfo contain valid data from prior refresh of CPU info
87 retrieves current data
88 calculates avg cpu load over last period
89 updates cpudata array with info
90 deallocates old numLastProcInfo and lastProcessorInfo and set ptrs to new data
94 processor_info_array_t processorInfo;
95 natural_t numProcessors_nobodyCares = 0U;
96 mach_msg_type_number_t numProcessorInfo;
98 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);
99 if(err != KERN_SUCCESS) {
100 NSLog(@"%s failed to get cpu statistics", _cmd);
104 TODO make this multicore. First, we're gonna need a multicore machine to test it on.
106 // for(unsigned i = 0U; i < numCPUs; ++i)
108 unsigned int inUse, total, user, sys, nice, idle;
110 user = processorInfo[CPU_STATE_USER] - lastProcessorInfo[CPU_STATE_USER];
111 sys = processorInfo[CPU_STATE_SYSTEM] - lastProcessorInfo[CPU_STATE_SYSTEM];
112 nice = processorInfo[CPU_STATE_NICE] - lastProcessorInfo[CPU_STATE_NICE];
113 idle = processorInfo[CPU_STATE_IDLE] - lastProcessorInfo[CPU_STATE_IDLE];
115 inUse = user + sys + nice;
116 total = inUse + idle;
118 cpudata[inptr].user = (double)user / (double)total;
119 cpudata[inptr].sys = (double)sys / (double)total;
120 cpudata[inptr].nice = (double)nice / (double)total;
121 cpudata[inptr].idle = (double)idle / (double)total;
124 // deallocate the last one, since we don't want memory leaks.
126 TODO refresh: test in Shark / malloc debug: this DOES leak if we take this dealloc out, right?
128 if(lastProcessorInfo) {
129 size_t lastProcessorInfoSize = sizeof(integer_t) * numLastProcessorInfo;
130 vm_deallocate(mach_task_self(), (vm_address_t)lastProcessorInfo, lastProcessorInfoSize);
133 lastProcessorInfo = processorInfo;
134 numLastProcessorInfo = numProcessorInfo;
136 if (++inptr >= size) // advance our data ptr
147 - (BOOL)getNext:(CPUDataPtr)ptr
151 *ptr = cpudata[outptr++];
160 - (void)getCurrent:(CPUDataPtr)ptr
162 *ptr = cpudata[inptr ? inptr - 1 : size - 1];
166 - (void)getLast:(CPUDataPtr)ptr
168 *ptr = cpudata[inptr > 1 ? inptr - 2 : size + inptr - 2];