• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <cstdio>
17 #include <cstring>
18 #include <unistd.h>
19 #include <cstdlib>
20 #include <pthread.h>
21 #include <vector>
22 #include <ctime>
23 #include <csignal>
24 #include <atomic>
25 #include <memory>
26 
27 namespace {
28 static int g_duration;
29 static int g_memSize;
30 static std::atomic<long long> g_times;
31 static std::atomic<long long> g_mallocTotalTime;
32 static std::atomic<long long> g_freeTotalTime;
33 static constexpr int N_INSTALL_MALLOC_HOOK_SIGNAL = 36;
34 static constexpr int DURATION_TIME = 30 * 60;
35 static constexpr int MEMORY_BUFFER_SIZE = 19;
36 
UserThread(void * param)37 void* UserThread(void* param)
38 {
39     int idx = *static_cast<int*>(param);
40     struct timespec beginTime;
41     struct timespec endTime;
42     struct timespec beginTimeMalloc;
43     struct timespec endTimeMalloc;
44     struct timespec beginTimeFree;
45     struct timespec endTimeFree;
46 
47     clock_gettime(CLOCK_REALTIME, &beginTime);
48     int displaySize = g_memSize > 5 ? 5 : g_memSize;
49     do {
50         clock_gettime(CLOCK_REALTIME, &endTime);
51         if (endTime.tv_sec - beginTime.tv_sec >= g_duration) {
52             break;
53         }
54         clock_gettime(CLOCK_REALTIME, &beginTimeMalloc);
55         char* mem = (char *)malloc(g_memSize);
56         if (mem == nullptr) {
57             printf("Error: malloc mem memory failed.\n");
58             return nullptr;
59         }
60         clock_gettime(CLOCK_REALTIME, &endTimeMalloc);
61         std::atomic_fetch_add_explicit(
62             &g_mallocTotalTime,
63             static_cast<long long>((endTimeMalloc.tv_sec - beginTimeMalloc.tv_sec) * 1000000000L +
64                                    (endTimeMalloc.tv_nsec - beginTimeMalloc.tv_nsec)),
65             std::memory_order_relaxed);
66         long long currentTimes = ++g_times;
67         long long timeBase = 10000;
68         if (currentTimes % timeBase == 0) {
69             printf("Thread %d, %lld: ", idx + 1, currentTimes);
70             for (int i = 0 ; i < displaySize ; i++) {
71                 printf("%d ", mem[i]);
72             }
73             printf("\n");
74         }
75         clock_gettime(CLOCK_REALTIME, &beginTimeFree);
76         if (mem != nullptr) {
77             free(mem);
78         }
79         clock_gettime(CLOCK_REALTIME, &endTimeFree);
80         std::atomic_fetch_add_explicit(
81             &g_freeTotalTime,
82             static_cast<long long>((endTimeFree.tv_sec - beginTimeFree.tv_sec) * 1000000000L +
83                                    (endTimeFree.tv_nsec - beginTimeFree.tv_nsec)),
84             std::memory_order_relaxed);
85     }
86     while (true);
87     return nullptr;
88 }
89 #define PRINTF_DATA(fileptr, fmt, ...) \
90 {                              \
91     do { \
92         fprintf(stderr, fmt, ## __VA_ARGS__); \
93         fprintf(fileptr, fmt, ## __VA_ARGS__); \
94         fflush(fileptr); \
95     } while (0); \
96 }
97 
Usage()98 void Usage()
99 {
100     printf("Usage: perf_test_data <-o output_file_name> [-t threadNum[] [-d g_duration] [-s g_memSize]\n");
101 }
102 
FileClose(FILE * fp)103 void FileClose(FILE* fp)
104 {
105     if (fp != nullptr) {
106         fclose(fp);
107     }
108 }
109 
110 } // namespace
111 
main(int argc,char * argv[])112 int main(int argc, char *argv[])
113 {
114     int threadNum = 1;
115     g_duration = DURATION_TIME;
116     g_memSize = MEMORY_BUFFER_SIZE;
117     std::unique_ptr<FILE, void (*)(FILE*)> outFp(nullptr, nullptr);
118     for (int idx = 1; idx < argc; ++idx) {
119         if (strcmp(argv[idx], "-o") == 0) {
120             if (idx + 1 >= argc) {
121                 Usage();
122                 return 1;
123             } else {
124                 ++idx;
125                 outFp = std::unique_ptr<FILE, void (*)(FILE*)>(fopen(argv[idx], "w"), FileClose);
126                 if (outFp == nullptr) {
127                     printf("File '%s' can't be opened.\n", argv[idx]);
128                     return 1;
129                 }
130             }
131         } else if (strcmp(argv[idx], "-t") == 0) {
132             if (idx + 1 >= argc) {
133                 Usage();
134                 return 1;
135             } else {
136                 ++idx;
137                 threadNum = atoi(argv[idx]);
138                 if (threadNum <= 0) {
139                     printf("Thread number can't be less or equal zero.\n");
140                     return 1;
141                 }
142             }
143         } else if (strcmp(argv[idx], "-d") == 0) {
144             if (idx + 1 >= argc) {
145                 Usage();
146                 return 1;
147             } else {
148                 ++idx;
149                 g_duration = atoi(argv[idx]);
150                 if (g_duration <= 0) {
151                     printf("g_duration can't be less or equal zero.\n");
152                     return 1;
153                 }
154             }
155         } else if (strcmp(argv[idx], "-s") == 0) {
156             if (idx + 1 >= argc) {
157                 Usage();
158                 return 1;
159             } else {
160                 ++idx;
161                 g_memSize = atoi(argv[idx]);
162                 if (g_memSize <= 0) {
163                     printf("memory size can't be less or equal zero.\n");
164                     return 1;
165                 }
166             }
167         }
168     }
169     if (outFp == nullptr) {
170         Usage();
171         return 1;
172     }
173     pthread_t* thrArray = (pthread_t*)malloc(sizeof(pthread_t) * threadNum);
174     if (thrArray == nullptr) {
175         printf("malloc thrArray memory failed.\n");
176         return 1;
177     }
178     int idxSituation;
179     int idxSituationMax = 2;
180     int pid = static_cast<int>(getpid());
181     PRINTF_DATA(outFp.get(), "PID: %d, file: %d.nativehook\n", pid, pid);
182     PRINTF_DATA(outFp.get(),
183         "Thread number: %d, duration: %d seconds, memory size: %d bytes\n",
184         threadNum,
185         g_duration,
186         g_memSize);
187     for (idxSituation = 0; idxSituation < idxSituationMax; ++idxSituation) {
188         if (idxSituation == 0) {
189             PRINTF_DATA(outFp.get(), "No hook situation\n");
190         } else {
191             PRINTF_DATA(outFp.get(), "\nWith hook situation\n");
192             raise(N_INSTALL_MALLOC_HOOK_SIGNAL);
193         }
194         int idx;
195 
196         std::atomic_store_explicit(&g_times, static_cast<long long>(0), std::memory_order_seq_cst);
197         std::atomic_store_explicit(&g_mallocTotalTime, static_cast<long long>(0), std::memory_order_seq_cst);
198         std::atomic_store_explicit(&g_freeTotalTime, static_cast<long long>(0), std::memory_order_seq_cst);
199 
200         for (idx = 0; idx < threadNum; ++idx) {
201             if (pthread_create(thrArray + idx, nullptr, UserThread, reinterpret_cast<void*>(&idx)) != 0) {
202                 printf("Creating thread failed.\n");
203             }
204         }
205 
206         for (idx = 0; idx < threadNum; ++idx) {
207             pthread_join(thrArray[idx], nullptr);
208         }
209         long long totalTimes = g_times.load(std::memory_order_relaxed);
210         PRINTF_DATA(outFp.get(), "The total g_times(malloc/free): %lld\n", totalTimes);
211     }
212     if (thrArray != nullptr) {
213         free(thrArray);
214     }
215     printf("Exit\n");
216 }
217