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 <stdio.h>
17 #include <unistd.h>
18 #include <stdlib.h>
19 #include <sys/syscall.h>
20 #include <pthread.h>
21 #include <time.h>
22 #pragma clang optimize off
23
24 #define DEFAULT_THREAD_NUM 1
25 #define DEFAULT_MALLOC_SIZE 100
26 #define DEFAULT_REALLOC_SIZE 100
27 #define SLEEP_TIME_SEC 1
28 #define TEST_BRANCH_NUM 3
29 #define ARG_CASE_NUM_THREADNUM 3
30 #define ARG_CASE_MALLOCSIZE 2
31 #define ARG_THREADNUM 2
32 #define STATIC_DEPTH 5
33 #define DATA_SIZE 50
34
35 typedef struct {
36 int data[DATA_SIZE];
37 } StaticSpace;
38
39 static int g_runing = 1;
40 static double g_mallocDuration = 0;
41 static double g_callocDuration = 0;
42 static double g_reallocDuration = 0;
43 static double g_freeDuration = 0;
44
DepthMalloc(int depth,int mallocSize)45 char *DepthMalloc(int depth, int mallocSize)
46 {
47 if (mallocSize <= 0) {
48 return NULL;
49 }
50 StaticSpace staticeData;
51 if (depth == 0) {
52 staticeData.data[0] = 1;
53 return (char *)malloc(mallocSize);
54 }
55 return (DepthMalloc(depth - 1, mallocSize));
56 }
57
DepthCalloc(int depth,int callocSize)58 char *DepthCalloc(int depth, int callocSize)
59 {
60 StaticSpace staticeData;
61 if (depth == 0) {
62 staticeData.data[0] = 1;
63 return (char *)calloc(sizeof(char), callocSize);
64 }
65 return (DepthCalloc(depth - 1, callocSize));
66 }
67
DepthRealloc(int depth,void * p,int reallocSize)68 char *DepthRealloc(int depth, void *p, int reallocSize)
69 {
70 StaticSpace staticeData;
71 if (depth == 0) {
72 staticeData.data[0] = 1;
73 return (char *)realloc(p, reallocSize);
74 }
75 return (DepthRealloc(depth - 1, p, reallocSize));
76 }
77
DepthFree(int depth,void * p)78 void DepthFree(int depth, void *p)
79 {
80 StaticSpace staticeData;
81 if (depth == 0) {
82 staticeData.data[0] = 1;
83 free(p);
84 return;
85 }
86 return (DepthFree(depth - 1, p));
87 }
88
ApplyForMalloc(int mallocSize)89 void ApplyForMalloc(int mallocSize)
90 {
91 printf("\nstart malloc apply (size = %d)\n", mallocSize);
92 clock_t timerStart, timerStop;
93 double duration = 0;
94 timerStart = clock();
95 char *p = DepthMalloc(STATIC_DEPTH, mallocSize);
96 timerStop = clock();
97 if (!p) {
98 printf("malloc failure\n");
99 return;
100 }
101 duration += (double)(timerStop - timerStart) / CLOCKS_PER_SEC;
102 g_mallocDuration += (double)(timerStop - timerStart) / CLOCKS_PER_SEC;
103 printf("malloc success, malloc (%d) time is %f\n", mallocSize, duration);
104 printf("\nReady for free -- ");
105 timerStart = clock();
106 DepthFree(STATIC_DEPTH, p);
107 timerStop = clock();
108 duration += (double)(timerStop - timerStart) / CLOCKS_PER_SEC;
109 g_freeDuration += (double)(timerStop - timerStart) / CLOCKS_PER_SEC;
110 printf("free success, free time is %f\n", (double)(timerStop - timerStart) / CLOCKS_PER_SEC);
111 printf("malloc apply success, total time is %f\n", duration);
112 }
113
ApplyForCalloc(int mallocSize)114 void ApplyForCalloc(int mallocSize)
115 {
116 int callocSize = mallocSize / sizeof(char);
117 printf("\nstart calloc apply (size = %d)\n", callocSize);
118 clock_t timerStart, timerStop;
119 double duration = 0;
120 timerStart = clock();
121 char *p = DepthCalloc(STATIC_DEPTH, callocSize);
122 timerStop = clock();
123 if (!p) {
124 printf("calloc failure\n");
125 return;
126 }
127 duration += (double)(timerStop - timerStart) / CLOCKS_PER_SEC;
128 g_callocDuration += (double)(timerStop - timerStart) / CLOCKS_PER_SEC;
129 printf("calloc success, calloc (%d) time is %f\n", callocSize, duration);
130 printf("\nReady for free -- ");
131 timerStart = clock();
132 DepthFree(STATIC_DEPTH, p);
133 timerStop = clock();
134 duration += (double)(timerStop - timerStart) / CLOCKS_PER_SEC;
135 g_freeDuration += (double)(timerStop - timerStart) / CLOCKS_PER_SEC;
136 printf("free success, free time is %f\n", (double)(timerStop - timerStart) / CLOCKS_PER_SEC);
137 printf("calloc apply success, total time is %f\n", duration);
138 }
139
ApplyForRealloc(int mallocSize)140 void ApplyForRealloc(int mallocSize)
141 {
142 int reallocSize = mallocSize * DEFAULT_REALLOC_SIZE;
143 printf("\nstart realloc apply (size = %d)\n", reallocSize);
144 if (mallocSize <= 0) {
145 printf("Invalid mallocSize.\n");
146 return;
147 }
148 clock_t timerStart, timerStop;
149 double duration = 0;
150 char *p = (char *)malloc(mallocSize);
151 if (!p) {
152 printf("malloc failure\n");
153 return;
154 }
155 timerStart = clock();
156 char *np = DepthRealloc(STATIC_DEPTH, p, reallocSize);
157 timerStop = clock();
158 if (!np) {
159 free(p);
160 printf("realloc failure\n");
161 return;
162 }
163 duration += (double)(timerStop - timerStart) / CLOCKS_PER_SEC;
164 g_reallocDuration += (double)(timerStop - timerStart) / CLOCKS_PER_SEC;
165 printf("realloc success, realloc (%d) time is %f\n", reallocSize, duration);
166 printf("\nReady for free -- ");
167 timerStart = clock();
168 DepthFree(STATIC_DEPTH, np);
169 timerStop = clock();
170 duration += (double)(timerStop - timerStart) / CLOCKS_PER_SEC;
171 g_freeDuration += (double)(timerStop - timerStart) / CLOCKS_PER_SEC;
172 printf("free success, free time is %f\n", (double)(timerStop - timerStart) / CLOCKS_PER_SEC);
173 printf("realloc apply success, total time is %f\n", duration);
174 }
175
ThreadFuncC(void * param)176 void* ThreadFuncC(void* param)
177 {
178 int mallocCount = 0;
179 int callocCount = 0;
180 int reallocCount = 0;
181 int freeCount = 0;
182 int randNum = 0;
183 int tid = syscall(SYS_gettid);
184 int mallocSize = *(int*)param;
185 printf("start thread %d\n", tid);
186 time_t tv = time(NULL);
187 if (tv == -1) {
188 tv = 1;
189 }
190 unsigned int seed = (unsigned int)tv;
191 while (g_runing) {
192 randNum = rand_r(&seed) % TEST_BRANCH_NUM;
193 if (randNum == 0) {
194 ApplyForMalloc(mallocSize);
195 mallocCount++;
196 } else if (randNum == 1) {
197 ApplyForCalloc(mallocSize);
198 callocCount++;
199 } else {
200 ApplyForRealloc(mallocSize);
201 reallocCount++;
202 }
203 freeCount++;
204 sleep(SLEEP_TIME_SEC);
205 }
206 printf("thread %d malloc count[%d] totalTime[%f] meanTime[%f].\n", tid,
207 mallocCount, g_mallocDuration, g_mallocDuration / mallocCount);
208 printf("thread %d calloc count[%d] totalTime[%f] meanTime[%f].\n", tid,
209 callocCount, g_callocDuration, g_callocDuration / callocCount);
210 printf("thread %d realloc count[%d] totalTime[%f] meanTime[%f].\n", tid,
211 reallocCount, g_reallocDuration, g_reallocDuration / reallocCount);
212 printf("thread %d free count[%d] totalTime[%f] meanTime[%f].\n", tid,
213 freeCount, g_freeDuration, g_freeDuration / freeCount);
214 printf("finish thread %d\n", tid);
215 return NULL;
216 }
217 #define INVALID_THREAD_NUM_RET 1
218 #define INVALID_MALLOC_SIZE_RET 2
main(int argc,char * argv[])219 int main(int argc, char *argv[])
220 {
221 int threadNum = DEFAULT_THREAD_NUM;
222 int mallocSize = DEFAULT_MALLOC_SIZE;
223 switch (argc) {
224 case ARG_CASE_NUM_THREADNUM:
225 threadNum = atoi(argv[ARG_THREADNUM]);
226 mallocSize = atoi(argv[1]);
227 break;
228 case ARG_CASE_MALLOCSIZE:
229 mallocSize = atoi(argv[1]);
230 break;
231 case 1:
232 break;
233 default:
234 printf("Usage: nativetest_c <mallocSize> <threadNum>\n");
235 return 0;
236 }
237 if (threadNum <= 0) {
238 printf("Invalid threadNum.\n");
239 return INVALID_THREAD_NUM_RET;
240 }
241 if (mallocSize <= 0) {
242 printf("Invalid mallocSize\n");
243 return INVALID_MALLOC_SIZE_RET;
244 }
245 pid_t pid = getpid();
246 printf("Process pid %d, Test start %d thread, malloc %d size\n", pid, threadNum, mallocSize);
247
248 pthread_t* thrArray = (pthread_t*)malloc(sizeof(pthread_t) * threadNum);
249 if (thrArray == NULL) {
250 printf("new thread failed.\n");
251 }
252 int idx;
253 for (idx = 0; idx < threadNum; ++idx) {
254 if (pthread_create(thrArray + idx, NULL, ThreadFuncC, (void*)(&mallocSize))) {
255 printf("Creating thread failed.\n");
256 }
257 }
258 while (getchar() != '\n') {};
259 g_runing = 0;
260
261 for (idx = 0; idx < threadNum; ++idx) {
262 pthread_join(thrArray[idx], NULL);
263 }
264 free(thrArray);
265 printf("Exit Process (pid %d)\n", pid);
266 return 0;
267 }
268
269 #pragma clang optimize on
270