1 char 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 52 static host_cpu_load_info_data_t lib_start_ticks; 53 static host_cpu_load_info_data_t lib_end_ticks; 54 55 static mach_port_t lib_host_port; 56 57 void 58 cpu_util_init(void) 59 { 60 lib_host_port = mach_host_self(); 61 return; 62 } 63 64 void 65 cpu_util_terminate(void) 66 { 67 mach_port_deallocate(lib_host_port); 68 return; 69 } 70 71 int 72 get_cpu_method(void) 73 { 74 return OSX; 75 } 76 77 void 78 get_cpu_idle(uint64_t *res) 79 { 80 return; 81 } 82 83 void 84 get_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 96 float 97 calibrate_idle_rate(int iterations, int interval) 98 { 99 return (float)0.0; 100 } 101 102 float 103 calc_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 } 139 void 140 cpu_start_internal(void) 141 { 142 get_host_ticks(&lib_start_ticks); 143 } 144 145 void 146 cpu_stop_internal(void) 147 { 148 get_host_ticks(&lib_end_ticks); 149 } 150