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