1 #include <malloc.h>
2 #include <time.h>
3 #include <sched.h>
4 #include <errno.h>
5 #include <string.h>
6 #include <pthread.h>
7 #include "test.h"
8
9 #define THREAD_MAX_N 8
10 #define SIZE_ALIGN (4 * sizeof(size_t))
11 #define MMAP_THRESHOLD 131052
12 #define FREE_CYCLE 16
13 #define THRESHOLD (MMAP_THRESHOLD / 16)
14 #define ITER_TIME 80
15 #define NANOSEC_PER_SEC 1e9
16 #define MALLOC_TIME (ITER_TIME * (THRESHOLD / (SIZE_ALIGN + 1)))
17
free_all(void ** ptr)18 void free_all(void **ptr)
19 {
20 for (int j = 0; j < FREE_CYCLE; j++) {
21 free(ptr[j]);
22 }
23 }
24
func(void * arg)25 void *func(void *arg)
26 {
27 int *val = (int *)arg;
28 cpu_set_t mask;
29 struct timespec ts[2];
30 int num = 0;
31 void *ptr[FREE_CYCLE];
32
33 CPU_ZERO(&mask);
34 CPU_SET(0, &mask);
35 if (sched_setaffinity(0, sizeof(mask), &mask) < 0) {
36 t_error("Set CPU affinity of thread %d failure, ERROR:%s\n", *val, strerror(errno));
37 return NULL;
38 }
39
40 for (int i = 0; i < ITER_TIME; ++i) {
41 for (size_t size = 0; size < THRESHOLD; size += SIZE_ALIGN + 1) {
42 if (num == FREE_CYCLE) {
43 free_all(ptr);
44 num = 0;
45 }
46 ptr[num] = malloc(size);
47 if (!ptr[num]) {
48 t_error("Thread %d malloc failed for size %u\n", *val, size);
49 *val = errno;
50 return NULL;
51 }
52 num++;
53 }
54 }
55
56 *val = 0;
57 return NULL;
58 }
59
main(int argc,char * argv[])60 int main(int argc, char *argv[])
61 {
62 struct timespec ts[2];
63 pthread_attr_t attr;
64 pthread_t tids[THREAD_MAX_N];
65 int t_result[THREAD_MAX_N] = {0};
66 int flag = 0;
67 int ret;
68 int i;
69
70 ret = pthread_attr_init(&attr);
71 if (ret < 0) {
72 t_error("Init pthread attribute failed: %s\n", strerror(errno));
73 return -1;
74 }
75
76 clock_gettime(CLOCK_REALTIME, ts);
77 for (i = 0; i < THREAD_MAX_N; ++i) {
78 t_result[i] = i;
79 ret = pthread_create(&tids[i], &attr, func, &t_result[i]);
80 if (ret < 0) {
81 t_error("Create pthread %u failed: %s\n", i, strerror(errno));
82 flag = -1;
83 break;
84 }
85 }
86
87 for (i = 0; i < THREAD_MAX_N; ++i) {
88 ret = pthread_join(tids[i], NULL);
89 if (ret < 0) {
90 t_error("Join thread %u failed: %s\n", i, strerror(errno));
91 }
92 }
93 clock_gettime(CLOCK_REALTIME, ts + 1);
94
95 (void)pthread_attr_destroy(&attr);
96
97 double cost = (ts[1].tv_sec - ts[0].tv_sec) * NANOSEC_PER_SEC +
98 (ts[1].tv_nsec - ts[0].tv_nsec);
99
100 if (!flag) {
101 t_printf("Malloc and free %d threads %d times cost %lf s\n", THREAD_MAX_N, MALLOC_TIME, cost / NANOSEC_PER_SEC);
102 t_status = 0;
103 }
104
105 return t_status;
106 }
107