236
|
1 //===----------------------------------------------------------------------===//
|
150
|
2 //
|
|
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
4 // See https://llvm.org/LICENSE.txt for license information.
|
|
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
6 //
|
|
7 //===----------------------------------------------------------------------===//
|
|
8
|
221
|
9 #include <cstdio>
|
150
|
10 #include <deque>
|
236
|
11 #include <cassert>
|
150
|
12
|
|
13 #include <__threading_support>
|
|
14
|
236
|
15 // UNSUPPORTED: c++03
|
|
16 // UNSUPPORTED: modules-build && no-threads
|
|
17
|
|
18 // Necessary because we include a private source file of libc++abi, which
|
|
19 // only understands _LIBCXXABI_HAS_NO_THREADS.
|
|
20 #include "test_macros.h"
|
|
21 #ifdef TEST_HAS_NO_THREADS
|
|
22 # define _LIBCXXABI_HAS_NO_THREADS
|
|
23 #endif
|
|
24
|
150
|
25 typedef std::deque<void *> container;
|
|
26
|
|
27 // #define DEBUG_FALLBACK_MALLOC
|
|
28 #define INSTRUMENT_FALLBACK_MALLOC
|
|
29 #include "../src/fallback_malloc.cpp"
|
|
30
|
236
|
31 void assertAlignment(void* ptr) { assert(reinterpret_cast<size_t>(ptr) % alignof(FallbackMaxAlignType) == 0); }
|
|
32
|
150
|
33 container alloc_series ( size_t sz ) {
|
|
34 container ptrs;
|
|
35 void *p;
|
221
|
36
|
236
|
37 while (NULL != (p = fallback_malloc(sz))) {
|
|
38 assertAlignment(p);
|
|
39 ptrs.push_back(p);
|
|
40 }
|
150
|
41 return ptrs;
|
221
|
42 }
|
150
|
43
|
|
44 container alloc_series ( size_t sz, float growth ) {
|
|
45 container ptrs;
|
|
46 void *p;
|
221
|
47
|
150
|
48 while ( NULL != ( p = fallback_malloc ( sz ))) {
|
236
|
49 assertAlignment(p);
|
|
50 ptrs.push_back(p);
|
|
51 sz *= growth;
|
221
|
52 }
|
150
|
53
|
|
54 return ptrs;
|
221
|
55 }
|
150
|
56
|
|
57 container alloc_series ( const size_t *first, size_t len ) {
|
|
58 container ptrs;
|
|
59 const size_t *last = first + len;
|
|
60 void * p;
|
221
|
61
|
150
|
62 for ( const size_t *iter = first; iter != last; ++iter ) {
|
|
63 if ( NULL == (p = fallback_malloc ( *iter )))
|
|
64 break;
|
236
|
65 assertAlignment(p);
|
150
|
66 ptrs.push_back ( p );
|
221
|
67 }
|
150
|
68
|
|
69 return ptrs;
|
221
|
70 }
|
150
|
71
|
|
72 void *pop ( container &c, bool from_end ) {
|
|
73 void *ptr;
|
|
74 if ( from_end ) {
|
|
75 ptr = c.back ();
|
|
76 c.pop_back ();
|
221
|
77 }
|
150
|
78 else {
|
|
79 ptr = c.front ();
|
|
80 c.pop_front ();
|
221
|
81 }
|
150
|
82 return ptr;
|
221
|
83 }
|
150
|
84
|
|
85 void exhaustion_test1 () {
|
|
86 container ptrs;
|
221
|
87
|
150
|
88 init_heap ();
|
221
|
89 std::printf("Constant exhaustion tests\n");
|
|
90
|
150
|
91 // Delete in allocation order
|
|
92 ptrs = alloc_series ( 32 );
|
221
|
93 std::printf("Allocated %zu 32 byte chunks\n", ptrs.size());
|
150
|
94 print_free_list ();
|
|
95 for ( container::iterator iter = ptrs.begin (); iter != ptrs.end (); ++iter )
|
|
96 fallback_free ( *iter );
|
|
97 print_free_list ();
|
221
|
98 std::printf("----\n");
|
150
|
99
|
|
100 // Delete in reverse order
|
|
101 ptrs = alloc_series ( 32 );
|
221
|
102 std::printf("Allocated %zu 32 byte chunks\n", ptrs.size());
|
150
|
103 for ( container::reverse_iterator iter = ptrs.rbegin (); iter != ptrs.rend (); ++iter )
|
|
104 fallback_free ( *iter );
|
|
105 print_free_list ();
|
221
|
106 std::printf("----\n");
|
150
|
107
|
|
108 // Alternate deletions
|
|
109 ptrs = alloc_series ( 32 );
|
221
|
110 std::printf("Allocated %zu 32 byte chunks\n", ptrs.size());
|
150
|
111 while ( ptrs.size () > 0 )
|
|
112 fallback_free ( pop ( ptrs, ptrs.size () % 1 == 1 ));
|
|
113 print_free_list ();
|
221
|
114 }
|
|
115
|
150
|
116 void exhaustion_test2 () {
|
|
117 container ptrs;
|
|
118 init_heap ();
|
221
|
119
|
|
120 std::printf("Growing exhaustion tests\n");
|
150
|
121
|
|
122 // Delete in allocation order
|
|
123 ptrs = alloc_series ( 32, 1.5 );
|
221
|
124
|
|
125 std::printf("Allocated %zu { 32, 48, 72, 108, 162 ... } byte chunks\n",
|
|
126 ptrs.size());
|
150
|
127 print_free_list ();
|
|
128 for ( container::iterator iter = ptrs.begin (); iter != ptrs.end (); ++iter )
|
|
129 fallback_free ( *iter );
|
|
130 print_free_list ();
|
221
|
131 std::printf("----\n");
|
|
132
|
150
|
133 // Delete in reverse order
|
|
134 print_free_list ();
|
|
135 ptrs = alloc_series ( 32, 1.5 );
|
221
|
136 std::printf("Allocated %zu { 32, 48, 72, 108, 162 ... } byte chunks\n",
|
|
137 ptrs.size());
|
150
|
138 for ( container::reverse_iterator iter = ptrs.rbegin (); iter != ptrs.rend (); ++iter )
|
|
139 fallback_free ( *iter );
|
|
140 print_free_list ();
|
221
|
141 std::printf("----\n");
|
150
|
142
|
|
143 // Alternate deletions
|
|
144 ptrs = alloc_series ( 32, 1.5 );
|
221
|
145 std::printf("Allocated %zu { 32, 48, 72, 108, 162 ... } byte chunks\n",
|
|
146 ptrs.size());
|
150
|
147 while ( ptrs.size () > 0 )
|
|
148 fallback_free ( pop ( ptrs, ptrs.size () % 1 == 1 ));
|
221
|
149 print_free_list ();
|
|
150
|
|
151 }
|
150
|
152
|
|
153 void exhaustion_test3 () {
|
|
154 const size_t allocs [] = { 124, 60, 252, 60, 4 };
|
|
155 container ptrs;
|
|
156 init_heap ();
|
221
|
157
|
|
158 std::printf("Complete exhaustion tests\n");
|
150
|
159
|
|
160 // Delete in allocation order
|
|
161 ptrs = alloc_series ( allocs, sizeof ( allocs ) / sizeof ( allocs[0] ));
|
221
|
162 std::printf("Allocated %zu chunks\n", ptrs.size());
|
150
|
163 print_free_list ();
|
|
164 for ( container::iterator iter = ptrs.begin (); iter != ptrs.end (); ++iter )
|
|
165 fallback_free ( *iter );
|
|
166 print_free_list ();
|
221
|
167 std::printf("----\n");
|
|
168
|
150
|
169 // Delete in reverse order
|
|
170 print_free_list ();
|
|
171 ptrs = alloc_series ( allocs, sizeof ( allocs ) / sizeof ( allocs[0] ));
|
221
|
172 std::printf("Allocated %zu chunks\n", ptrs.size());
|
150
|
173 for ( container::reverse_iterator iter = ptrs.rbegin (); iter != ptrs.rend (); ++iter )
|
|
174 fallback_free ( *iter );
|
|
175 print_free_list ();
|
221
|
176 std::printf("----\n");
|
150
|
177
|
|
178 // Alternate deletions
|
|
179 ptrs = alloc_series ( allocs, sizeof ( allocs ) / sizeof ( allocs[0] ));
|
221
|
180 std::printf("Allocated %zu chunks\n", ptrs.size());
|
150
|
181 while ( ptrs.size () > 0 )
|
|
182 fallback_free ( pop ( ptrs, ptrs.size () % 1 == 1 ));
|
221
|
183 print_free_list ();
|
150
|
184
|
221
|
185 }
|
|
186
|
|
187
|
150
|
188 int main () {
|
|
189 print_free_list ();
|
|
190
|
|
191 char *p = (char *) fallback_malloc ( 1024 ); // too big!
|
221
|
192 std::printf("fallback_malloc ( 1024 ) --> %lu\n", (unsigned long ) p);
|
150
|
193 print_free_list ();
|
221
|
194
|
150
|
195 p = (char *) fallback_malloc ( 32 );
|
221
|
196 std::printf("fallback_malloc ( 32 ) --> %lu\n", (unsigned long) (p - heap));
|
150
|
197 if ( !is_fallback_ptr ( p ))
|
221
|
198 std::printf("### p is not a fallback pointer!!\n");
|
|
199
|
150
|
200 print_free_list ();
|
|
201 fallback_free ( p );
|
|
202 print_free_list ();
|
221
|
203
|
|
204 exhaustion_test1();
|
|
205 exhaustion_test2();
|
|
206 exhaustion_test3();
|
150
|
207 return 0;
|
221
|
208 }
|