⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpustatus.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 2 页
字号:
/*     This file is part of GNUnet.     (C) 2001, 2002, 2003, 2005, 2006 Christian Grothoff (and other contributing authors)     GNUnet is free software; you can redistribute it and/or modify     it under the terms of the GNU General Public License as published     by the Free Software Foundation; either version 2, or (at your     option) any later version.     GNUnet is distributed in the hope that it will be useful, but     WITHOUT ANY WARRANTY; without even the implied warranty of     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     General Public License for more details.     You should have received a copy of the GNU General Public License     along with GNUnet; see the file COPYING.  If not, write to the     Free Software Foundation, Inc., 59 Temple Place - Suite 330,     Boston, MA 02111-1307, USA.*//** * @file util/os/cpustatus.c * @brief calls to determine current CPU load * @author Tzvetan Horozov * @author Christian Grothoff * @author Igor Wronsky * @author Alex Harper (OS X portion) */#include "platform.h"#include "gnunet_util_os.h"#include "gnunet_util_error.h"#include "gnunet_util_threads.h"#include "gnunet_util_string.h"#if SOLARIS#if HAVE_KSTAT_H#include <kstat.h>#endif#if HAVE_SYS_SYSINFO_H#include <sys/sysinfo.h>#endif#if HAVE_KVM_H#include <kvm.h>#endif#endif#if SOMEBSD#if HAVE_KVM_H#include <kvm.h>#endif#endif#ifdef OSX#include <mach-o/arch.h>#include <mach/mach.h>#include <mach/mach_error.h>static processor_cpu_load_info_t prev_cpu_load;#endif#define DEBUG_STATUSCALLS GNUNET_NO#ifdef LINUXstatic FILE *proc_stat;#endifstatic struct GNUNET_Mutex *statusMutex;/** * Current CPU load, as percentage of CPU cycles not idle or * blocked on IO. */static int currentCPULoad;static int agedCPULoad = -1;/** * Current IO load, as percentage of CPU cycles blocked on IO. */static int currentIOLoad;static int agedIOLoad = -1;#ifdef OSXstatic intinitMachCpuStats (){  unsigned int cpu_count;  processor_cpu_load_info_t cpu_load;  mach_msg_type_number_t cpu_msg_count;  kern_return_t kret;  int i, j;  kret = host_processor_info (mach_host_self (),                              PROCESSOR_CPU_LOAD_INFO,                              &cpu_count,                              (processor_info_array_t *) & cpu_load,                              &cpu_msg_count);  if (kret != KERN_SUCCESS)    {      GNUNET_GE_LOG (NULL,                     GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_ADMIN |                     GNUNET_GE_BULK, "host_processor_info failed.");      return GNUNET_SYSERR;    }  prev_cpu_load = GNUNET_malloc (cpu_count * sizeof (*prev_cpu_load));  for (i = 0; i < cpu_count; i++)    {      for (j = 0; j < CPU_STATE_MAX; j++)        {          prev_cpu_load[i].cpu_ticks[j] = cpu_load[i].cpu_ticks[j];        }    }  vm_deallocate (mach_task_self (),                 (vm_address_t) cpu_load,                 (vm_size_t) (cpu_msg_count * sizeof (*cpu_load)));  return GNUNET_OK;}#endif/** * Update the currentCPU and currentIO load values. * * Before its first invocation the method initStatusCalls() must be called. * If there is an error the method returns -1. */static intupdateUsage (){  currentIOLoad = -1;  currentCPULoad = -1;#ifdef LINUX  /* under linux, first try %idle/usage using /proc/stat;     if that does not work, disable /proc/stat for the future     by closing the file and use the next-best method. */  if (proc_stat != NULL)    {      static unsigned long long last_cpu_results[5] = { 0, 0, 0, 0, 0 };      static int have_last_cpu = GNUNET_NO;      int ret;      char line[256];      unsigned long long user_read, system_read, nice_read, idle_read,        iowait_read;      unsigned long long user, system, nice, idle, iowait;      unsigned long long usage_time = 0, total_time = 1;      /* Get the first line with the data */      rewind (proc_stat);      fflush (proc_stat);      if (NULL == fgets (line, 256, proc_stat))        {          GNUNET_GE_LOG_STRERROR_FILE (NULL,                                       GNUNET_GE_ERROR | GNUNET_GE_USER |                                       GNUNET_GE_ADMIN | GNUNET_GE_BULK,                                       "fgets", "/proc/stat");          fclose (proc_stat);          proc_stat = NULL;     /* don't try again */        }      else        {          iowait_read = 0;          ret = sscanf (line, "%*s %llu %llu %llu %llu %llu",                        &user_read,                        &system_read, &nice_read, &idle_read, &iowait_read);          if (ret < 4)            {              GNUNET_GE_LOG_STRERROR_FILE (NULL,                                           GNUNET_GE_ERROR | GNUNET_GE_USER |                                           GNUNET_GE_ADMIN | GNUNET_GE_BULK,                                           "fgets-sscanf", "/proc/stat");              fclose (proc_stat);              proc_stat = NULL; /* don't try again */              have_last_cpu = GNUNET_NO;            }          else            {              /* Store the current usage */              user = user_read - last_cpu_results[0];              system = system_read - last_cpu_results[1];              nice = nice_read - last_cpu_results[2];              idle = idle_read - last_cpu_results[3];              iowait = iowait_read - last_cpu_results[4];              /* Calculate the % usage */              usage_time = user + system + nice;              total_time = usage_time + idle + iowait;              if ((total_time > 0) && (have_last_cpu == GNUNET_YES))                {                  currentCPULoad = (int) (100L * usage_time / total_time);                  if (ret > 4)                    currentIOLoad = (int) (100L * iowait / total_time);                  else                    currentIOLoad = -1; /* 2.4 kernel */                }              /* Store the values for the next calculation */              last_cpu_results[0] = user_read;              last_cpu_results[1] = system_read;              last_cpu_results[2] = nice_read;              last_cpu_results[3] = idle_read;              last_cpu_results[4] = iowait_read;              have_last_cpu = GNUNET_YES;              return GNUNET_OK;            }        }    }#endif#ifdef OSX  {    unsigned int cpu_count;    processor_cpu_load_info_t cpu_load;    mach_msg_type_number_t cpu_msg_count;    unsigned long long t_sys, t_user, t_nice, t_idle, t_total;    unsigned long long t_idle_all, t_total_all;    kern_return_t kret;    int i, j;    t_idle_all = t_total_all = 0;    kret = host_processor_info (mach_host_self (), PROCESSOR_CPU_LOAD_INFO,                                &cpu_count,                                (processor_info_array_t *) & cpu_load,                                &cpu_msg_count);    if (kret == KERN_SUCCESS)      {        for (i = 0; i < cpu_count; i++)          {            if (cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM] >=                prev_cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM])              {                t_sys = cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM] -                  prev_cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM];              }            else              {                t_sys = cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM] +                  (ULONG_MAX - prev_cpu_load[i].cpu_ticks[CPU_STATE_SYSTEM] +                   1);              }            if (cpu_load[i].cpu_ticks[CPU_STATE_USER] >=                prev_cpu_load[i].cpu_ticks[CPU_STATE_USER])              {                t_user = cpu_load[i].cpu_ticks[CPU_STATE_USER] -                  prev_cpu_load[i].cpu_ticks[CPU_STATE_USER];              }            else              {                t_user = cpu_load[i].cpu_ticks[CPU_STATE_USER] +                  (ULONG_MAX - prev_cpu_load[i].cpu_ticks[CPU_STATE_USER] +                   1);              }            if (cpu_load[i].cpu_ticks[CPU_STATE_NICE] >=                prev_cpu_load[i].cpu_ticks[CPU_STATE_NICE])              {                t_nice = cpu_load[i].cpu_ticks[CPU_STATE_NICE] -                  prev_cpu_load[i].cpu_ticks[CPU_STATE_NICE];              }            else              {                t_nice = cpu_load[i].cpu_ticks[CPU_STATE_NICE] +                  (ULONG_MAX - prev_cpu_load[i].cpu_ticks[CPU_STATE_NICE] +                   1);              }            if (cpu_load[i].cpu_ticks[CPU_STATE_IDLE] >=                prev_cpu_load[i].cpu_ticks[CPU_STATE_IDLE])              {                t_idle = cpu_load[i].cpu_ticks[CPU_STATE_IDLE] -                  prev_cpu_load[i].cpu_ticks[CPU_STATE_IDLE];              }            else              {                t_idle = cpu_load[i].cpu_ticks[CPU_STATE_IDLE] +                  (ULONG_MAX - prev_cpu_load[i].cpu_ticks[CPU_STATE_IDLE] +                   1);              }            t_total = t_sys + t_user + t_nice + t_idle;            t_idle_all += t_idle;            t_total_all += t_total;          }        for (i = 0; i < cpu_count; i++)          {            for (j = 0; j < CPU_STATE_MAX; j++)              {                prev_cpu_load[i].cpu_ticks[j] = cpu_load[i].cpu_ticks[j];              }          }        if (t_total_all > 0)          currentCPULoad = 100 - (100 * t_idle_all) / t_total_all;        else          currentCPULoad = -1;        vm_deallocate (mach_task_self (),                       (vm_address_t) cpu_load,                       (vm_size_t) (cpu_msg_count * sizeof (*cpu_load)));        currentIOLoad = -1;     /* FIXME-OSX! */        return GNUNET_OK;      }    else      {        GNUNET_GE_LOG (NULL,                       GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_ADMIN |                       GNUNET_GE_BULK, "host_processor_info failed.");        return GNUNET_SYSERR;      }  }#endif  /* try kstat (Solaris only) */#if SOLARIS && HAVE_KSTAT_H && HAVE_SYS_SYSINFO_H  {    static long long last_idlecount;    static long long last_totalcount;    static int kstat_once;      /* if open fails, don't keep                                   trying */    kstat_ctl_t *kc;    kstat_t *khelper;    long long idlecount;    long long totalcount;    long long deltaidle;    long long deltatotal;    if (kstat_once == 1)      goto ABORT_KSTAT;    kc = kstat_open ();    if (kc == NULL)      {        GNUNET_GE_LOG_STRERROR (NULL,                                GNUNET_GE_ERROR | GNUNET_GE_USER |                                GNUNET_GE_ADMIN | GNUNET_GE_BULK,                                "kstat_open");        goto ABORT_KSTAT;      }    idlecount = 0;    totalcount = 0;    for (khelper = kc->kc_chain; khelper != NULL; khelper = khelper->ks_next)      {        cpu_stat_t stats;        if (0 != strncmp (khelper->ks_name, "cpu_stat", strlen ("cpu_stat")))          continue;        if (khelper->ks_data_size > sizeof (cpu_stat_t))          continue;             /* better save then sorry! */        if (-1 != kstat_read (kc, khelper, &stats))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -