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