1 /*
2  * Copyright (c) 2023 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 <cstdint>
20 #include <cstdio>
21 #include <unistd.h>
22 #include <cstdlib>
23 #include <cerrno>
24 #include <cstring>
25 #include <ctime>
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 #include <fcntl.h>
33 
34 // check if 'actual' is close to 'target', within 5% in default
35 int CheckValueClose(double target, double actual, double accuracy = 0.05);
36 
37 // sleep n millisecond(1/1000 sec)
38 void Msleep(int n);
39 
40 /**
41  * desc:   check process state use 'waitpid'
42  * input:  pid  -- target pid
43  *         code -- store exit code or signal number
44  *         flag -- flag for waitpid, default to WNOHANG
45  * output: -1 -- waitpid return -1
46  *         -2 -- waitpid return value error(not -1 and not pid)
47  *          0 -- target process still alive
48  *          1 -- target process existd, exist code is set in 'code'
49  *          2 -- target process killed by a signal, signal number is set in 'code'
50  *          3 -- target process is stopped,  signal number is set in 'code'
51  *          4 -- get target process state error, due to waitpid error
52  */
53 int CheckProcStatus(pid_t pid, int* code, int flag = WNOHANG);
54 
55 // make sure process is still alive
56 void AssertProcAlive(pid_t pid);
57 void ExpectProcAlive(pid_t pid);
58 
59 // make sure process exited with exitCode 0
60 void AssertProcExitedOK(pid_t pid);
61 void ExpectProcExitedOK(pid_t pid);
62 
63 // wait until child statu changed
64 void WaitProcExitedOK(pid_t pid);
65 
66 // make sure process killed by signal signum
67 void AssertProcKilled(pid_t pid, int signum);
68 void ExpectProcKilled(pid_t pid, int signum);
69 
70 // wait until child statu changed
71 void WaitProcKilled(pid_t pid, int signum);
72 
73 // keep current process run for a specific time, no sleep.
74 // msec is millisecond (1/1000 sec).
75 // return value is the loop count(generally you don't need to care about it)
76 int KeepRun(int msec);
77 
78 /**
79  * code to determain if execve is faild, may confic with actual sub program's exit code
80  */
81 const int EXECVE_RETURN_ERROR = 190;  // execve return -1
82 const int EXECVE_RETURN_OK    = 191;  // execve return not -1: execve should never return on success
83 
84 /**
85  * desc:   start an elf, check if execve success, and return child process exit code within timeout_sec
86  * input:  fname, argv, envp -- parameters for execve
87  *         timeout_sec       -- timeout of the child executing, default: 5 seconds.
88  *                              timeout_sec<=0 means no timeout, wait forever until child exit.
89  * output: -1 -- something wrong for internal syscall, check log for detail
90  *         -2 -- child does not finish in 'timeout_sec'
91  *     n(>=0) -- child exit code
92  */
93 int RunElf(const char* fname, char* const argv[], char* const envp[], int timeoutSec = 5);
94 
95 /**
96  * desc:   call execve with error parameters(e.g. a non-exist file)
97  * input:  fname, argv, envp -- parameters for execve
98  * output:  0 -- execve ok
99  *         -1 -- unexpected fork error
100  *         -2 -- unexpected execve error
101  *         -3 -- unknow error
102  *      n(>0) -- errno of execve
103  */
104 int StartExecveError(const char* fname, char* const argv[], char* const envp[]);
105 
106 // Get a pid number that currently not exist
107 pid_t GetNonExistPid();
108 
109 /**
110  * return random number n: 0 < n <= max
111  * we found in most case '0' is not expected.
112  */
113 uint32_t GetRandom(uint32_t max);
114 
115 /**
116  * desc:    get current time, plus 'ms'
117  */
118 void GetDelayedTime(struct timespec *ts, unsigned int ms);
119 
120 /**
121  * desc:    calculate time difference, in ms
122  * output:  return time difference, unit is ms
123  */
124 int GetTimeDiff(struct timespec ts1, struct timespec ts2);
125 
126 /**
127  * desc:    fix calling process to one cpu
128  * output:  return 0 successful, -1 fail
129  */
130 int FixCurProcessToOneCpu(int cpuIndex, cpu_set_t* pOldMask);
131 
132 /**
133  * desc:    get cpu count
134  * output:  return cpu count
135  */
136 int GetCpuCount(void);
137 #endif
138