• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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