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(
73 : ((timeout == 0) || (timeout > CPUD_DETECT_MAX_TIME)), return CPUD_ERROR_PARAM, "invalid param timeout: %d",
74 : timeout);
75 2 : ADETECT_CHK_EXPR_ACTION(g_pid != 0, return CPUD_ERROR_BUSY, "cpu detect is running on process[%d].", g_pid);
76 :
77 2 : CpuDetectMutexLock();
78 2 : if (g_pid != 0) {
79 0 : ADETECT_INF("cpu detect is running on process[%d].", g_pid);
80 0 : CpuDetectMutexUnLock();
81 0 : return CPUD_ERROR_BUSY;
82 : }
83 :
84 2 : ADETECT_RUN_INF("cpu detect process start.");
85 2 : g_pid = CpuDetectCreateProcess(timeout);
86 2 : if (g_pid == 0) {
87 0 : ADETECT_ERR("create detect process failed.");
88 0 : CpuDetectMutexUnLock();
89 0 : return CPUD_ERROR_CREATE_PROCESS;
90 : } else {
91 2 : ADETECT_INF("start cpu detect process[%d] success", g_pid);
92 : }
93 2 : CpuDetectMutexUnLock();
94 :
95 2 : CpudStatus ret = CpuDetectReleaseProcess(g_pid);
96 2 : ADETECT_RUN_INF("cpu detect process[%d] end with %d.", g_pid, ret);
97 :
98 2 : g_pid = 0;
99 2 : return ret;
100 : }
101 :
102 3 : void CpuDetectStop(void)
103 : {
104 3 : if (g_pid == 0) {
105 1 : ADETECT_INF("cpu detect is not running.");
106 1 : return;
107 : }
108 :
109 2 : CpuDetectMutexLock();
110 2 : if (g_pid != 0) {
111 2 : ADETECT_RUN_INF("cpu detect kill process[%d].", g_pid);
112 2 : int32_t ret = kill(g_pid, 9);
113 2 : if (ret != 0) {
114 1 : ADETECT_ERR("cpu detect stop process[%d] failed with %d.", g_pid, ret);
115 : }
116 : }
117 2 : CpuDetectMutexUnLock();
118 : }
|