• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef TEST_MALLOC_STATS_COMMON_H
17 #define TEST_MALLOC_STATS_COMMON_H
18 
19 #define _GNU_SOURCE
20 
21 #include <unistd.h>
22 #include <sys/syscall.h>
23 #include <stddef.h>
24 #include <pthread.h>
25 #include <malloc.h>
26 #include "test.h"
27 
28 #define SIZES_COUNT 10
29 #define SIZE_ALIGN (8 * sizeof(size_t))
30 #define MMAP_THRESHOLD ((0x1c00 * SIZE_ALIGN) - OVERHEAD)
31 #define LIST_OVERHEAD (2 * sizeof(void *))
32 #define OVERHEAD (sizeof(size_t) + LIST_OVERHEAD)
33 
34 static size_t sizes[SIZES_COUNT] = {
35 	23,
36 	32,
37 	256,
38 	3072,
39 	3584,
40 	262144,
41 	327680,
42 	8 * 1024 * 1024,
43 	16 * 1024 * 1024,
44 	32 * 1024 * 1024
45 };
46 
47 typedef struct {
48 	long long mmapped_regions;
49 	long long total_mmapped_memory;
50 	long long total_allocated_memory;
51 } malloc_thread_stats_t;
52 
53 typedef struct {
54 	size_t alloc_size;
55 	pthread_barrier_t *alloc_barrier;
56 	pthread_barrier_t *free_barrier;
57 	pid_t self_id;
58 } thread_data_t;
59 
get_total_from_test_sizes()60 static malloc_thread_stats_t get_total_from_test_sizes()
61 {
62 	malloc_thread_stats_t total_stats = {0};
63 	for (size_t i = 0; i < SIZES_COUNT; i++) {
64 		if (sizes[i] > MMAP_THRESHOLD) {
65 			total_stats.total_mmapped_memory += sizes[i];
66 			total_stats.mmapped_regions++;
67 		}
68 		total_stats.total_allocated_memory += sizes[i];
69 	}
70 	return total_stats;
71 }
72 
expect_greater_equal(long long amt1,long long amt2,const char * amt1_name,const char * amt2_name)73 static int expect_greater_equal(long long amt1, long long amt2, const char *amt1_name, const char *amt2_name)
74 {
75 	if (amt1 >= amt2) {
76 		return 1;
77 	}
78 	t_error("Expected %s(value: %lld) to be >= %s(value: %lld)\n", amt1_name, amt1, amt2_name, amt2);
79 	return 0;
80 }
81 
expect_equal(long long amt,long long value,const char * amt_name)82 static int expect_equal(long long amt, long long value, const char *amt_name)
83 {
84 	if (amt == value) {
85 		return 1;
86 	}
87 	t_error("Expected %s(value: %lld) to be %lld\n", amt_name, amt, value);
88 	return 0;
89 }
90 
validate_total_allocated(malloc_thread_stats_t * total_stats)91 static int validate_total_allocated(malloc_thread_stats_t *total_stats)
92 {
93 	malloc_thread_stats_t total_from_test_sizes = get_total_from_test_sizes();
94 
95 	int result = expect_greater_equal(
96 		total_stats->total_allocated_memory,
97 		total_from_test_sizes.total_allocated_memory,
98 		"allocated memory",
99 		"total memory from test sizes");
100 	result &= expect_greater_equal(
101 		total_stats->total_mmapped_memory,
102 		total_from_test_sizes.total_mmapped_memory,
103 		"mmapped memory",
104 		"total large memory from test sizes");
105 	result &= expect_equal(
106 		total_stats->mmapped_regions,
107 		total_from_test_sizes.mmapped_regions,
108 		"mmapped regions");
109 	return result;
110 }
111 
validate_all_freed(malloc_thread_stats_t * total_stats)112 static int validate_all_freed(malloc_thread_stats_t *total_stats)
113 {
114 	int result = expect_equal(total_stats->total_allocated_memory, 0, "allocated memory");
115 	result &= expect_equal(total_stats->total_mmapped_memory, 0, "mmapped memory");
116 	result &= expect_equal(total_stats->mmapped_regions, 0, "mmapped regions");
117 	return result;
118 }
119 
allocate_wait_free(void * arg)120 static void *allocate_wait_free(void *arg)
121 {
122 	thread_data_t *thread_data = arg;
123 	thread_data->self_id = syscall(__NR_gettid);
124 	void *alloc = malloc(thread_data->alloc_size);
125 	pthread_barrier_wait(thread_data->alloc_barrier);
126 	pthread_barrier_wait(thread_data->free_barrier);
127 	free(alloc);
128 	return NULL;
129 }
130 
131 #endif // TEST_MALLOC_STATS_COMMON_H
132