• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 - 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef KERNEL_LITE_UTILS
17 #define KERNEL_LITE_UTILS
18 
19 #include <stdint.h>
20 #include <stdio.h>
21 #include <unistd.h>
22 #include <stdlib.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <time.h>
26 #include <sys/time.h>
27 #include <sys/types.h>
28 #include <sys/wait.h>
29 #include <sys/syscall.h>
30 #include <sys/resource.h>
31 #include <pthread.h>
32 
33 
34 // get thread id
35 #define gettid() ((pid_t)syscall(SYS_gettid))
36 
37 // check if 'actual' is close to 'target', within 5% in default
38 int CheckValueClose(double target, double actual, double accuracy = 0.05);
39 
40 // sleep n millisecond(1/1000 sec)
41 void Msleep(int n);
42 
43 /**
44  * desc:   check process state use 'waitpid'
45  * input:  pid  -- target pid
46  *         code -- store exit code or signal number
47  *         flag -- flag for waitpid, default to WNOHANG
48  * output: -1 -- waitpid return -1
49  *         -2 -- waitpid return value error(not -1 and not pid)
50  *          0 -- target process still alive
51  *          1 -- target process existd, exist code is set in 'code'
52  *          2 -- target process killed by a signal, signal number is set in 'code'
53  *          3 -- target process is stopped,  signal number is set in 'code'
54  *          4 -- get target process state error, due to waitpid error
55  */
56 int CheckProcStatus(pid_t pid, int* code, int flag = WNOHANG);
57 
58 // make sure process is still alive
59 #define AssertProcAlive(pid)  do {                                        \
60         int exitCode;                                                     \
61         int procStat = CheckProcStatus(pid, &exitCode);                   \
62         ASSERT_EQ(procStat, 0) << "target process should still alive.\n"; \
63     } while (0)
64 #define ExpectProcAlive(pid)  do {                                        \
65         int exitCode;                                                     \
66         int procStat = CheckProcStatus(pid, &exitCode);                   \
67         EXPECT_EQ(procStat, 0) << "target process should still alive.\n"; \
68     } while (0)
69 
70 // make sure process exited with exitCode 0
71 #define AssertProcExitedOK(pid)  do {                                  \
72         int exitCode;                                                  \
73         int procStat = CheckProcStatus(pid, &exitCode);                \
74         EXPECT_EQ(procStat, 1);                                        \
75         ASSERT_EQ(exitCode, 0) << "target process should exited 0.\n"; \
76     } while (0)
77 #define ExpectProcExitedOK(pid)  do {                                  \
78         int exitCode;                                                  \
79         int procStat = CheckProcStatus(pid, &exitCode);                \
80         EXPECT_EQ(procStat, 1);                                        \
81         EXPECT_EQ(exitCode, 0) << "target process should exited 0.\n"; \
82     } while (0)
83 // wait until child statu changed
84 #define WaitProcExitedOK(pid)  do {                                    \
85         int exitCode;                                                  \
86         int procStat = CheckProcStatus(pid, &exitCode, 0);             \
87         EXPECT_EQ(procStat, 1);                                        \
88         EXPECT_EQ(exitCode, 0) << "target process should exited 0.\n"; \
89     } while (0)
90 
91 // make sure process killed by signal signum
92 #define AssertProcKilled(pid, signum)  do {                                          \
93         int exitCode;                                                                \
94         int procStat = CheckProcStatus(pid, &exitCode);                              \
95         ASSERT_EQ(procStat, 2) << "target process should killed by " << signum;      \
96         ASSERT_EQ(exitCode, signum) << "target process should killed by " << signum; \
97     } while (0)
98 #define ExpectProcKilled(pid, signum)  do {                                          \
99         int exitCode;                                                                \
100         int procStat = CheckProcStatus(pid, &exitCode);                              \
101         EXPECT_EQ(procStat, 2);                                                      \
102         EXPECT_EQ(exitCode, signum) << "target process should killed by " << signum; \
103     } while (0)
104 // wait until child statu changed
105 #define WaitProcKilled(pid, signum)  do {                                            \
106         int exitCode;                                                                \
107         int procStat = CheckProcStatus(pid, &exitCode, 0);                           \
108         ASSERT_EQ(procStat, 2) << "target process should killed by " << signum;      \
109         ASSERT_EQ(exitCode, signum) << "target process should killed by " << signum; \
110     } while (0)
111 
112 // for now, crash process act like killed by SIGUSR2
113 #define ExpectProcCrashed(pid) WaitProcKilled(pid, SIGUSR2)
114 
115 // keep current process run for a specific time, no sleep.
116 // msec is millisecond (1/1000 sec).
117 // return value is the loop count(generally you don't need to care about it)
118 int KeepRun(int msec);
119 
120 /**
121  * code to determain if execve is faild, may confic with actual sub program's exit code
122  */
123 const int EXECVE_RETURN_ERROR = 190;  // execve return -1
124 const int EXECVE_RETURN_OK    = 191;  // execve return not -1: execve should never return on success
125 
126 /**
127  * desc:   start an elf, check if execve success, and return child process exit code within timeout_sec
128  * input:  fname, argv, envp -- parameters for execve
129  *         timeout_sec       -- timeout of the child executing, default: 5 seconds.
130  *                              timeout_sec<=0 means no timeout, wait forever until child exit.
131  * output: -1 -- something wrong for internal syscall, check log for detail
132  *         -2 -- child does not finish in 'timeout_sec'
133  *     n(>=0) -- child exit code
134  */
135 int RunElf(const char* fname, char* const argv[], char* const envp[], int timeoutSec = 5);
136 
137 /**
138  * desc:   call execve with error parameters(e.g. a non-exist file)
139  * input:  fname, argv, envp -- parameters for execve
140  * output:  0 -- execve ok
141  *         -1 -- unexpected fork error
142  *         -2 -- unexpected execve error
143  *         -3 -- unknow error
144  *      n(>0) -- errno of execve
145  */
146 int StartExecveError(const char* fname, char* const argv[], char* const envp[]);
147 
148 // Get a pid number that currently not exist
149 pid_t GetNonExistPid();
150 
151 /**
152  * return random number n: 0 < n <= max
153  * we found in most case '0' is not expected.
154  */
155 uint32_t GetRandom(uint32_t max);
156 
157 /**
158  * desc:    get current time, plus 'ms'
159  */
160 void GetDelayedTime(struct timespec *ts, unsigned int ms);
161 
162 /**
163  * desc:    calculate time difference, in ms
164  * output:  return time difference, unit is ms
165  */
166 int GetTimeDiff(struct timespec ts1, struct timespec ts2);
167 
168 /**
169  * desc:    fix calling process to one cpu
170  * output:  return 0 successful, -1 fail
171  */
172 int FixCurProcessToOneCpu(int cpuIndex, cpu_set_t* pOldMask);
173 
174 /**
175  * desc:    get cpu count
176  * output:  return cpu count
177  */
178 int GetCpuCount(void);
179 #endif
180