Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "cpu_detect.h"
12 : #include <pthread.h>
13 : #include <sys/types.h>
14 : #include <sys/wait.h>
15 : #include <unistd.h>
16 : #include "cpu_detect_print.h"
17 : #include "cpu_detect_core.h"
18 :
19 : STATIC pid_t g_pid = 0;
20 : STATIC pthread_mutex_t g_cpuDetectMutex = PTHREAD_MUTEX_INITIALIZER;
21 :
22 4 : STATIC INLINE void CpuDetectMutexLock(void)
23 : {
24 4 : int32_t ret = pthread_mutex_lock(&g_cpuDetectMutex);
25 4 : ADETECT_CHK_EXPR(ret != 0, "mutex lock failed with %d.", ret);
26 4 : }
27 :
28 4 : STATIC INLINE void CpuDetectMutexUnLock(void)
29 : {
30 4 : int32_t ret = pthread_mutex_unlock(&g_cpuDetectMutex);
31 4 : ADETECT_CHK_EXPR(ret != 0, "mutex unlock failed with %d.", ret);
32 4 : }
33 :
34 0 : STATIC pid_t CpuDetectCreateProcess(uint32_t timeout)
35 : {
36 0 : pid_t id = fork();
37 0 : if (id == -1) {
38 0 : return 0;
39 : }
40 0 : if (id == 0) {
41 : // child
42 0 : CpudStatus ret = CpuDetectProcess(timeout);
43 0 : _exit(ret);
44 : } else {
45 : // parent
46 0 : return id;
47 : }
48 : }
49 :
50 2 : STATIC CpudStatus CpuDetectReleaseProcess(pid_t pid)
51 : {
52 2 : int32_t wstatus = -1;
53 2 : int32_t ret = waitpid(pid, &wstatus, 0);
54 2 : if (ret > 0) {
55 0 : if (WIFEXITED(wstatus)) {
56 0 : ADETECT_INF("cpu detect process[%d] exit success, status: %d", pid, WEXITSTATUS(wstatus));
57 0 : return WEXITSTATUS(wstatus);
58 0 : } else if (WIFSIGNALED(wstatus)) {
59 0 : ADETECT_INF("cpu detect process[%d] be killed by signal: %d", pid, WTERMSIG(wstatus));
60 0 : return CPUD_ERROR_STOP;
61 : }
62 2 : } else if (ret == -1) {
63 1 : ADETECT_ERR("waitpid pid = %d, sub process exit abnormally", pid);
64 1 : return CPUD_FAILURE;
65 : }
66 :
67 1 : return CPUD_SUCCESS;
68 : }
69 :
70 2 : CpudStatus CpuDetectStart(uint32_t timeout)
71 : {
72 2 : ADETECT_CHK_EXPR_ACTION(((timeout == 0) || (timeout > CPUD_DETECT_MAX_TIME)),
73 : return CPUD_ERROR_PARAM, "invalid param timeout: %d", timeout);
74 2 : ADETECT_CHK_EXPR_ACTION(g_pid != 0, return CPUD_ERROR_BUSY, "cpu detect is running on process[%d].", g_pid);
75 :
76 2 : CpuDetectMutexLock();
77 2 : if (g_pid != 0) {
78 0 : ADETECT_INF("cpu detect is running on process[%d].", g_pid);
79 0 : CpuDetectMutexUnLock();
80 0 : return CPUD_ERROR_BUSY;
81 : }
82 :
83 2 : ADETECT_RUN_INF("cpu detect process start.");
84 2 : g_pid = CpuDetectCreateProcess(timeout);
85 2 : if (g_pid == 0) {
86 0 : ADETECT_ERR("create detect process failed.");
87 0 : CpuDetectMutexUnLock();
88 0 : return CPUD_ERROR_CREATE_PROCESS;
89 : } else {
90 2 : ADETECT_INF("start cpu detect process[%d] success", g_pid);
91 : }
92 2 : CpuDetectMutexUnLock();
93 :
94 2 : CpudStatus ret = CpuDetectReleaseProcess(g_pid);
95 2 : ADETECT_RUN_INF("cpu detect process[%d] end with %d.", g_pid, ret);
96 :
97 2 : g_pid = 0;
98 2 : return ret;
99 : }
100 :
101 3 : void CpuDetectStop(void)
102 : {
103 3 : if (g_pid == 0) {
104 1 : ADETECT_INF("cpu detect is not running.");
105 1 : return;
106 : }
107 :
108 2 : CpuDetectMutexLock();
109 2 : if (g_pid != 0) {
110 2 : ADETECT_RUN_INF("cpu detect kill process[%d].", g_pid);
111 2 : int32_t ret = kill(g_pid, 9);
112 2 : if (ret != 0) {
113 1 : ADETECT_ERR("cpu detect stop process[%d] failed with %d.", g_pid, ret);
114 : }
115 : }
116 2 : CpuDetectMutexUnLock();
117 : }
|