📄 cpustatus.c
字号:
{ idlecount += stats.cpu_sysinfo.cpu[CPU_IDLE]; totalcount += stats.cpu_sysinfo.cpu[CPU_IDLE] + stats.cpu_sysinfo.cpu[CPU_USER] + stats.cpu_sysinfo.cpu[CPU_KERNEL] + stats.cpu_sysinfo.cpu[CPU_WAIT]; } } if (0 != kstat_close (kc)) GNUNET_GE_LOG_STRERROR (NULL, GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER | GNUNET_GE_BULK, "kstat_close"); if ((idlecount == 0) && (totalcount == 0)) goto ABORT_KSTAT; /* no stats found => abort */ deltaidle = idlecount - last_idlecount; deltatotal = totalcount - last_totalcount; if ((deltatotal > 0) && (last_totalcount > 0)) { currentCPULoad = (unsigned int) (100.0 * deltaidle / deltatotal); if (currentCPULoad > 100) currentCPULoad = 100; /* odd */ if (currentCPULoad < 0) currentCPULoad = 0; /* odd */ currentCPULoad = 100 - currentCPULoad; /* computed idle-load before! */ } else currentCPULoad = -1; currentIOLoad = -1; /* FIXME-SOLARIS! */ last_idlecount = idlecount; last_totalcount = totalcount; return GNUNET_OK; ABORT_KSTAT: kstat_once = 1; /* failed, don't try again */ return GNUNET_SYSERR; }#endif /* insert methods better than getloadavg for other platforms HERE! */ /* ok, maybe we have getloadavg on this platform */#if HAVE_GETLOADAVG { static int warnOnce = 0; double loadavg; if (1 != getloadavg (&loadavg, 1)) { /* only warn once, if there is a problem with getloadavg, we're going to hit it frequently... */ if (warnOnce == 0) { warnOnce = 1; GNUNET_GE_LOG_STRERROR (NULL, GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_ADMIN | GNUNET_GE_BULK, "getloadavg"); } return GNUNET_SYSERR; } else { /* success with getloadavg */ currentCPULoad = (int) (100 * loadavg); currentIOLoad = -1; /* FIXME */ return GNUNET_OK; } }#endif#if MINGW /* Win NT? */ if (GNNtQuerySystemInformation) { static double dLastKernel; static double dLastIdle; static double dLastUser; double dKernel; double dIdle; double dUser; double dDiffKernel; double dDiffIdle; double dDiffUser; SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION theInfo; if (GNNtQuerySystemInformation (SystemProcessorPerformanceInformation, &theInfo, sizeof (theInfo), NULL) == NO_ERROR) { /* PORT-ME MINGW: Multi-processor? */ dKernel = Li2Double (theInfo.KernelTime); dIdle = Li2Double (theInfo.IdleTime); dUser = Li2Double (theInfo.UserTime); dDiffKernel = dKernel - dLastKernel; dDiffIdle = dIdle - dLastIdle; dDiffUser = dUser - dLastUser; if (((dDiffKernel + dDiffUser) > 0) && (dLastIdle + dLastKernel + dLastUser > 0)) currentCPULoad = 100.0 - (dDiffIdle / (dDiffKernel + dDiffUser)) * 100.0; else currentCPULoad = -1; /* don't know (yet) */ dLastKernel = dKernel; dLastIdle = dIdle; dLastUser = dUser; currentIOLoad = -1; /* FIXME-MINGW */ return GNUNET_OK; } else { /* only warn once, if there is a problem with NtQuery..., we're going to hit it frequently... */ static int once; if (once == 0) { once = 1; GNUNET_GE_LOG (NULL, GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_ADMIN | GNUNET_GE_BULK, _("Cannot query the CPU usage (Windows NT).\n")); } return GNUNET_SYSERR; } } else { /* Win 9x */ HKEY hKey; DWORD dwDataSize, dwType, dwDummy; /* Start query */ if (RegOpenKeyEx (HKEY_DYN_DATA, "PerfStats\\StartSrv", 0, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS) { /* only warn once */ static int once = 0; if (once == 0) { once = 1; GNUNET_GE_LOG (NULL, GNUNET_GE_USER | GNUNET_GE_ADMIN | GNUNET_GE_ERROR | GNUNET_GE_BULK, _("Cannot query the CPU usage (Win 9x)\n")); } } RegOpenKeyEx (HKEY_DYN_DATA, "PerfStats\\StartStat", 0, KEY_ALL_ACCESS, &hKey); dwDataSize = sizeof (dwDummy); RegQueryValueEx (hKey, "KERNEL\\CPUUsage", NULL, &dwType, (LPBYTE) & dwDummy, &dwDataSize); RegCloseKey (hKey); /* Get CPU usage */ RegOpenKeyEx (HKEY_DYN_DATA, "PerfStats\\StatData", 0, KEY_ALL_ACCESS, &hKey); dwDataSize = sizeof (currentCPULoad); RegQueryValueEx (hKey, "KERNEL\\CPUUsage", NULL, &dwType, (LPBYTE) & currentCPULoad, &dwDataSize); RegCloseKey (hKey); currentIOLoad = -1; /* FIXME-MINGW! */ /* Stop query */ RegOpenKeyEx (HKEY_DYN_DATA, "PerfStats\\StopStat", 0, KEY_ALL_ACCESS, &hKey); RegOpenKeyEx (HKEY_DYN_DATA, "PerfStats\\StopSrv", 0, KEY_ALL_ACCESS, &hKey); dwDataSize = sizeof (dwDummy); RegQueryValueEx (hKey, "KERNEL\\CPUUsage", NULL, &dwType, (LPBYTE) & dwDummy, &dwDataSize); RegCloseKey (hKey); return GNUNET_OK; }#endif /* loadaverage not defined and no platform specific alternative defined => default: error */ return GNUNET_SYSERR;}/** * Update load values (if enough time has expired), * including computation of averages. Code assumes * that lock has already been obtained. */static voidupdateAgedLoad (struct GNUNET_GE_Context *ectx, struct GNUNET_GC_Configuration *cfg){ static GNUNET_CronTime lastCall; GNUNET_CronTime now; now = GNUNET_get_time (); if ((agedCPULoad == -1) || (now - lastCall > 500 * GNUNET_CRON_MILLISECONDS)) { /* use smoothing, but do NOT update lastRet at frequencies higher than 500ms; this makes the smoothing (mostly) independent from the frequency at which getCPULoad is called (and we don't spend more time measuring CPU than actually computing something). */ lastCall = now; updateUsage (); if (currentCPULoad == -1) { agedCPULoad = -1; } else { if (agedCPULoad == -1) { agedCPULoad = currentCPULoad; } else { /* for CPU, we don't do the 'fast increase' since CPU is much more jitterish to begin with */ agedCPULoad = (agedCPULoad * 31 + currentCPULoad) / 32; } } if (currentIOLoad == -1) { agedIOLoad = -1; } else { if (agedIOLoad == -1) { agedIOLoad = currentIOLoad; } else { /* for IO, we don't do the 'fast increase' since IO is much more jitterish to begin with */ agedIOLoad = (agedIOLoad * 31 + currentIOLoad) / 32; } } }}/** * Get the load of the CPU relative to what is allowed. * @return the CPU load as a percentage of allowed * (100 is equivalent to full load) */intGNUNET_cpu_get_load (struct GNUNET_GE_Context *ectx, struct GNUNET_GC_Configuration *cfg){ unsigned long long maxCPULoad; int ret; GNUNET_mutex_lock (statusMutex); updateAgedLoad (ectx, cfg); ret = agedCPULoad; GNUNET_mutex_unlock (statusMutex); if (ret == -1) return -1; if (-1 == GNUNET_GC_get_configuration_value_number (cfg, "LOAD", "MAXCPULOAD", 0, 10000, /* more than 1 CPU possible */ 100, &maxCPULoad)) return GNUNET_SYSERR; return (100 * ret) / maxCPULoad;}/** * Get the load of the CPU relative to what is allowed. * @return the CPU load as a percentage of allowed * (100 is equivalent to full load) */intGNUNET_disk_get_load (struct GNUNET_GE_Context *ectx, struct GNUNET_GC_Configuration *cfg){ unsigned long long maxIOLoad; int ret; GNUNET_mutex_lock (statusMutex); updateAgedLoad (ectx, cfg); ret = agedIOLoad; GNUNET_mutex_unlock (statusMutex); if (ret == -1) return -1; if (-1 == GNUNET_GC_get_configuration_value_number (cfg, "LOAD", "MAXIOLOAD", 0, 10000, /* more than 1 CPU possible */ 100, &maxIOLoad)) return GNUNET_SYSERR; return (100 * ret) / maxIOLoad;}/** * The following method is called in order to initialize the status calls * routines. After that it is safe to call each of the status calls separately * @return GNUNET_OK on success and GNUNET_SYSERR on error (or calls errexit). */void __attribute__ ((constructor)) GNUNET_cpustats_ltdl_init (){ statusMutex = GNUNET_mutex_create (GNUNET_NO);#ifdef LINUX proc_stat = fopen ("/proc/stat", "r"); if (NULL == proc_stat) GNUNET_GE_LOG_STRERROR_FILE (NULL, GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_ADMIN | GNUNET_GE_BULK, "fopen", "/proc/stat");#elif OSX initMachCpuStats ();#elif MINGW InitWinEnv (NULL);#endif updateUsage (); /* initialize */}/** * Shutdown the status calls module. */void __attribute__ ((destructor)) GNUNET_cpustats_ltdl_fini (){#ifdef LINUX if (proc_stat != NULL) { fclose (proc_stat); proc_stat = NULL; }#elif OSX GNUNET_free_non_null (prev_cpu_load);#elif MINGW ShutdownWinEnv ();#endif GNUNET_mutex_destroy (statusMutex);}/* end of cpustatus.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -