value hh_processor_info()

in src/hack_forked/utils/sys/processor_info.c [53:117]


value hh_processor_info(void) {
  CAMLparam0();
  CAMLlocal3(result, array, info);

  processor_cpu_load_info_t cpu_load_info;
  mach_msg_type_number_t msg_count;
  char buf[256];

  double total_user = 0, total_nice = 0, total_system = 0, total_idle = 0;
  int i;
  long ticks_per_second = sysconf(_SC_CLK_TCK);
  natural_t num_cpus;

  kern_return_t ret = host_processor_info(
      mach_host_self(),
      PROCESSOR_CPU_LOAD_INFO,
      &num_cpus,
      (processor_info_array_t*)&cpu_load_info,
      &msg_count);

  if (ret) {
    snprintf(buf, 256, "host_processor_info error: %s", mach_error_string(ret));
    caml_failwith(buf);
  }

  array = caml_alloc_tuple(num_cpus);

  for (i = 0; i < num_cpus; i++) {
    info = caml_alloc(4, Double_array_tag);
    Store_double_field(
        info,
        CPU_INFO_USER,
        cpu_load_info[i].cpu_ticks[CPU_STATE_USER] / ticks_per_second);
    Store_double_field(
        info,
        CPU_INFO_USER_NICE,
        cpu_load_info[i].cpu_ticks[CPU_STATE_NICE] / ticks_per_second);
    Store_double_field(
        info,
        CPU_INFO_SYSTEM,
        cpu_load_info[i].cpu_ticks[CPU_STATE_SYSTEM] / ticks_per_second);
    Store_double_field(
        info,
        CPU_INFO_IDLE,
        cpu_load_info[i].cpu_ticks[CPU_STATE_IDLE] / ticks_per_second);
    Store_field(array, i, info);

    total_user += cpu_load_info[i].cpu_ticks[CPU_STATE_USER];
    total_nice += cpu_load_info[i].cpu_ticks[CPU_STATE_NICE];
    total_system += cpu_load_info[i].cpu_ticks[CPU_STATE_SYSTEM];
    total_idle += cpu_load_info[i].cpu_ticks[CPU_STATE_IDLE];
  }

  info = caml_alloc(4, Double_array_tag);
  Store_double_field(info, CPU_INFO_USER, total_user / ticks_per_second);
  Store_double_field(info, CPU_INFO_USER_NICE, total_nice / ticks_per_second);
  Store_double_field(info, CPU_INFO_SYSTEM, total_system / ticks_per_second);
  Store_double_field(info, CPU_INFO_IDLE, total_idle / ticks_per_second);

  result = caml_alloc_tuple(2);
  Store_field(result, PROCESSOR_INFO_PROC_TOTALS, info);
  Store_field(result, PROCESSOR_INFO_PROC_PER_CPU, array);

  CAMLreturn(result);
}