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