• 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 <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