static unsigned int __stdcall memory_alloc_test_thread_func(void*) { allocs_info* info = new allocs_info; info->count = 0; info->memory = new char*[loop_count]; std::size_t count = 0; while (count < run_count) { for (std::size_t i = 0; i < loop_count; ++i) { std::size_t size = ::rand() % (8 * 1024); #ifdef LARGE_MEMORY size += 20 * 1024; #endif #if defined(CRT_LFH) || defined(TBBMALLOC) || defined(TCMALLOC) info->memory[i] = new char[size]; #elif defined(MS_CONCURRENCY) info->memory[i] = reinterpret_cast<char*>(Concurrency::Alloc(size)); #elif defined(MY_ALLOCATOR) info->memory[i] = reinterpret_cast<char*>(allocator.alloc(size)); #elif defined(JEMALLOC) info->memory[i] = reinterpret_cast<char*>(je_malloc(size)); #endif ++info->count; SecureZeroMemory(info->memory[i], size); //::memset( info->memory[i], 0xff, size ); } #ifdef OTHER_THREAD_FREE unsigned int id = 0; HANDLE free_thread = reinterpret_cast< HANDLE >(::_beginthreadex(nullptr, 0, memory_free_test_thread_func, info, 0, &id)); if (free_thread != nullptr) { ::WaitForSingleObject(free_thread, INFINITE); ::CloseHandle(free_thread); } else { free_all(info); } #else free_all(info); #endif ++count; } delete[] info->memory; info->memory = nullptr; delete info; return 0; }
void print_allocator_stat(const memory::allocator* allocator) { const memory::statistics* stat = allocator->get_statistics(); assert(stat != nullptr); size_t heap_alloc = 0; size_t heap_free = 0; for (size_t i = 0; i < stat->get_heap_count(); ++i) { const memory::heap_statistics_t* heap = stat->get_heap(i); assert(heap != nullptr); if (heap != nullptr) { ::wprintf(L"heap[%u]: alloc: %u, free: %u\n", i, heap->alloc, heap->free); heap_alloc += heap->alloc; heap_free += heap->free; } } size_t lookaside_alloc = 0; size_t lookaside_free = 0; for (size_t i = 0; i < stat->get_cache_count(); ++i) { const memory::cache_statistics_t* cache = stat->get_cache(i); assert(cache != nullptr); if (cache != nullptr) { size_t cache_alloc = 0; size_t cache_free = 0; for (size_t j = 0; j < cache->count; ++j) { const memory::lookaside_statistics_t* lookaside = &cache->lookaside[j]; cache_alloc += lookaside->alloc; cache_free += lookaside->free; } lookaside_alloc += cache_alloc; lookaside_free += cache_free; ::wprintf(L"cache[%u]: alloc: %u, free: %u\n", i, cache_alloc, cache_free); } } ::wprintf(L"\nheap(%u) alloc: %u, free: %u\n", stat->get_heap_count(), heap_alloc, heap_free); ::wprintf(L"lookaside(%u) alloc: %u, free: %u\n", stat->get_cache_count(), lookaside_alloc, lookaside_free); ::wprintf(L"total alloc: %u, total free: %u\n", heap_alloc + lookaside_alloc, heap_free + lookaside_free); }
void free_all(allocs_info* info) { for (int i = 0; i < info->count; ++i) { #if defined( CRT_LFH ) || defined( TBBMALLOC ) || defined( TCMALLOC ) delete[] info->memory[i]; #elif defined( MS_CONCURRENCY ) Concurrency::Free(info->memory[i]); #elif defined( LOOKASIDE_HEAP ) allocator.free(info->memory[i]); #endif info->memory[i] = nullptr; } info->count = 0; }
void free_all(allocs_info* info) { for (std::size_t i = 0; i < info->count; ++i) { #if defined(CRT_LFH) || defined(TBBMALLOC) || defined(TCMALLOC) delete[] info->memory[i]; #elif defined(MS_CONCURRENCY) Concurrency::Free(info->memory[i]); #elif defined(MY_ALLOCATOR) allocator.free(info->memory[i]); #elif defined(JEMALLOC) je_free(info->memory[i]); #endif info->memory[i] = nullptr; } info->count = 0; }
int main() { #if defined(CRT_LFH) ::wprintf(L"crt lfh\n"); set_lfh(); #elif defined(TBBMALLOC) ::wprintf(L"tbbmalloc\n"); #elif defined(TCMALLOC) ::wprintf(L"tcmalloc\n"); #elif defined(JEMALLOC) ::wprintf(L"jemalloc\n"); set_jemalloc(); #elif defined(MS_CONCURRENCY) ::wprintf(L"ms concurrency\n"); #elif defined(MY_ALLOCATOR) ::wprintf(L"my allocator\n"); if (allocator.create(true, 0) == false) { ::wprintf(L"allocator.create() failed.\n"); return 0; } #endif // for crt tbb tcmalloc char* dummy = new char[10]; SecureZeroMemory(dummy, 10); ::wprintf(L"start memory info\n"); print_memory_info(); HANDLE thread_handle[thread_count] = { nullptr, }; ULONGLONG start = ::GetTickCount64(); for (std::size_t i = 0; i < thread_count; ++i) { unsigned int id = 0; thread_handle[i] = reinterpret_cast< HANDLE >(::_beginthreadex(nullptr, 0, memory_alloc_test_thread_func, nullptr, 0, &id)); if (thread_handle[i] == nullptr) { ::wprintf(L"%llu: _beginthreadex failed.\n", i); } } ::WaitForMultipleObjects(thread_count, thread_handle, TRUE, INFINITE); ULONGLONG run_time = ::GetTickCount64() - start; ::wprintf(L"run time: %llu\n", run_time); for (std::size_t i = 0; i < thread_count; ++i) { if (thread_handle[i] != nullptr) { ::CloseHandle(thread_handle[i]); thread_handle[i] = nullptr; } } delete[] dummy; dummy = nullptr; ::wprintf(L"end memory info\n"); print_memory_info(); #if defined(MY_ALLOCATOR) print_allocator_stat(allocator.get_statistics()); allocator.destroy(); #elif defined(JEMALLOC) { //je_malloc_stats_print(nullptr, nullptr, nullptr); size_t sz = sizeof(jemalloc_post_allocated); je_mallctl("stats.active", &jemalloc_post_allocated, &sz, nullptr, 0); size_t leaked = jemalloc_post_allocated - jemalloc_pre_allocated; ::wprintf(L"\nDone. Leaked: %zd bytes\n", leaked); bool failed = leaked > 65536; // in case C++ runtime allocated something (e.g. iostream locale or facet) ::wprintf(L"\nTest %s!\n", (failed ? L"FAILED" : L"successful")); } #endif return 0; }
int main() { #if defined( CRT_LFH ) ::wprintf(L"crt lfh\n"); set_lfh(); #elif defined( TBBMALLOC ) ::wprintf(L"tbbmalloc\n"); #elif defined( TCMALLOC ) ::wprintf(L"tcmalloc\n"); #elif defined( MS_CONCURRENCY ) ::wprintf(L"ms concurrency\n"); #elif defined( LOOKASIDE_HEAP ) ::wprintf(L"lookaside heap\n"); if (allocator.create(true) == false) { ::wprintf(L"allocator.create() failed.\n"); return 0; } #endif HANDLE thread_handle[thread_count] = { nullptr, }; DWORD start = ::GetTickCount(); for (int i = 0; i < thread_count; ++i) { unsigned int id = 0; thread_handle[i] = reinterpret_cast< HANDLE >(::_beginthreadex(nullptr, 0, memory_alloc_test_thread_func, nullptr, 0, &id)); if (thread_handle[i] == nullptr) { wprintf(L"%d: _beginthreadex failed.\n", i); } } ::WaitForMultipleObjects(thread_count, thread_handle, TRUE, INFINITE); DWORD run_time = ::GetTickCount() - start; ::wprintf(L"run time: %d\n", run_time); for (int i = 0; i < thread_count; ++i) { if (thread_handle[i] != nullptr) { ::CloseHandle(thread_handle[i]); thread_handle[i] = nullptr; } } #ifdef LOOKASIDE_HEAP print_allocator_stat(&allocator); allocator.destroy(); #endif return 0; }