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 // utils for multi-thread and multi-process test
17
18 #include "mt_utils.h"
19 #include <pthread.h>
20 #include <unistd.h>
21 #include <cstdlib>
22 #include <cerrno>
23 #include <sys/types.h>
24 #include <sys/shm.h>
25 #include "log.h"
26
27 #define MAX_INDEX 12
28 const uint32_t MSECOND_INDEX[MAX_INDEX] = {10, 20, 30, 60, 100, 150, 200, 300, 400, 600, 1000, 2000};
29 const uint32_t NUMBER_INDEX[MAX_INDEX] = {2500, 3600, 4500, 6600, 8800, 1000, 12000, 15000, 18000, 2000, 3000, 42000 };
30
31 int g_shmidCheckStep = 0;
CheckStep(int value)32 uint64_t CheckStep(int value)
33 {
34 int num4 = 4;
35 size_t sharememory = 1024;
36 unsigned int accessPermiss = 0666;
37 if (value == 1) {
38 shmctl(g_shmidCheckStep, IPC_RMID, nullptr);
39 g_shmidCheckStep = shmget(IPC_PRIVATE, sharememory, accessPermiss | IPC_CREAT);
40 }
41 if (g_shmidCheckStep != -1) {
42 uint64_t *shared = (uint64_t *)shmat(g_shmidCheckStep, nullptr, 0);
43 if (value == 1) {
44 *shared = 1;
45 } else {
46 *shared = (*shared << num4) + value;
47 }
48 uint64_t state = *shared;
49 shmdt(shared);
50 return state;
51 }
52 return 0;
53 }
54
CountPrimes(uint32_t maxNumber)55 int CountPrimes(uint32_t maxNumber)
56 {
57 uint32_t primesCount = 0;
58 uint32_t i;
59 uint32_t num;
60 uint32_t num2 = 2;
61 for (num = num2; num <= maxNumber; ++num) {
62 for (i = num2; i <= num; i++) {
63 if (num % i == 0) {
64 break;
65 }
66 }
67 if (i == num) {
68 primesCount++;
69 }
70 }
71 return primesCount;
72 }
73
GetNumberFromMS(uint32_t ms)74 static uint32_t GetNumberFromMS(uint32_t ms)
75 {
76 for (uint32_t i = 0; i < MAX_INDEX; i++) {
77 if (MSECOND_INDEX[i] == ms) {
78 return NUMBER_INDEX[i];
79 }
80 }
81 return 0;
82 }
83
BusyRun(uint32_t ms)84 int BusyRun(uint32_t ms)
85 {
86 uint32_t n = GetNumberFromMS(ms);
87 if (n == 0) {
88 LOG("BusyRun Error: %d ms not support", n);
89 _exit(1);
90 }
91 return CountPrimes(n);
92 }
93
94 // pipe for sync in ipc
95 static int g_pipeFd[2];
InitPipe()96 int InitPipe()
97 {
98 return pipe(g_pipeFd);
99 }
UnBlockPipe()100 void UnBlockPipe()
101 {
102 close(g_pipeFd[0]);
103 close(g_pipeFd[1]);
104 }
BlockOnPipe()105 void BlockOnPipe()
106 {
107 close(g_pipeFd[1]);
108 char buffer[2];
109 LOGD("before pipe read");
110 read(g_pipeFd[0], buffer, 1); // will block until close(fd[1]) in another port
111 LOGD("after pipe read");
112 close(g_pipeFd[0]);
113 }
114
115 // shm for process
116 int g_shmidGlobal;
InitGlobalVariable(void)117 int InitGlobalVariable(void)
118 {
119 size_t shareMemory = 1024;
120 unsigned int accessPermiss = 0666;
121 g_shmidGlobal = shmget(IPC_PRIVATE, shareMemory, accessPermiss | IPC_CREAT);
122 if (g_shmidGlobal == -1) {
123 LOG("> shmget errno = %d", errno);
124 return -1;
125 }
126 return 0;
127 }
128
SetGlobalVariable(int value)129 int SetGlobalVariable(int value)
130 {
131 int *shared = (int *)shmat(g_shmidGlobal, nullptr, 0);
132 if (shared == reinterpret_cast<int*>(-1)) {
133 LOG("> shmat errno = %d", errno);
134 return -1;
135 }
136 *shared = value;
137 if ((shmdt(shared)) == -1) {
138 LOG("> shmdt errno = %d", errno);
139 return -1;
140 }
141 return 0;
142 }
143
GetGlobalVariable(void)144 int GetGlobalVariable(void)
145 {
146 int re;
147 int *shared = (int *)shmat(g_shmidGlobal, nullptr, 0);
148 if (shared == reinterpret_cast<int*>(-1)) {
149 LOG("> shmat errno = %d", errno);
150 return -1;
151 }
152 re = *shared;
153 if ((shmdt(shared)) == -1) {
154 LOG("> shmdt errno = %d", errno);
155 return -1;
156 }
157 return re;
158 }
159
DeleteGlobalVariable(void)160 int DeleteGlobalVariable(void)
161 {
162 if (shmctl(g_shmidGlobal, IPC_RMID, nullptr) == -1) {
163 LOG("> shmctl errno = %d", errno);
164 return -1;
165 }
166 return 1;
167 }
168