Adding release notes licensing for 1.0.1, and a patch from @dsandler for multicore...
[cpuHistory.git] / cpuhistory-multiproc.patch
blob5faaf7dc878a02eef010581d19eba3d70ff1c2d5
1 From 4d2001fee99e46d5dc2099dee89cec68430e7fa6 Mon Sep 17 00:00:00 2001
2 From: Daniel Sandler <dsandler@river.cs.rice.edu>
3 Date: Sun, 27 Jan 2008 00:00:32 -0600
4 Subject: [PATCH] Implement multiple CPU support. Tested on MacBook (Core Duo) only.
6 ---
7 CPUInfo.h | 11 +++--
8 CPUInfo.m | 87 ++++++++++++++++++++++----------------
9 MainController.m | 123 +++++++++++++++++++++++++++++++-----------------------
10 3 files changed, 127 insertions(+), 94 deletions(-)
12 diff --git a/CPUInfo.h b/CPUInfo.h
13 index a96f491..be3ae43 100644
14 --- a/CPUInfo.h
15 +++ b/CPUInfo.h
16 @@ -25,10 +25,10 @@ typedef struct cpudata {
17 } CPUData, *CPUDataPtr;
19 @interface CPUInfo : NSObject {
20 - processor_info_array_t lastProcessorInfo;
21 + processor_cpu_load_info_t lastProcessorInfo;
22 mach_msg_type_number_t numLastProcessorInfo;
23 unsigned numCPUs;
24 - CPUDataPtr cpudata;
25 + CPUDataPtr *allcpudata;
26 int size;
27 int inptr;
28 int outptr;
29 @@ -36,10 +36,11 @@ typedef struct cpudata {
31 - (CPUInfo *)initWithCapacity:(unsigned)numItems;
32 - (void)refresh;
33 +- (unsigned)numCPUs;
34 - (void)startIterate;
35 -- (BOOL)getNext:(CPUDataPtr)ptr;
36 -- (void)getCurrent:(CPUDataPtr)ptr;
37 -- (void)getLast:(CPUDataPtr)ptr;
38 +- (BOOL)getNext:(CPUDataPtr)ptr forCPU:(unsigned)cpu;
39 +- (void)getCurrent:(CPUDataPtr)ptr forCPU:(unsigned)cpu;
40 +- (void)getLast:(CPUDataPtr)ptr forCPU:(unsigned)cpu;
41 - (int)getSize;
43 @end
44 diff --git a/CPUInfo.m b/CPUInfo.m
45 index 77d935d..ad1a659 100644
46 --- a/CPUInfo.m
47 +++ b/CPUInfo.m
48 @@ -37,35 +37,34 @@
50 - (CPUInfo *) initWithCapacity:(unsigned)numItems
53 + unsigned i;
56 from Hosey's CPU Usage.app:
57 */
58 //We could get the number of processors the same way that we get the CPU usage info, but that allocates memory.
59 -/* enum { miblen = 2U };
60 + enum { miblen = 2U };
61 int mib[miblen] = { CTL_HW, HW_NCPU };
62 size_t sizeOfNumCPUs = sizeof(numCPUs);
63 int status = sysctl(mib, miblen,
64 &numCPUs, &sizeOfNumCPUs,
65 -*/ /*newp*/ // NULL, /*newlen*/ 0U);
66 -// if(status != 0) {
67 + NULL, /*newlen*/ 0U);
68 + if(status != 0) {
69 numCPUs = 1; // TODO we're going to assume one CPU for the moment.
70 -// NSLog(@"%s error status, assuming one CPU", _cmd);
71 -// }
77 + NSLog(@"%s error status, assuming one CPU", _cmd);
78 + }
80 self = [super init];
82 size = numItems;
83 - cpudata = calloc(numItems, sizeof(CPUData));
84 - if (cpudata == NULL) {
85 + allcpudata = calloc(numCPUs, sizeof(CPUDataPtr));
86 + if (allcpudata == NULL) {
87 NSLog (@"%s Failed to allocate buffer for CPUInfo", _cmd);
88 return (nil);
90 + for(i = 0; i < numCPUs; i++) {
91 + allcpudata[i] = calloc(numItems, sizeof(CPUData));
92 + }
93 // Set up our data structure ptrs
94 inptr = 0;
95 outptr = -1;
96 @@ -96,11 +95,16 @@
98 - (void)refresh
100 - processor_info_array_t processorInfo;
101 - natural_t numProcessors_nobodyCares = 0U;
102 + processor_cpu_load_info_t processorInfo;
103 + natural_t numProcessors;
104 mach_msg_type_number_t numProcessorInfo;
105 + unsigned i;
107 - 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);
108 + kern_return_t err = host_processor_info(mach_host_self(),
109 + PROCESSOR_CPU_LOAD_INFO,
110 + (natural_t *)&numProcessors,
111 + (processor_info_array_t *)&processorInfo,
112 + (mach_msg_type_number_t *)&numProcessorInfo);
113 if(err != KERN_SUCCESS) {
114 NSLog(@"%s failed to get cpu statistics", _cmd);
116 @@ -108,23 +112,30 @@
118 TODO make this multicore. First, we're gonna need a multicore machine to test it on.
120 - // for(unsigned i = 0U; i < numCPUs; ++i)
122 - unsigned int inUse, total, user, sys, nice, idle;
124 - user = processorInfo[CPU_STATE_USER] - lastProcessorInfo[CPU_STATE_USER];
125 - sys = processorInfo[CPU_STATE_SYSTEM] - lastProcessorInfo[CPU_STATE_SYSTEM];
126 - nice = processorInfo[CPU_STATE_NICE] - lastProcessorInfo[CPU_STATE_NICE];
127 - idle = processorInfo[CPU_STATE_IDLE] - lastProcessorInfo[CPU_STATE_IDLE];
129 - inUse = user + sys + nice;
130 - total = inUse + idle;
132 - cpudata[inptr].user = (double)user / (double)total;
133 - cpudata[inptr].sys = (double)sys / (double)total;
134 - cpudata[inptr].nice = (double)nice / (double)total;
135 - cpudata[inptr].idle = (double)idle / (double)total;
136 + for(i = 0U; i < numCPUs; ++i) {
137 + // NB: numCPUs ought to be the same as numProcessors -- otherwise ...?
138 + assert(numCPUs == numProcessors);
139 + assert(numProcessorInfo == numProcessors * CPU_STATE_MAX);
141 + CPUDataPtr cpudata = allcpudata[i];
143 + unsigned int inUse, total, user, sys, nice, idle;
145 + user = processorInfo[i].cpu_ticks[CPU_STATE_USER] - lastProcessorInfo[i].cpu_ticks[CPU_STATE_USER];
146 + sys = processorInfo[i].cpu_ticks[CPU_STATE_SYSTEM] - lastProcessorInfo[i].cpu_ticks[CPU_STATE_SYSTEM];
147 + nice = processorInfo[i].cpu_ticks[CPU_STATE_NICE] - lastProcessorInfo[i].cpu_ticks[CPU_STATE_NICE];
148 + idle = processorInfo[i].cpu_ticks[CPU_STATE_IDLE] - lastProcessorInfo[i].cpu_ticks[CPU_STATE_IDLE];
150 + inUse = user + sys + nice;
151 + total = inUse + idle;
153 + cpudata[inptr].user = (double)user / (double)total;
154 + cpudata[inptr].sys = (double)sys / (double)total;
155 + cpudata[inptr].nice = (double)nice / (double)total;
156 + cpudata[inptr].idle = (double)idle / (double)total;
157 + NSLog(@"CPU %d: IDLE: %f\n", i, (double)idle / (double)total);
160 // deallocate the last one, since we don't want memory leaks.
162 @@ -149,11 +160,11 @@
166 -- (BOOL)getNext:(CPUDataPtr)ptr
167 +- (BOOL)getNext:(CPUDataPtr)ptr forCPU:(unsigned)cpu
169 if (outptr == -1)
170 return (FALSE);
171 - *ptr = cpudata[outptr++];
172 + *ptr = allcpudata[cpu][outptr++];
173 if (outptr >= size)
174 outptr = 0;
175 if (outptr == inptr)
176 @@ -162,15 +173,15 @@
180 -- (void)getCurrent:(CPUDataPtr)ptr
181 +- (void)getCurrent:(CPUDataPtr)ptr forCPU:(unsigned)cpu
183 - *ptr = cpudata[inptr ? inptr - 1 : size - 1];
184 + *ptr = allcpudata[cpu][inptr ? inptr - 1 : size - 1];
188 -- (void)getLast:(CPUDataPtr)ptr
189 +- (void)getLast:(CPUDataPtr)ptr forCPU:(unsigned)cpu
191 - *ptr = cpudata[inptr > 1 ? inptr - 2 : size + inptr - 2];
192 + *ptr = allcpudata[cpu][inptr > 1 ? inptr - 2 : size + inptr - 2];
196 @@ -179,4 +190,6 @@
197 return (size);
200 +- (unsigned)numCPUs { return (numCPUs); }
202 @end
203 diff --git a/MainController.m b/MainController.m
204 index 403dbe5..5a5e911 100644
205 --- a/MainController.m
206 +++ b/MainController.m
207 @@ -61,38 +61,49 @@
209 CPUData cpudata;
212 + unsigned cpu;
213 + float height = GRAPH_SIZE / [cpuInfo numCPUs];
214 + float width = GRAPH_SIZE;
215 int x;
216 - float y, yy;
217 + float y, yy = 0;
218 int barWidth = (int)[[preferences objectForKey:BAR_WIDTH_SIZE_KEY] floatValue];
219 // double interval = 0.1 * [[preferences objectForKey:UPDATE_FREQUENCY_KEY] floatValue];
221 [graphImage lockFocus];
223 // draw the cpu usage graph
225 [cpuInfo startIterate];
226 - // for (x = 0; [memInfo getNext:&vmdata]; x++) {
227 - for (x = 0; [cpuInfo getNext:&cpudata]; x+=barWidth) {
229 - // y += vmdata.active * GRAPH_SIZE;
230 - y = cpudata.sys * GRAPH_SIZE;
231 - [[preferences objectForKey:SYS_COLOR_KEY] set];
232 - NSRectFill (NSMakeRect(x - barWidth, 0.0, x, y));
233 - yy = y;
234 - // y += vmdata.inactive * GRAPH_SIZE;
235 - y += cpudata.nice * GRAPH_SIZE;
236 - [[preferences objectForKey:NICE_COLOR_KEY] set];
237 - NSRectFill (NSMakeRect(x - barWidth, yy, x, y));
238 - // y = vmdata.wired * GRAPH_SIZE;
239 - yy = y;
241 - y += cpudata.user * GRAPH_SIZE;
242 - [[preferences objectForKey:USER_COLOR_KEY] set];
243 - NSRectFill (NSMakeRect(x - barWidth, yy, x, y));
245 - // free data here
246 + for (cpu = 0; cpu < [cpuInfo numCPUs]; cpu++ ) {
247 + yy = cpu * height;
249 [[preferences objectForKey:IDLE_COLOR_KEY] set];
250 - NSRectFill (NSMakeRect(x - barWidth, y, x, GRAPH_SIZE));
251 + NSRectFill(NSMakeRect(0, yy, width, yy + height));
253 + // for (x = 0; [memInfo getNext:&vmdata]; x++) {
254 + for (x = 0; [cpuInfo getNext:&cpudata forCPU:cpu]; x+=barWidth) {
255 + // y += vmdata.active * GRAPH_SIZE;
256 + y = yy + cpudata.sys * height;
257 + [[preferences objectForKey:SYS_COLOR_KEY] set];
258 + NSRectFill (NSMakeRect(x - barWidth, yy, x, y));
259 + yy = y;
260 + // y += vmdata.inactive * GRAPH_SIZE;
261 + y += cpudata.nice * height;
262 + [[preferences objectForKey:NICE_COLOR_KEY] set];
263 + NSRectFill (NSMakeRect(x - barWidth, yy, x, y));
264 + // y = vmdata.wired * GRAPH_SIZE;
265 + yy = y;
267 + y += cpudata.user * height;
268 + [[preferences objectForKey:USER_COLOR_KEY] set];
269 + NSRectFill (NSMakeRect(x - barWidth, yy, x, y));
270 + yy = y;
272 + // free data here
273 + y += cpudata.idle * height;
274 + [[preferences objectForKey:IDLE_COLOR_KEY] set];
275 + NSRectFill (NSMakeRect(x - barWidth, yy, x, y));
279 // transfer graph image to icon image
280 @@ -110,7 +121,10 @@
281 // VMData vmdata, vmdata0;
282 CPUData cpudata, cpudata0;
283 int barWidth = (int)[[preferences objectForKey:BAR_WIDTH_SIZE_KEY] floatValue];
284 - float y, yy;
285 + float y, yy = 0;
286 + unsigned cpu;
287 + float height = GRAPH_SIZE / [cpuInfo numCPUs];
288 + float width = GRAPH_SIZE;
290 // double interval = 0.1 * [[preferences objectForKey:UPDATE_FREQUENCY_KEY] floatValue];
292 @@ -119,34 +133,39 @@
293 // offset the old graph image
294 [graphImage compositeToPoint:NSMakePoint(-barWidth, 0) operation:NSCompositeCopy];
296 - // [memInfo getLast:&vmdata0];
297 - [cpuInfo getLast:&cpudata0];
298 - // [memInfo getCurrent:&vmdata];
299 - [cpuInfo getCurrent:&cpudata];
301 - // draw chronological graph into graph image
303 - // y += vmdata.active * GRAPH_SIZE;
304 - y = cpudata.sys * GRAPH_SIZE;
305 - [[preferences objectForKey:SYS_COLOR_KEY] set];
306 - NSRectFill (NSMakeRect(GRAPH_SIZE - barWidth, 0.0, GRAPH_SIZE - barWidth, y));
307 - yy = y;
309 - // y += vmdata.inactive * GRAPH_SIZE;
310 - y += cpudata.nice * GRAPH_SIZE;
311 - [[preferences objectForKey:NICE_COLOR_KEY] set];
312 - NSRectFill (NSMakeRect(GRAPH_SIZE - barWidth, yy, GRAPH_SIZE - barWidth, y));
313 - yy = y;
315 - // y = vmdata.wired * GRAPH_SIZE;
316 - y += cpudata.user * GRAPH_SIZE;
317 - [[preferences objectForKey:USER_COLOR_KEY] set];
318 - NSRectFill (NSMakeRect(GRAPH_SIZE - barWidth, yy, GRAPH_SIZE - barWidth, y));
320 - // free data here
321 - [[preferences objectForKey:IDLE_COLOR_KEY] set];
322 - NSRectFill (NSMakeRect(GRAPH_SIZE - barWidth, y, GRAPH_SIZE - barWidth, GRAPH_SIZE));
324 + for (cpu = 0; cpu < [cpuInfo numCPUs]; cpu++ ) {
325 + yy = cpu * height;
327 + // [memInfo getLast:&vmdata0];
328 + [cpuInfo getLast:&cpudata0 forCPU:cpu];
329 + // [memInfo getCurrent:&vmdata];
330 + [cpuInfo getCurrent:&cpudata forCPU:cpu];
332 + // draw chronological graph into graph image
334 + // y += vmdata.active * GRAPH_SIZE;
335 + y = yy;
336 + [[preferences objectForKey:SYS_COLOR_KEY] set];
337 + NSRectFill (NSMakeRect(width - barWidth, yy, width - barWidth, y));
338 + yy = y;
340 + // y += vmdata.inactive * GRAPH_SIZE;
341 + y += cpudata.nice * height;
342 + [[preferences objectForKey:NICE_COLOR_KEY] set];
343 + NSRectFill (NSMakeRect(width - barWidth, yy, width - barWidth, y));
344 + yy = y;
346 + // y = vmdata.wired * GRAPH_SIZE;
347 + y += cpudata.user * height;
348 + [[preferences objectForKey:USER_COLOR_KEY] set];
349 + NSRectFill (NSMakeRect(width - barWidth, yy, width - barWidth, y));
350 + yy = y;
352 + // free data here
353 + y += cpudata.idle * height;
354 + [[preferences objectForKey:IDLE_COLOR_KEY] set];
355 + NSRectFill (NSMakeRect(width - barWidth, yy, width - barWidth, y));
358 // transfer graph image to icon image
359 [graphImage unlockFocus];
361 1.5.2.4