1char   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
58static host_cpu_load_info_data_t lib_start_ticks;
59static host_cpu_load_info_data_t lib_end_ticks;
60
61static mach_port_t lib_host_port;
62
63void
64cpu_util_init(void)
65{
66  lib_host_port = mach_host_self();
67  return;
68}
69
70void
71cpu_util_terminate(void)
72{
73  mach_port_deallocate(lib_host_port);
74  return;
75}
76
77int
78get_cpu_method(void)
79{
80  return OSX;
81}
82
83void
84get_cpu_idle(uint64_t *res)
85{
86    return;
87}
88
89void
90get_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
102float
103calibrate_idle_rate(int iterations, int interval)
104{
105    return (float)0.0;
106}
107
108float
109calc_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}
147void
148cpu_start_internal(void)
149{
150    get_host_ticks(&lib_start_ticks);
151}
152
153void
154cpu_stop_internal(void)
155{
156    get_host_ticks(&lib_end_ticks);
157}
158