/* Copyright (c) 2005-2021 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #define __TBB_NO_IMPLICIT_LINKAGE 1 #include "common/test.h" #include "common/utils.h" #include "common/utils_report.h" #include "common/memory_usage.h" #include "oneapi/tbb/detail/_utils.h" #include "tbb/scalable_allocator.h" #include "thread" #include class minimalAllocFree { public: void operator()(int size) const { tbb::scalable_allocator a; char* str = a.allocate( size ); a.deallocate( str, size ); } }; template void RunThread(const Body& body, const Arg& arg) { std::thread job(body, arg); job.join(); } /*--------------------------------------------------------------------*/ // The regression test against bug #1518 where thread bootstrap allocations "leaked" bool TestBootstrapLeak() { /* In the bug 1518, each thread leaked ~384 bytes. Initially, scalable allocator maps 1MB. Thus it is necessary to take out most of this space. 1MB is chunked into 16K blocks; of those, one block is for thread bootstrap, and one more should be reserved for the test body. 62 blocks left, each can serve 15 objects of 1024 bytes. */ const int alloc_size = 1024; const int take_out_count = 15*62; tbb::scalable_allocator a; char* array[take_out_count]; for( int i=0; i0 ) { // possibly too strong? REPORT( "Error: memory leak of up to %ld bytes\n", static_cast(memory_leak)); } for( int i=0; i=startSz, "scalable_msize must be not less then allocated size"); memset(buf, 'a', realSz-1); buf[realSz-1] = 0; char *buf1 = (char*)scalable_realloc(buf, 2*realSz); REQUIRE_MESSAGE(buf1, ""); REQUIRE_MESSAGE((scalable_msize(buf1)>=2*realSz), "scalable_msize must be not less then allocated size"); buf1[2*realSz-1] = 0; if ( strspn(buf1, "a") < realSz-1 ) { REPORT( "Error: data broken for %d Bytes object.\n", startSz); passed = false; } scalable_free(buf1); return passed; } // regression test against incorrect work of msize/realloc // for aligned objects void TestAlignedMsize() { const int NUM = 4; char *p[NUM]; size_t objSizes[NUM]; size_t allocSz[] = {4, 8, 512, 2*1024, 4*1024, 8*1024, 16*1024, 0}; size_t align[] = {8, 512, 2*1024, 4*1024, 8*1024, 16*1024, 0}; for (int a=0; align[a]; a++) for (int s=0; allocSz[s]; s++) { for (int i=0; i= allocSz[s], "allocated size must be not less than requested"); memset(p[i], i, objSizes[i]); } for (int i=0; i