committing back changes from branch.
[cpuHistory.git] / CPUInfo.m
blob472361d2ca391804e2098c732cb1e2ee5a878d23
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
27 static processor_info_array_t getCPUStat (processor_info_array_t *cpustat, mach_msg_type_number_t *numcpustat)
29         processor_info_array_t processorInfo;
30         natural_t numProcessors_nobodyCares = 0U;
31         mach_msg_type_number_t numProcessorInfo;
33         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);
34         if(err != KERN_SUCCESS) {
35                 NSLog(@"getCPUStat: failed to get cpu statistics");
36         }
37         
38         
39         unsigned int inUse, total, user, sys, nice, idle;
40         user = processorInfo[CPU_STATE_USER];
41         sys  = processorInfo[CPU_STATE_SYSTEM];
42         nice = processorInfo[CPU_STATE_NICE];
43         idle = processorInfo[CPU_STATE_IDLE];
44         
45         inUse = user + sys + nice;
46         total = inUse + idle;
47                 
48         double dbluser = (double)user / (double)total;
49         double dblsys = (double)sys / (double)total;
50         double dblnice = (double)nice / (double)total;
51         double dblidle = (double)idle / (double)total;
52         
53         return processorInfo;
56 - (CPUInfo *) initWithCapacity:(unsigned)numItems
58         self = [super init];
59         
60         /*
61                 from CPU usage
62         */      
63         //We could get the number of processors the same way that we get the CPU usage info, but that allocates memory.
64 /*      enum { miblen = 2U };
65         int mib[miblen] = { CTL_HW, HW_NCPU };
66         size_t sizeOfNumCPUs = sizeof(numCPUs);
67         int status = sysctl(mib, miblen,
68                    &numCPUs, &sizeOfNumCPUs,
69 */                 /*newp*/ // NULL, /*newlen*/ 0U);
70 //      if(status != 0) {
71                 numCPUs = 1; // TODO we're going to assume one CPU for the moment.
72 //              NSLog(@"%s error status, assuming one CPU", _cmd);
73 //      }       
74         /*
75                 from meminfo
76         */
77         size = numItems;
78         cpudata = calloc(numItems, sizeof(CPUData));
79         if (cpudata == NULL) {
80                 NSLog (@"Failed to allocate buffer for CPUInfo");
81                 return (nil);
82         }
83         inptr = 0;
84         outptr = -1;
85         
86         getCPUStat(lastcpustat, numlastcpustat);
88         return (self);
91 - (void)refresh
93         processor_info_array_t cpustat;
94                 
95         cpustat = getCPUStat();
96         /*
97                 TODO make this multicore. First, we're gonna need a multicore machine to test it on.
98         */
99         // for(unsigned i = 0U; i < numCPUs; ++i) {
101         unsigned int inUse, total, user, sys, nice, idle;
102         user = cpustat[CPU_STATE_USER];
103         sys  = cpustat[CPU_STATE_SYSTEM];
104         nice = cpustat[CPU_STATE_NICE];
105         idle = cpustat[CPU_STATE_IDLE];
106         
107         inUse = user + sys + nice;
108         total = inUse + idle;
109                 
110         cpudata[inptr].user = (double)user / (double)total;
111         cpudata[inptr].sys = (double)sys / (double)total;
112         cpudata[inptr].nice = (double)nice / (double)total;
113         cpudata[inptr].idle = (double)idle / (double)total;
114         if(lastcpustat) {
115                                 size_t lastcpustatSize = sizeof(integer_t) * numLastProcessorInfo;
116                                 vm_deallocate(target_task, (vm_address_t)lastProcessorInfo, lastProcessorInfoSize);
117                         }
119                         lastProcessorInfo = processorInfo;
120                         numLastProcessorInfo = numProcessorInfo;
121         lastcpustat = cpustat;
122         if (++inptr >= size) // advance our data ptr
123                 inptr = 0;
127 - (void)startIterate
129         outptr = inptr;
133 - (BOOL)getNext:(CPUDataPtr)ptr
135         if (outptr == -1)
136                 return (FALSE);
137         *ptr = cpudata[outptr++];
138         if (outptr >= size)
139                 outptr = 0;
140         if (outptr == inptr)
141                 outptr = -1;
142         return (TRUE);
146 - (void)getCurrent:(CPUDataPtr)ptr
148         *ptr = cpudata[inptr ? inptr - 1 : size - 1];
152 - (void)getLast:(CPUDataPtr)ptr
154         *ptr = cpudata[inptr > 1 ? inptr - 2 : size + inptr - 2];
158 - (int)getSize
160         return (size);
163 @end