#include "PerProcess.h"
#include "VMAllocate.h"
#include <stdio.h>
namespace bmalloc {
static constexpr unsigned tableSize = 100;
static constexpr bool verbose = false;
static Mutex s_mutex;
static char* s_bumpBase;
static size_t s_bumpOffset;
static size_t s_bumpLimit;
static PerProcessData* s_table[tableSize];
static void* allocate(size_t size, size_t alignment)
{
s_bumpOffset = roundUpToMultipleOf(alignment, s_bumpOffset);
void* result = s_bumpBase + s_bumpOffset;
s_bumpOffset += size;
if (s_bumpOffset <= s_bumpLimit)
return result;
size_t allocationSize = vmSize(size);
void* allocation = vmAllocate(allocationSize);
s_bumpBase = static_cast<char*>(allocation);
s_bumpOffset = 0;
s_bumpLimit = allocationSize;
return allocate(size, alignment);
}
PerProcessData* getPerProcessData(unsigned hash, const char* disambiguator, size_t size, size_t alignment)
{
std::lock_guard<Mutex> lock(s_mutex);
PerProcessData*& bucket = s_table[hash % tableSize];
for (PerProcessData* data = bucket; data; data = data->next) {
if (!strcmp(data->disambiguator, disambiguator)) {
if (verbose)
fprintf(stderr, "%d: Using existing %s\n", getpid(), disambiguator);
RELEASE_BASSERT(data->size == size);
RELEASE_BASSERT(data->alignment == alignment);
return data;
}
}
if (verbose)
fprintf(stderr, "%d: Creating new %s\n", getpid(), disambiguator);
void* rawDataPtr = allocate(sizeof(PerProcessData), std::alignment_of<PerProcessData>::value);
PerProcessData* data = static_cast<PerProcessData*>(rawDataPtr);
data->disambiguator = disambiguator;
data->memory = allocate(size, alignment);
data->size = size;
data->alignment = alignment;
data->next = bucket;
bucket = data;
return data;
}
}