Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ if(MSVC)
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG")
else()
find_package(Threads REQUIRED)
add_compile_options(-mcx16 -march=native -Wall -Wextra -Werror -g)
add_compile_options(-mcx16 -march=native -Wall -Wextra -Werror -Wsign-conversion -g)
endif()

set(CMAKE_CXX_STANDARD 17)
Expand Down
24 changes: 20 additions & 4 deletions src/mem/largealloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ namespace snmalloc
return std::make_pair(r, size);
}

void new_block()
{
auto r_size = reserve_block();
bump = (size_t)r_size.first;
remaining = r_size.second;
}

public:
/**
* Stack of large allocations that have been returned for reuse.
Expand All @@ -61,6 +68,7 @@ namespace snmalloc
* Primitive allocator for structure that are required before
* the allocator can be running.
***/
template<size_t alignment = 64>
void* alloc_chunk(size_t size)
{
// Cache line align
Expand All @@ -70,12 +78,20 @@ namespace snmalloc
{
FlagLock f(lock);

if (remaining < size)
auto aligned_bump = bits::align_up(bump, alignment);
if ((aligned_bump - bump) < size)
{
new_block();
}
else
{
auto r_size = reserve_block();
remaining -= aligned_bump - bump;
bump = aligned_bump;
}

bump = (size_t)r_size.first;
remaining = r_size.second;
if (remaining < size)
{
new_block();
}

p = (void*)bump;
Expand Down
17 changes: 9 additions & 8 deletions src/mem/pagemap.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ namespace snmalloc
value, (PagemapEntry*)LOCKED_ENTRY, std::memory_order_relaxed))
{
auto& v = default_memory_provider;
value = (PagemapEntry*)v.alloc_chunk(PAGEMAP_NODE_SIZE);
value =
(PagemapEntry*)v.alloc_chunk<OS_PAGE_SIZE>(PAGEMAP_NODE_SIZE);
e->store(value, std::memory_order_release);
}
else
Expand Down Expand Up @@ -160,6 +161,13 @@ namespace snmalloc
return &(leaf_ix.first->values[leaf_ix.second]);
}

std::atomic<T>* get_ptr(void* p)
{
bool success;
return get_addr<true>(p, success);
}

public:
/**
* Returns the index of a pagemap entry within a given page. This is used
* in code that propagates changes to the pagemap elsewhere.
Expand All @@ -182,13 +190,6 @@ namespace snmalloc
reinterpret_cast<uintptr_t>(get_addr<true>(p, success)));
}

std::atomic<T>* get_ptr(void* p)
{
bool success;
return get_addr<true>(p, success);
}

public:
T get(void* p)
{
bool success;
Expand Down
33 changes: 17 additions & 16 deletions src/mem/remoteallocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "../ds/mpscq.h"
#include "../mem/allocconfig.h"
#include "../mem/sizeclass.h"

#include <atomic>

Expand All @@ -10,13 +11,11 @@ namespace snmalloc
struct Remote
{
static const size_t PTR_BITS = sizeof(void*) * 8;
static const size_t SIZECLASS_BITS = sizeof(uint8_t) * 8;
static const size_t SIZECLASS_BITS =
bits::next_pow2_bits_const(NUM_SIZECLASSES);
static const bool USE_TOP_BITS =
SIZECLASS_BITS + bits::ADDRESS_BITS <= PTR_BITS;
static const uintptr_t SIZECLASS_SHIFT = PTR_BITS - SIZECLASS_BITS;
static const uintptr_t SIZECLASS_MASK = ((1ULL << SIZECLASS_BITS) - 1)
<< SIZECLASS_SHIFT;
static const uintptr_t TARGET_MASK = ~SIZECLASS_MASK;
SIZECLASS_BITS + bits::ADDRESS_BITS < PTR_BITS;
static const uintptr_t SIZECLASS_MASK = ((1ULL << SIZECLASS_BITS) - 1);

using alloc_id_t = size_t;
union
Expand All @@ -25,7 +24,11 @@ namespace snmalloc
Remote* non_atomic_next;
};

uintptr_t value;
// Uses an intptr_t so that when we use the TOP_BITS to encode the
// sizeclass, then we can use signed shift to correctly handle kernel versus
// user mode.
intptr_t value;

// This will not exist for the minimum object size. This is only used if
// USE_TOP_BITS is false, and the bottom bit of value is set.
uint8_t possible_sizeclass;
Expand All @@ -34,21 +37,19 @@ namespace snmalloc
{
if constexpr (USE_TOP_BITS)
{
assert(id == (id & TARGET_MASK));
value = (id & TARGET_MASK) |
((static_cast<uint64_t>(sizeclass) << SIZECLASS_SHIFT) &
SIZECLASS_MASK);
value = (intptr_t)(
(id << SIZECLASS_BITS) | ((static_cast<uintptr_t>(sizeclass))));
}
else
{
assert((id & 1) == 0);
if (sizeclass == 0)
{
value = id | 1;
value = (intptr_t)(id | 1);
}
else
{
value = id;
value = (intptr_t)id;
possible_sizeclass = sizeclass;
}
}
Expand All @@ -58,19 +59,19 @@ namespace snmalloc
{
if constexpr (USE_TOP_BITS)
{
return value & TARGET_MASK;
return (alloc_id_t)(value >> SIZECLASS_BITS);
}
else
{
return value & ~1;
return (alloc_id_t)(value & ~1);
}
}

uint8_t sizeclass()
{
if constexpr (USE_TOP_BITS)
{
return (value & SIZECLASS_MASK) >> SIZECLASS_SHIFT;
return (static_cast<uint8_t>((uintptr_t)value & SIZECLASS_MASK));
}
else
{
Expand Down