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