1char   netcpu_sysctl_id[]="\
2@(#)netcpu_osx.c  Version 2.4.3";
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#include "netsh.h"
48#include "netlib.h"
49
50#define UNSIGNED_DIFFERENCE(x,y) (x >= y ? x - y : (0 - y) + x )
51
52static host_cpu_load_info_data_t lib_start_ticks;
53static host_cpu_load_info_data_t lib_end_ticks;
54
55static mach_port_t lib_host_port;
56
57void
58cpu_util_init(void)
59{
60  lib_host_port = mach_host_self();
61  return;
62}
63
64void
65cpu_util_terminate(void)
66{
67  mach_port_deallocate(lib_host_port);
68  return;
69}
70
71int
72get_cpu_method(void)
73{
74  return OSX;
75}
76
77void
78get_cpu_idle(uint64_t *res)
79{
80    return;
81}
82
83void
84get_host_ticks(host_cpu_load_info_t info)
85{
86  mach_msg_type_number_t count;
87
88  count = HOST_CPU_LOAD_INFO_COUNT;
89  host_statistics(lib_host_port, HOST_CPU_LOAD_INFO, (host_info_t)info, &count);
90  return;
91}
92
93/* calibrate_sysctl  - perform the idle rate calculation using the
94   sysctl call - typically on BSD */
95
96float
97calibrate_idle_rate(int iterations, int interval)
98{
99    return (float)0.0;
100}
101
102float
103calc_cpu_util_internal(float elapsed_time)
104{
105  float correction_factor;
106  natural_t	userticks, systicks, idleticks, totalticks;
107
108  lib_local_cpu_util = (float)0.0;
109  /* It is possible that the library measured a time other than */
110  /* the one that the user want for the cpu utilization */
111  /* calculations - for example, tests that were ended by */
112  /* watchdog timers such as the udp stream test. We let these */
113  /* tests tell up what the elapsed time should be. */
114
115  if (elapsed_time != 0.0) {
116    correction_factor = (float) 1.0 +
117      ((lib_elapsed - elapsed_time) / elapsed_time);
118  }
119  else {
120    correction_factor = (float) 1.0;
121  }
122
123  if (debug) {
124    fprintf(where, "correction factor: %f\n", correction_factor);
125  }
126
127  userticks = UNSIGNED_DIFFERENCE((lib_end_ticks.cpu_ticks[CPU_STATE_USER] + lib_end_ticks.cpu_ticks[CPU_STATE_NICE]),
128				  (lib_start_ticks.cpu_ticks[CPU_STATE_USER] + lib_start_ticks.cpu_ticks[CPU_STATE_NICE]));
129  systicks = UNSIGNED_DIFFERENCE(lib_end_ticks.cpu_ticks[CPU_STATE_SYSTEM], lib_start_ticks.cpu_ticks[CPU_STATE_SYSTEM]);
130  idleticks = UNSIGNED_DIFFERENCE(lib_end_ticks.cpu_ticks[CPU_STATE_IDLE], lib_start_ticks.cpu_ticks[CPU_STATE_IDLE]);
131  totalticks = userticks + systicks + idleticks;
132
133  lib_local_cpu_util = ((float)userticks + (float)systicks)/(float)totalticks * 100.0f;
134  lib_local_cpu_util *= correction_factor;
135
136  return lib_local_cpu_util;
137
138}
139void
140cpu_start_internal(void)
141{
142    get_host_ticks(&lib_start_ticks);
143}
144
145void
146cpu_stop_internal(void)
147{
148    get_host_ticks(&lib_end_ticks);
149}
150