1 char   netcpu_sysctl_id[]="\
2 @(#)netcpu_osx.c  Version 2.6.0";
3 
4 #if HAVE_CONFIG_H
5 # include <config.h>
6 #endif
7 
8 #include <stdio.h>
9 
10 #if HAVE_INTTYPES_H
11 # include <inttypes.h>
12 #else
13 # if HAVE_STDINT_H
14 #  include <stdint.h>
15 # endif
16 #endif
17 
18 #if TIME_WITH_SYS_TIME
19 # include <sys/time.h>
20 # include <time.h>
21 #else
22 # if HAVE_SYS_TIME_H
23 #  include <sys/time.h>
24 # else
25 #  include <time.h>
26 # endif
27 #endif
28 #if HAVE_LIMITS_H
29 # include <limits.h>
30 # ifndef LONG_LONG_MAX
31 #  define LONG_LONG_MAX LLONG_MAX
32 # endif /* LONG_LONG_MAX */
33 #endif
34 
35 
36 #include <errno.h>
37 
38 #include <mach/host_info.h>
39 #include <mach/mach_types.h>
40 /* it would seem that on 10.3.9 mach_msg_type_number_t is in
41    <mach/message.h> so we'll see about including that one too.
42    hopefully it still exists in 10.4. if not, we will need to add some
43    .h file checks in configure so we can use "HAVE_mumble" ifdefs
44    here */
45 #include <mach/message.h>
46 
47 /* some of this is to make Tiger (10.4), Leopard (10.5) and
48    SnowLeopard (10.6) happy, we hope it does not anger previous
49    versions */
50 #include <mach/mach_host.h>
51 /* #include <mach/mach_port.h> */
52 
53 #include "netsh.h"
54 #include "netlib.h"
55 
56 #define UNSIGNED_DIFFERENCE(x,y) (x >= y ? x - y : (0 - y) + x )
57 
58 static host_cpu_load_info_data_t lib_start_ticks;
59 static host_cpu_load_info_data_t lib_end_ticks;
60 
61 static mach_port_t lib_host_port;
62 
63 void
cpu_util_init(void)64 cpu_util_init(void)
65 {
66   lib_host_port = mach_host_self();
67   return;
68 }
69 
70 void
cpu_util_terminate(void)71 cpu_util_terminate(void)
72 {
73   mach_port_deallocate(lib_host_port);
74   return;
75 }
76 
77 int
get_cpu_method(void)78 get_cpu_method(void)
79 {
80   return OSX;
81 }
82 
83 void
get_cpu_idle(uint64_t * res)84 get_cpu_idle(uint64_t *res)
85 {
86     return;
87 }
88 
89 void
get_host_ticks(host_cpu_load_info_t info)90 get_host_ticks(host_cpu_load_info_t info)
91 {
92   mach_msg_type_number_t count;
93 
94   count = HOST_CPU_LOAD_INFO_COUNT;
95   host_statistics(lib_host_port, HOST_CPU_LOAD_INFO, (host_info_t)info, &count);
96   return;
97 }
98 
99 /* calibrate_sysctl  - perform the idle rate calculation using the
100    sysctl call - typically on BSD */
101 
102 float
calibrate_idle_rate(int iterations,int interval)103 calibrate_idle_rate(int iterations, int interval)
104 {
105     return (float)0.0;
106 }
107 
108 float
calc_cpu_util_internal(float elapsed_time)109 calc_cpu_util_internal(float elapsed_time)
110 {
111   float correction_factor;
112   natural_t	userticks, systicks, idleticks, totalticks;
113 
114   memset(&lib_local_cpu_stats, 0, sizeof(lib_local_cpu_stats));
115 
116   /* It is possible that the library measured a time other than the
117      one that the user want for the cpu utilization calculations - for
118      example, tests that were ended by watchdog timers such as the udp
119      stream test. We let these tests tell up what the elapsed time
120      should be. */
121 
122   if (elapsed_time != 0.0) {
123     correction_factor = (float) 1.0 +
124       ((lib_elapsed - elapsed_time) / elapsed_time);
125   }
126   else {
127     correction_factor = (float) 1.0;
128   }
129 
130   if (debug) {
131     fprintf(where, "correction factor: %f\n", correction_factor);
132   }
133 
134   userticks = UNSIGNED_DIFFERENCE((lib_end_ticks.cpu_ticks[CPU_STATE_USER] + lib_end_ticks.cpu_ticks[CPU_STATE_NICE]),
135 				  (lib_start_ticks.cpu_ticks[CPU_STATE_USER] + lib_start_ticks.cpu_ticks[CPU_STATE_NICE]));
136   systicks = UNSIGNED_DIFFERENCE(lib_end_ticks.cpu_ticks[CPU_STATE_SYSTEM], lib_start_ticks.cpu_ticks[CPU_STATE_SYSTEM]);
137   idleticks = UNSIGNED_DIFFERENCE(lib_end_ticks.cpu_ticks[CPU_STATE_IDLE], lib_start_ticks.cpu_ticks[CPU_STATE_IDLE]);
138   totalticks = userticks + systicks + idleticks;
139 
140   lib_local_cpu_stats.cpu_util = ((float)userticks
141                                   + (float)systicks)/(float)totalticks * 100.0f;
142   lib_local_cpu_stats.cpu_util *= correction_factor;
143 
144   return lib_local_cpu_stats.cpu_util;
145 
146 }
147 void
cpu_start_internal(void)148 cpu_start_internal(void)
149 {
150     get_host_ticks(&lib_start_ticks);
151 }
152 
153 void
cpu_stop_internal(void)154 cpu_stop_internal(void)
155 {
156     get_host_ticks(&lib_end_ticks);
157 }
158