CPUInfo looks good to go. main.m is back to launching the app.
[cpuHistory.git] / CPUInfo.m
blob116cbda8dd4f3082032ca51dfacd33141de33302
1 //
2 //  CPUInfo.m
3 //  CPU Usage
4 //
5 //  Created by Peter Hosey on 2006-06-21.
6 //  Copyright 2006 Peter Hosey. All rights reserved.
7 //
8 //  Modified by Christopher Bowns, starting 2007-1-1.
10 #ifndef NSLOG_DEBUG
11 #define NSLOG_DEBUG
12 #endif
14 #import "CPUInfo.h"
16 #include <sys/types.h>
17 //sqrtf, ceilf
18 #include <math.h>
19 //sysctl and its parameters
20 #include <sys/sysctl.h>
21 //errno, strerror
22 #include <sys/errno.h>
23 #include <string.h>
25 @implementation CPUInfo
28         Accomplishes:
29                 inits cpudata, inptr, outptr
30                 retrieves lastProcessorInfo for refresh method to go to town.
31         
32         if cannot get processor info, returns nil.
34 - (CPUInfo *) initWithCapacity:(unsigned)numItems
36         
37         /*
38                 from CPU usage
39         */      
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);
47 //      if(status != 0) {
48                 numCPUs = 1; // TODO we're going to assume one CPU for the moment.
49 //              NSLog(@"%s error status, assuming one CPU", _cmd);
50 //      }
51         
52         
53         
54         
55         
56         
57         self = [super init];
58         
59         size = numItems;
60         cpudata = calloc(numItems, sizeof(CPUData));
61         if (cpudata == NULL) {
62                 NSLog (@"%s Failed to allocate buffer for CPUInfo", _cmd);
63                 return (nil);
64         }
65         // Set up our data structure ptrs
66         inptr = 0;
67         outptr = -1;
68         
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);
73                 
74                 // if we can't get this info, then we're toast. Exit gracefully.
75                 return (nil);
76         }
77         
78         return (self);
83         Assumptions:
84                 init has run.
85                 lastProcessorInfo and numLastProcessorInfo contain valid data from prior refresh of CPU info
86         Accomplishes:
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
92 - (void)refresh
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);
101         }
102         
103         /*
104                 TODO make this multicore. First, we're gonna need a multicore machine to test it on.
105         */
106         // for(unsigned i = 0U; i < numCPUs; ++i)
107         
108         unsigned int inUse, total, user, sys, nice, idle;
109                 
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;
117         
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;
122         
123         
124         // deallocate the last one, since we don't want memory leaks.
125         /*
126                 TODO refresh: test in Shark / malloc debug: this DOES leak if we take this dealloc out, right?
127         */
128         if(lastProcessorInfo) {
129                 size_t lastProcessorInfoSize = sizeof(integer_t) * numLastProcessorInfo;
130                 vm_deallocate(mach_task_self(), (vm_address_t)lastProcessorInfo, lastProcessorInfoSize);
131         }
133         lastProcessorInfo = processorInfo;
134         numLastProcessorInfo = numProcessorInfo;
135         
136         if (++inptr >= size) // advance our data ptr
137                 inptr = 0;
141 - (void)startIterate
143         outptr = inptr;
147 - (BOOL)getNext:(CPUDataPtr)ptr
149         if (outptr == -1)
150                 return (FALSE);
151         *ptr = cpudata[outptr++];
152         if (outptr >= size)
153                 outptr = 0;
154         if (outptr == inptr)
155                 outptr = -1;
156         return (TRUE);
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];
172 - (int)getSize
174         return (size);
177 @end