1b9f2cc816dc3e5369507db9509bea6d10b524a94Howard Hinnant//===--------------------- test_fallback_malloc.cpp -----------------------===// 2b9f2cc816dc3e5369507db9509bea6d10b524a94Howard Hinnant// 3b9f2cc816dc3e5369507db9509bea6d10b524a94Howard Hinnant// The LLVM Compiler Infrastructure 4b9f2cc816dc3e5369507db9509bea6d10b524a94Howard Hinnant// 5b9f2cc816dc3e5369507db9509bea6d10b524a94Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open 6b9f2cc816dc3e5369507db9509bea6d10b524a94Howard Hinnant// Source Licenses. See LICENSE.TXT for details. 7b9f2cc816dc3e5369507db9509bea6d10b524a94Howard Hinnant// 8b9f2cc816dc3e5369507db9509bea6d10b524a94Howard Hinnant//===----------------------------------------------------------------------===// 9b9f2cc816dc3e5369507db9509bea6d10b524a94Howard Hinnant 1047c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow#include <iostream> 1147c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow#include <deque> 1247c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 1347c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow#include <pthread.h> 1447c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 1547c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clowtypedef std::deque<void *> container; 1647c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 1747c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow// #define DEBUG_FALLBACK_MALLOC 1847c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow#define INSTRUMENT_FALLBACK_MALLOC 1960a178840d23fbf169a22fde1cef5e558ef232f9Howard Hinnant#include "../src/fallback_malloc.ipp" 2047c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 2147c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clowcontainer alloc_series ( size_t sz ) { 2247c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow container ptrs; 2347c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow void *p; 2447c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 2547c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow while ( NULL != ( p = fallback_malloc ( sz ))) 2647c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow ptrs.push_back ( p ); 2747c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow return ptrs; 2847c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow } 2947c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 3047c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clowcontainer alloc_series ( size_t sz, float growth ) { 3147c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow container ptrs; 3247c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow void *p; 3347c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 3447c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow while ( NULL != ( p = fallback_malloc ( sz ))) { 3547c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow ptrs.push_back ( p ); 3647c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow sz *= growth; 3747c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow } 3847c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 3947c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow return ptrs; 4047c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow } 4147c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 4247c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clowcontainer alloc_series ( const size_t *first, size_t len ) { 4347c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow container ptrs; 4447c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow const size_t *last = first + len; 4547c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow void * p; 4647c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 4747c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow for ( const size_t *iter = first; iter != last; ++iter ) { 4847c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow if ( NULL == (p = fallback_malloc ( *iter ))) 4947c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow break; 5047c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow ptrs.push_back ( p ); 5147c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow } 5247c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 5347c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow return ptrs; 5447c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow } 5547c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 5647c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clowvoid *pop ( container &c, bool from_end ) { 5747c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow void *ptr; 5847c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow if ( from_end ) { 5947c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow ptr = c.back (); 6047c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow c.pop_back (); 6147c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow } 6247c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow else { 6347c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow ptr = c.front (); 6447c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow c.pop_front (); 6547c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow } 6647c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow return ptr; 6747c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow } 6847c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 6947c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clowvoid exhaustion_test1 () { 7047c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow container ptrs; 7147c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 7247c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow init_heap (); 7347c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "Constant exhaustion tests" << std::endl; 7447c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 7547c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow// Delete in allocation order 7647c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow ptrs = alloc_series ( 32 ); 7747c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "Allocated " << ptrs.size () << " 32 byte chunks" << std::endl; 7847c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow print_free_list (); 7947c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow for ( container::iterator iter = ptrs.begin (); iter != ptrs.end (); ++iter ) 8047c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow fallback_free ( *iter ); 8147c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow print_free_list (); 8247c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "----" << std::endl; 8347c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 8447c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow// Delete in reverse order 8547c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow ptrs = alloc_series ( 32 ); 8647c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "Allocated " << ptrs.size () << " 32 byte chunks" << std::endl; 8747c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow for ( container::reverse_iterator iter = ptrs.rbegin (); iter != ptrs.rend (); ++iter ) 8847c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow fallback_free ( *iter ); 8947c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow print_free_list (); 9047c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "----" << std::endl; 9147c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 9247c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow// Alternate deletions 9347c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow ptrs = alloc_series ( 32 ); 9447c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "Allocated " << ptrs.size () << " 32 byte chunks" << std::endl; 9547c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow while ( ptrs.size () > 0 ) 9647c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow fallback_free ( pop ( ptrs, ptrs.size () % 1 == 1 )); 9747c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow print_free_list (); 9847c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow } 9947c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 10047c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clowvoid exhaustion_test2 () { 10147c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow container ptrs; 10247c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow init_heap (); 10347c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 10447c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "Growing exhaustion tests" << std::endl; 10547c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 10647c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow// Delete in allocation order 10747c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow ptrs = alloc_series ( 32, 1.5 ); 10847c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "Allocated " << ptrs.size () << " { 32, 48, 72, 108, 162 ... } byte chunks" << std::endl; 10947c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow print_free_list (); 11047c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow for ( container::iterator iter = ptrs.begin (); iter != ptrs.end (); ++iter ) 11147c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow fallback_free ( *iter ); 11247c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow print_free_list (); 11347c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "----" << std::endl; 11447c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 11547c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow// Delete in reverse order 11647c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow print_free_list (); 11747c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow ptrs = alloc_series ( 32, 1.5 ); 11847c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "Allocated " << ptrs.size () << " { 32, 48, 72, 108, 162 ... } byte chunks" << std::endl; 11947c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow for ( container::reverse_iterator iter = ptrs.rbegin (); iter != ptrs.rend (); ++iter ) 12047c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow fallback_free ( *iter ); 12147c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow print_free_list (); 12247c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "----" << std::endl; 12347c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 12447c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow// Alternate deletions 12547c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow ptrs = alloc_series ( 32, 1.5 ); 12647c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "Allocated " << ptrs.size () << " { 32, 48, 72, 108, 162 ... } byte chunks" << std::endl; 12747c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow while ( ptrs.size () > 0 ) 12847c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow fallback_free ( pop ( ptrs, ptrs.size () % 1 == 1 )); 12947c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow print_free_list (); 13047c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 13147c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow } 13247c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 13347c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clowvoid exhaustion_test3 () { 13447c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow const size_t allocs [] = { 124, 60, 252, 60, 4 }; 13547c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow container ptrs; 13647c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow init_heap (); 13747c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 13847c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "Complete exhaustion tests" << std::endl; 13947c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 14047c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow// Delete in allocation order 14147c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow ptrs = alloc_series ( allocs, sizeof ( allocs ) / sizeof ( allocs[0] )); 14247c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "Allocated " << ptrs.size () << " chunks" << std::endl; 14347c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow print_free_list (); 14447c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow for ( container::iterator iter = ptrs.begin (); iter != ptrs.end (); ++iter ) 14547c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow fallback_free ( *iter ); 14647c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow print_free_list (); 14747c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "----" << std::endl; 14847c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 14947c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow// Delete in reverse order 15047c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow print_free_list (); 15147c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow ptrs = alloc_series ( allocs, sizeof ( allocs ) / sizeof ( allocs[0] )); 15247c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "Allocated " << ptrs.size () << " chunks" << std::endl; 15347c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow for ( container::reverse_iterator iter = ptrs.rbegin (); iter != ptrs.rend (); ++iter ) 15447c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow fallback_free ( *iter ); 15547c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow print_free_list (); 15647c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "----" << std::endl; 15747c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 15847c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow// Alternate deletions 15947c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow ptrs = alloc_series ( allocs, sizeof ( allocs ) / sizeof ( allocs[0] )); 16047c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "Allocated " << ptrs.size () << " chunks" << std::endl; 16147c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow while ( ptrs.size () > 0 ) 16247c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow fallback_free ( pop ( ptrs, ptrs.size () % 1 == 1 )); 16347c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow print_free_list (); 16447c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 16547c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow } 16647c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 16747c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 16847c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clowint main ( int argc, char *argv [] ) { 16947c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow print_free_list (); 17047c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 17147c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow char *p = (char *) fallback_malloc ( 1024 ); // too big! 17247c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "fallback_malloc ( 1024 ) --> " << (unsigned long ) p << std::endl; 17347c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow print_free_list (); 17447c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 17547c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow p = (char *) fallback_malloc ( 32 ); 17647c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "fallback_malloc ( 32 ) --> " << (unsigned long) (p - heap) << std::endl; 17747c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow if ( !is_fallback_ptr ( p )) 17847c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << "### p is not a fallback pointer!!" << std::endl; 17947c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 18047c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow print_free_list (); 18147c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow fallback_free ( p ); 18247c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow print_free_list (); 18347c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow 18447c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow std::cout << std::endl; 18547c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow exhaustion_test1 (); std::cout << std::endl; 18647c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow exhaustion_test2 (); std::cout << std::endl; 18747c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow exhaustion_test3 (); std::cout << std::endl; 18847c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow return 0; 18947c29eb784f53ff170074ea00cd238e0e95af82fMarshall Clow } 190