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 18void free_all(void **ptr) 19{ 20 for (int j = 0; j < FREE_CYCLE; j++) { 21 free(ptr[j]); 22 } 23} 24 25void *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 60int 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