Skip to content

Commit

Permalink
Fix alignment issues when using SMM_FLOAT_PARTITIONING
Browse files Browse the repository at this point in the history
  • Loading branch information
SergeyMakeev committed Oct 6, 2023
1 parent ef2fadc commit 53a0463
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 21 deletions.
13 changes: 7 additions & 6 deletions SmMalloc/smmalloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,14 @@ void TlsPoolBucket::Init(uint32_t* pCacheStack, uint32_t maxElementsNum, CacheWa
SM_ASSERT(pBucket);
pBucketData = pBucket->pData;

if (warmupOptions == CACHE_COLD)
// warmup cache
size_t elementSize = sm::getBucketSizeInBytesByIndex(bucketIndex);

if (warmupOptions == CACHE_COLD || !IsAligned(elementSize, 16))
{
return;
}

// warmup cache
size_t elementSize = sm::getBucketSizeInBytesByIndex(bucketIndex);
uint32_t num = (warmupOptions == CACHE_WARM) ? (maxElementsCount / 2) : (maxElementsCount);

CacheWarmupLink* pRoot = nullptr;
Expand Down Expand Up @@ -141,7 +142,7 @@ void Allocator::CreateThreadCache(CacheWarmupOptions warmupOptions, std::initial
uint32_t elementsNum = _elementsNum + SMM_MAX_CACHE_ITEMS_COUNT;

// allocate stack for cache
uint32_t* localStack = (uint32_t*)GenericAllocator::Alloc(gAllocator, elementsNum * sizeof(uint32_t), 64);
uint32_t* localStack = (uint32_t*)GenericAllocator::Alloc(gAllocator, elementsNum * sizeof(uint32_t), kMaxValidAlignment);

// initialize
GetTlsBucket(i)->Init(localStack, elementsNum, warmupOptions, this, i);
Expand Down Expand Up @@ -240,8 +241,8 @@ void Allocator::Init(uint32_t _bucketsCount, size_t _bucketSizeInBytes)
}

bucketsCount = _bucketsCount;
size_t alignmentMax = GetNextPow2((uint32_t)(16 * bucketsCount));
bucketSizeInBytes = Align(_bucketSizeInBytes, alignmentMax);
size_t alignmentMax = kMaxValidAlignment;
bucketSizeInBytes = Align(_bucketSizeInBytes, kMaxValidAlignment);

size_t i = 0;
for (i = 0; i < bucketsDataBegin.size(); i++)
Expand Down
12 changes: 6 additions & 6 deletions SmMalloc/smmalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ class Allocator
static const size_t kMinValidAlignment = 16;

private:
static const size_t kMaxValidAlignment = 16384;
static const size_t kMaxValidAlignment = 128;

friend struct internal::TlsPoolBucket;

Expand Down Expand Up @@ -532,19 +532,19 @@ class Allocator
}
#endif

size_t bytesCount = (_bytesCount < alignment) ? alignment : _bytesCount;
size_t bytesCount = Align(_bytesCount, alignment);
size_t bucketIndex = getBucketIndexBySize(bytesCount);

#ifdef SMMALLOC_STATS_SUPPORT
bool isValidBucket = false;
#endif

if (bucketIndex < bucketsCount)

// only allocate from thread-local cache is alignment is compatible
if (bucketIndex < bucketsCount && IsAligned(alignment, 16))
{
#ifdef SMMALLOC_STATS_SUPPORT
isValidBucket = true;
#endif

// try to handle allocation using local thread cache
void* pRes = AllocFromCache(GetTlsBucket(bucketIndex));
if (pRes)
Expand Down Expand Up @@ -694,7 +694,7 @@ class Allocator
}

// check if we need to realloc from generic allocator to smmalloc
size_t __bytesCount = (bytesCount < alignment) ? alignment : bytesCount;
size_t __bytesCount = Align(bytesCount, alignment);
size_t __bucketIndex = getBucketIndexBySize(__bytesCount);
if (__bucketIndex < bucketsCount)
{
Expand Down
44 changes: 36 additions & 8 deletions smmalloc_test01.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,42 @@
#include <smmalloc.h>
#include <vector>

bool IsAligned(void* p, size_t alignment)
{
uintptr_t v = uintptr_t(p);
size_t lowBits = v & (alignment - 1);
return (lowBits == 0);
}



TEST(SimpleTests, AlignmentTest)
{
sm_allocator heap = _sm_allocator_create(5, (48 * 1024 * 1024));

for (size_t iter = 0; iter < 10000; iter++)
{
void* p1 = _sm_malloc(heap, 20, 1);
ASSERT_TRUE(IsAligned(p1, 1));
void* p2 = _sm_malloc(heap, 20, 2);
ASSERT_TRUE(IsAligned(p2, 2));
void* p4 = _sm_malloc(heap, 20, 4);
ASSERT_TRUE(IsAligned(p4, 4));
void* p8 = _sm_malloc(heap, 20, 8);
ASSERT_TRUE(IsAligned(p8, 8));
void* p16 = _sm_malloc(heap, 20, 16);
ASSERT_TRUE(IsAligned(p16, 16));
void* p32 = _sm_malloc(heap, 20, 32);
ASSERT_TRUE(IsAligned(p32, 32));
void* p64 = _sm_malloc(heap, 20, 64);
ASSERT_TRUE(IsAligned(p64, 64));
void* p128 = _sm_malloc(heap, 20, 128);
ASSERT_TRUE(IsAligned(p128, 128));
}

_sm_allocator_destroy(heap);
}

TEST(SimpleTests, Basic)
{
sm_allocator heap = _sm_allocator_create(5, (48 * 1024 * 1024));
Expand Down Expand Up @@ -135,14 +171,6 @@ TEST(SimpleTests, MegaAlloc)
}


bool IsAligned(void* p, size_t alignment)
{
uintptr_t v = uintptr_t(p);
size_t lowBits = v & (alignment - 1);
return (lowBits == 0);
}


TEST(SimpleTests, ReAlloc)
{
sm_allocator heap = _sm_allocator_create(5, (48 * 1024 * 1024));
Expand Down
3 changes: 2 additions & 1 deletion smmalloc_test02.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ TEST(MultithreadingTests, StressTest)
void* p = nullptr;
for (;; availCount++)
{
p = _sm_malloc(heap, elementSize, 16);
// set alignement to 1 to avoid internal size alignment (based on requested alignemnt size)
p = _sm_malloc(heap, elementSize, 1);
ptrs.push_back(p);
if (_sm_mbucket(heap, p) != bucketIndex)
{
Expand Down

0 comments on commit 53a0463

Please sign in to comment.