106f6ba60Sopenharmony_ci/* 206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. 306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License. 506f6ba60Sopenharmony_ci * You may obtain a copy of the License at 606f6ba60Sopenharmony_ci * 706f6ba60Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 806f6ba60Sopenharmony_ci * 906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and 1306f6ba60Sopenharmony_ci * limitations under the License. 1406f6ba60Sopenharmony_ci */ 1506f6ba60Sopenharmony_ci 1606f6ba60Sopenharmony_ci#include <cstdio> 1706f6ba60Sopenharmony_ci#include <cstring> 1806f6ba60Sopenharmony_ci#include <unistd.h> 1906f6ba60Sopenharmony_ci#include <cstdlib> 2006f6ba60Sopenharmony_ci#include <pthread.h> 2106f6ba60Sopenharmony_ci#include <vector> 2206f6ba60Sopenharmony_ci#include <ctime> 2306f6ba60Sopenharmony_ci#include <csignal> 2406f6ba60Sopenharmony_ci#include <atomic> 2506f6ba60Sopenharmony_ci#include <memory> 2606f6ba60Sopenharmony_ci 2706f6ba60Sopenharmony_cinamespace { 2806f6ba60Sopenharmony_cistatic int g_duration; 2906f6ba60Sopenharmony_cistatic int g_memSize; 3006f6ba60Sopenharmony_cistatic std::atomic<long long> g_times; 3106f6ba60Sopenharmony_cistatic std::atomic<long long> g_mallocTotalTime; 3206f6ba60Sopenharmony_cistatic std::atomic<long long> g_freeTotalTime; 3306f6ba60Sopenharmony_cistatic constexpr int N_INSTALL_MALLOC_HOOK_SIGNAL = 36; 3406f6ba60Sopenharmony_cistatic constexpr int DURATION_TIME = 30 * 60; 3506f6ba60Sopenharmony_cistatic constexpr int MEMORY_BUFFER_SIZE = 19; 3606f6ba60Sopenharmony_ci 3706f6ba60Sopenharmony_civoid* UserThread(void* param) 3806f6ba60Sopenharmony_ci{ 3906f6ba60Sopenharmony_ci int idx = *static_cast<int*>(param); 4006f6ba60Sopenharmony_ci struct timespec beginTime; 4106f6ba60Sopenharmony_ci struct timespec endTime; 4206f6ba60Sopenharmony_ci struct timespec beginTimeMalloc; 4306f6ba60Sopenharmony_ci struct timespec endTimeMalloc; 4406f6ba60Sopenharmony_ci struct timespec beginTimeFree; 4506f6ba60Sopenharmony_ci struct timespec endTimeFree; 4606f6ba60Sopenharmony_ci 4706f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &beginTime); 4806f6ba60Sopenharmony_ci int displaySize = g_memSize > 5 ? 5 : g_memSize; 4906f6ba60Sopenharmony_ci do { 5006f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &endTime); 5106f6ba60Sopenharmony_ci if (endTime.tv_sec - beginTime.tv_sec >= g_duration) { 5206f6ba60Sopenharmony_ci break; 5306f6ba60Sopenharmony_ci } 5406f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &beginTimeMalloc); 5506f6ba60Sopenharmony_ci char* mem = static_cast<char *>(malloc(g_memSize)); 5606f6ba60Sopenharmony_ci if (mem == nullptr) { 5706f6ba60Sopenharmony_ci printf("Error: malloc mem memory failed.\n"); 5806f6ba60Sopenharmony_ci return nullptr; 5906f6ba60Sopenharmony_ci } 6006f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &endTimeMalloc); 6106f6ba60Sopenharmony_ci std::atomic_fetch_add_explicit( 6206f6ba60Sopenharmony_ci &g_mallocTotalTime, 6306f6ba60Sopenharmony_ci static_cast<long long>((endTimeMalloc.tv_sec - beginTimeMalloc.tv_sec) * 1000000000L + 6406f6ba60Sopenharmony_ci (endTimeMalloc.tv_nsec - beginTimeMalloc.tv_nsec)), 6506f6ba60Sopenharmony_ci std::memory_order_relaxed); 6606f6ba60Sopenharmony_ci long long currentTimes = ++g_times; 6706f6ba60Sopenharmony_ci long long timeBase = 10000; 6806f6ba60Sopenharmony_ci if (currentTimes % timeBase == 0) { 6906f6ba60Sopenharmony_ci printf("Thread %d, %lld: ", idx + 1, currentTimes); 7006f6ba60Sopenharmony_ci for (int i = 0 ; i < displaySize ; i++) { 7106f6ba60Sopenharmony_ci printf("%d ", mem[i]); 7206f6ba60Sopenharmony_ci } 7306f6ba60Sopenharmony_ci printf("\n"); 7406f6ba60Sopenharmony_ci } 7506f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &beginTimeFree); 7606f6ba60Sopenharmony_ci if (mem != nullptr) { 7706f6ba60Sopenharmony_ci free(mem); 7806f6ba60Sopenharmony_ci } 7906f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &endTimeFree); 8006f6ba60Sopenharmony_ci std::atomic_fetch_add_explicit( 8106f6ba60Sopenharmony_ci &g_freeTotalTime, 8206f6ba60Sopenharmony_ci static_cast<long long>((endTimeFree.tv_sec - beginTimeFree.tv_sec) * 1000000000L + 8306f6ba60Sopenharmony_ci (endTimeFree.tv_nsec - beginTimeFree.tv_nsec)), 8406f6ba60Sopenharmony_ci std::memory_order_relaxed); 8506f6ba60Sopenharmony_ci } 8606f6ba60Sopenharmony_ci while (true); 8706f6ba60Sopenharmony_ci return nullptr; 8806f6ba60Sopenharmony_ci} 8906f6ba60Sopenharmony_ci#define PRINTF_DATA(fileptr, fmt, ...) \ 9006f6ba60Sopenharmony_ci{ \ 9106f6ba60Sopenharmony_ci do { \ 9206f6ba60Sopenharmony_ci fprintf(stderr, fmt, ## __VA_ARGS__); \ 9306f6ba60Sopenharmony_ci fprintf(fileptr, fmt, ## __VA_ARGS__); \ 9406f6ba60Sopenharmony_ci fflush(fileptr); \ 9506f6ba60Sopenharmony_ci } while (0); \ 9606f6ba60Sopenharmony_ci} 9706f6ba60Sopenharmony_ci 9806f6ba60Sopenharmony_civoid Usage() 9906f6ba60Sopenharmony_ci{ 10006f6ba60Sopenharmony_ci printf("Usage: perf_test_data <-o output_file_name> [-t threadNum[] [-d g_duration] [-s g_memSize]\n"); 10106f6ba60Sopenharmony_ci} 10206f6ba60Sopenharmony_ci 10306f6ba60Sopenharmony_civoid FileClose(FILE* fp) 10406f6ba60Sopenharmony_ci{ 10506f6ba60Sopenharmony_ci if (fp != nullptr) { 10606f6ba60Sopenharmony_ci fclose(fp); 10706f6ba60Sopenharmony_ci } 10806f6ba60Sopenharmony_ci} 10906f6ba60Sopenharmony_ci 11006f6ba60Sopenharmony_ci} // namespace 11106f6ba60Sopenharmony_ci 11206f6ba60Sopenharmony_ciint main(int argc, char *argv[]) 11306f6ba60Sopenharmony_ci{ 11406f6ba60Sopenharmony_ci int threadNum = 1; 11506f6ba60Sopenharmony_ci g_duration = DURATION_TIME; 11606f6ba60Sopenharmony_ci g_memSize = MEMORY_BUFFER_SIZE; 11706f6ba60Sopenharmony_ci std::unique_ptr<FILE, void (*)(FILE*)> outFp(nullptr, nullptr); 11806f6ba60Sopenharmony_ci for (int idx = 1; idx < argc; ++idx) { 11906f6ba60Sopenharmony_ci if (strcmp(argv[idx], "-o") == 0) { 12006f6ba60Sopenharmony_ci if (idx + 1 >= argc) { 12106f6ba60Sopenharmony_ci Usage(); 12206f6ba60Sopenharmony_ci return 1; 12306f6ba60Sopenharmony_ci } else { 12406f6ba60Sopenharmony_ci ++idx; 12506f6ba60Sopenharmony_ci outFp = std::unique_ptr<FILE, void (*)(FILE*)>(fopen(argv[idx], "w"), FileClose); 12606f6ba60Sopenharmony_ci if (outFp == nullptr) { 12706f6ba60Sopenharmony_ci printf("File '%s' can't be opened.\n", argv[idx]); 12806f6ba60Sopenharmony_ci return 1; 12906f6ba60Sopenharmony_ci } 13006f6ba60Sopenharmony_ci } 13106f6ba60Sopenharmony_ci } else if (strcmp(argv[idx], "-t") == 0) { 13206f6ba60Sopenharmony_ci if (idx + 1 >= argc) { 13306f6ba60Sopenharmony_ci Usage(); 13406f6ba60Sopenharmony_ci return 1; 13506f6ba60Sopenharmony_ci } else { 13606f6ba60Sopenharmony_ci ++idx; 13706f6ba60Sopenharmony_ci threadNum = atoi(argv[idx]); 13806f6ba60Sopenharmony_ci if (threadNum <= 0) { 13906f6ba60Sopenharmony_ci printf("Thread number can't be less or equal zero.\n"); 14006f6ba60Sopenharmony_ci return 1; 14106f6ba60Sopenharmony_ci } 14206f6ba60Sopenharmony_ci } 14306f6ba60Sopenharmony_ci } else if (strcmp(argv[idx], "-d") == 0) { 14406f6ba60Sopenharmony_ci if (idx + 1 >= argc) { 14506f6ba60Sopenharmony_ci Usage(); 14606f6ba60Sopenharmony_ci return 1; 14706f6ba60Sopenharmony_ci } else { 14806f6ba60Sopenharmony_ci ++idx; 14906f6ba60Sopenharmony_ci g_duration = atoi(argv[idx]); 15006f6ba60Sopenharmony_ci if (g_duration <= 0) { 15106f6ba60Sopenharmony_ci printf("g_duration can't be less or equal zero.\n"); 15206f6ba60Sopenharmony_ci return 1; 15306f6ba60Sopenharmony_ci } 15406f6ba60Sopenharmony_ci } 15506f6ba60Sopenharmony_ci } else if (strcmp(argv[idx], "-s") == 0) { 15606f6ba60Sopenharmony_ci if (idx + 1 >= argc) { 15706f6ba60Sopenharmony_ci Usage(); 15806f6ba60Sopenharmony_ci return 1; 15906f6ba60Sopenharmony_ci } else { 16006f6ba60Sopenharmony_ci ++idx; 16106f6ba60Sopenharmony_ci g_memSize = atoi(argv[idx]); 16206f6ba60Sopenharmony_ci if (g_memSize <= 0) { 16306f6ba60Sopenharmony_ci printf("memory size can't be less or equal zero.\n"); 16406f6ba60Sopenharmony_ci return 1; 16506f6ba60Sopenharmony_ci } 16606f6ba60Sopenharmony_ci } 16706f6ba60Sopenharmony_ci } 16806f6ba60Sopenharmony_ci } 16906f6ba60Sopenharmony_ci if (outFp == nullptr) { 17006f6ba60Sopenharmony_ci Usage(); 17106f6ba60Sopenharmony_ci return 1; 17206f6ba60Sopenharmony_ci } 17306f6ba60Sopenharmony_ci pthread_t* thrArray = static_cast<pthread_t*>(malloc(sizeof(pthread_t) * threadNum)); 17406f6ba60Sopenharmony_ci if (thrArray == nullptr) { 17506f6ba60Sopenharmony_ci printf("malloc thrArray memory failed.\n"); 17606f6ba60Sopenharmony_ci return 1; 17706f6ba60Sopenharmony_ci } 17806f6ba60Sopenharmony_ci int idxSituation; 17906f6ba60Sopenharmony_ci int idxSituationMax = 2; 18006f6ba60Sopenharmony_ci int pid = static_cast<int>(getpid()); 18106f6ba60Sopenharmony_ci PRINTF_DATA(outFp.get(), "PID: %d, file: %d.nativehook\n", pid, pid); 18206f6ba60Sopenharmony_ci PRINTF_DATA(outFp.get(), 18306f6ba60Sopenharmony_ci "Thread number: %d, duration: %d seconds, memory size: %d bytes\n", 18406f6ba60Sopenharmony_ci threadNum, 18506f6ba60Sopenharmony_ci g_duration, 18606f6ba60Sopenharmony_ci g_memSize); 18706f6ba60Sopenharmony_ci for (idxSituation = 0; idxSituation < idxSituationMax; ++idxSituation) { 18806f6ba60Sopenharmony_ci if (idxSituation == 0) { 18906f6ba60Sopenharmony_ci PRINTF_DATA(outFp.get(), "No hook situation\n"); 19006f6ba60Sopenharmony_ci } else { 19106f6ba60Sopenharmony_ci PRINTF_DATA(outFp.get(), "\nWith hook situation\n"); 19206f6ba60Sopenharmony_ci raise(N_INSTALL_MALLOC_HOOK_SIGNAL); 19306f6ba60Sopenharmony_ci } 19406f6ba60Sopenharmony_ci int idx; 19506f6ba60Sopenharmony_ci 19606f6ba60Sopenharmony_ci std::atomic_store_explicit(&g_times, static_cast<long long>(0), std::memory_order_seq_cst); 19706f6ba60Sopenharmony_ci std::atomic_store_explicit(&g_mallocTotalTime, static_cast<long long>(0), std::memory_order_seq_cst); 19806f6ba60Sopenharmony_ci std::atomic_store_explicit(&g_freeTotalTime, static_cast<long long>(0), std::memory_order_seq_cst); 19906f6ba60Sopenharmony_ci 20006f6ba60Sopenharmony_ci for (idx = 0; idx < threadNum; ++idx) { 20106f6ba60Sopenharmony_ci if (pthread_create(thrArray + idx, nullptr, UserThread, reinterpret_cast<void*>(&idx)) != 0) { 20206f6ba60Sopenharmony_ci printf("Creating thread failed.\n"); 20306f6ba60Sopenharmony_ci } 20406f6ba60Sopenharmony_ci } 20506f6ba60Sopenharmony_ci 20606f6ba60Sopenharmony_ci for (idx = 0; idx < threadNum; ++idx) { 20706f6ba60Sopenharmony_ci pthread_join(thrArray[idx], nullptr); 20806f6ba60Sopenharmony_ci } 20906f6ba60Sopenharmony_ci long long totalTimes = g_times.load(std::memory_order_relaxed); 21006f6ba60Sopenharmony_ci PRINTF_DATA(outFp.get(), "The total g_times(malloc/free): %lld\n", totalTimes); 21106f6ba60Sopenharmony_ci } 21206f6ba60Sopenharmony_ci if (thrArray != nullptr) { 21306f6ba60Sopenharmony_ci free(thrArray); 21406f6ba60Sopenharmony_ci } 21506f6ba60Sopenharmony_ci printf("Exit\n"); 21606f6ba60Sopenharmony_ci} 217