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