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