vcpe/srcs/libs/hardware/cpu.c

173 lines
4.1 KiB
C
Raw Normal View History

2022-05-10 06:43:27 +00:00
//
// Created by xajhu on 2021/7/6 0006.
//
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <uv.h>
#include "hardware.h"
#include "misc.h"
#include "user_errno.h"
#include "config.h"
typedef struct {
unsigned long cpuTotal;
unsigned long cpuIdle;
} CPU_TIME;
#define CMD_CPU_NUM ("cat /proc/cpuinfo| grep \"physical id\" | sort | uniq | wc -l")
#define CMD_CPU_CORE ("cat /proc/cpuinfo| grep \"cpu cores\" | uniq | awk \'{print $4}\'")
#define CMP_CPU_LOGIC_CORE ("cat /proc/cpuinfo| grep \"cpu cores\" | wc -l")
#define SUM_CPU_TIME(x) ((x).user + (x).nice + (x).sys + (x).idle + (x).irq)
2022-05-10 06:43:27 +00:00
static int g_isInit = FALSE;
static CPU_INFO g_cpuInfo;
static int get_cpu_info_cmd(const char *pCmd) {
char *pRet = NULL;
char *pOver;
long val;
if (shell_with_output(pCmd, &pRet) != ERR_SUCCESS || pRet == NULL || strlen(pRet) == 0) {
2022-05-10 06:43:27 +00:00
if (pRet) {
free(pRet);
}
return -ERR_CALL_SHELL;
}
errno = 0;
val = strtol(pRet, &pOver, 10);
free(pRet);
if (/*(pOver != NULL && strlen(pOver)) ||*/ errno != 0) {
return -ERR_STRING_TO_NUMBER;
}
return (int)val;
}
static int get_cpu_number() {
return get_cpu_info_cmd(CMD_CPU_NUM);
}
static int get_cpu_core_number() {
return get_cpu_info_cmd(CMD_CPU_CORE);
}
static int get_cpu_logic_core() {
return get_cpu_info_cmd(CMP_CPU_LOGIC_CORE);
}
int get_cpu_desc(PCPU_DESC pDesc) {
uv_cpu_info_t *pCpu = NULL;
int nCpu;
if (uv_cpu_info(&pCpu, &nCpu) != 0 || nCpu <= 0) {
if (pCpu) {
uv_free_cpu_info(pCpu, nCpu);
}
return -ERR_SYS_GET_CPU_INFO;
}
if (pDesc) {
memset(pDesc->cpuName, 0, MEM_VALUE_SIZE * 4);
strcpy(pDesc->cpuName, (pCpu[0].model));
pDesc->cpuSpeed = pCpu[0].speed;
}
uv_free_cpu_info(pCpu, nCpu);
return ERR_SUCCESS;
2022-05-10 06:43:27 +00:00
}
static int get_cpu_time_info(unsigned long *pTotal, unsigned long *pIdle) {
uv_cpu_info_t *pCpu = NULL;
int i, nCpu;
if (pTotal == NULL || pIdle == NULL) {
return -ERR_INPUT_PARAMS;
}
if (uv_cpu_info(&pCpu, &nCpu) != 0 || nCpu <= 0) {
if (pCpu) {
uv_free_cpu_info(pCpu, nCpu);
}
return -ERR_SYS_GET_CPU_INFO;
}
// 清零计算值
*pTotal = *pIdle = 0;
for (i = 0; i < nCpu; i++) {
*pIdle += pCpu[i].cpu_times.idle;
2022-05-10 06:43:27 +00:00
*pTotal += SUM_CPU_TIME(pCpu[i].cpu_times);
}
uv_free_cpu_info(pCpu, nCpu);
return ERR_SUCCESS;
2022-05-10 06:43:27 +00:00
}
static void cpuUsedRefresh() {
CPU_TIME beginTime, endTime;
memset(&beginTime, 0, sizeof(CPU_TIME));
memset(&endTime, 0, sizeof(CPU_TIME));
if (get_cpu_time_info(&beginTime.cpuTotal, &beginTime.cpuIdle) != ERR_SUCCESS) {
2022-05-10 06:43:27 +00:00
return;
}
// 延时 1s 后再获取1次CPU信息
uv_sleep(1000);
if (get_cpu_time_info(&endTime.cpuTotal, &endTime.cpuIdle) != ERR_SUCCESS) {
2022-05-10 06:43:27 +00:00
return;
} else {
uint64_t idle = endTime.cpuIdle - beginTime.cpuIdle;
uint64_t total = endTime.cpuTotal - beginTime.cpuTotal;
g_cpuInfo.cpuUsed = 1.0 - ((double)idle / (double)total);
g_cpuInfo.timestamp = time(NULL);
}
}
int cpu_watch_init() {
memset(&g_cpuInfo, 0, sizeof(CPU_INFO));
g_cpuInfo.nCpus = get_cpu_number();
g_cpuInfo.nLogicCores = get_cpu_logic_core();
g_cpuInfo.nCores = get_cpu_core_number();
g_cpuInfo.timestamp = time(NULL);
get_cpu_desc(&g_cpuInfo.cpuCoreDesc);
g_isInit = TRUE;
return ERR_SUCCESS;
2022-05-10 06:43:27 +00:00
}
int get_cpu_info(PCPU_INFO pInfo) {
if (pInfo == NULL) {
return -ERR_INPUT_PARAMS;
}
if (g_isInit == FALSE) {
memset(&g_cpuInfo, 0, sizeof(CPU_INFO));
g_cpuInfo.nCpus = get_cpu_number();
g_cpuInfo.nLogicCores = get_cpu_logic_core();
g_cpuInfo.nCores = get_cpu_core_number();
g_cpuInfo.timestamp = time(NULL);
get_cpu_desc(&g_cpuInfo.cpuCoreDesc);
g_isInit = TRUE;
} else if (cfg_get_watch_cpu()) {
cpuUsedRefresh();
2022-05-10 06:43:27 +00:00
}
memcpy(pInfo, &g_cpuInfo, sizeof(CPU_INFO));
return ERR_SUCCESS;
2022-05-10 06:43:27 +00:00
}