Skip to content
Open
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
7 changes: 5 additions & 2 deletions Engine/src/delta/core/EngineTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace delta::core
{
// TODO: revise this structure and its purpose
struct ThreadPageCoordinator
{
uint8_t* virtualAddressBase;
Expand All @@ -12,7 +13,7 @@ namespace delta::core
size_t pageSize;
};

struct EngineArena
struct ThreadArena
{
uint8_t* backingMemory;
size_t capacity;
Expand All @@ -25,7 +26,9 @@ namespace delta::core
uint32_t threadId;

ThreadPageCoordinator pageCoordinator;
EngineArena transientArena;
ThreadArena transientArena;
ThreadArena componentPoolArena;
ThreadArena sceneArena;
delta::platform::Timer perThreadTimer;
};

Expand Down
20 changes: 13 additions & 7 deletions Engine/src/delta/core/MemoryConfig.cpp
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
#include "MemoryConfig.h"

#include "EngineTypes.h"
#include <delta/platform/os.h>

namespace delta::core
{
EngineMemoryConfig g_MemoryConfig{};
std::atomic<size_t> g_TotalLockedBytes{ 0 };

void MemoryConfig_Initialize(size_t physicalRamInstalled, uint32_t maxEngineWorkers)
void MemoryConfig_Initialize(size_t physicalRamInstalled, size_t pageSize, uint32_t maxEngineWorkers)
{
g_MemoryConfig.totalPhysicalRam = physicalRamInstalled;
g_MemoryConfig.globalLockCeiling = (g_MemoryConfig.totalPhysicalRam / 10) * 7;
g_MemoryConfig.threadSoftBaseline = g_MemoryConfig.globalLockCeiling / maxEngineWorkers;
g_MemoryConfig.maxAllowedPhysical = (physicalRamInstalled / 10) * 7; // 70% of total capacity

// calculate soft baseline (ideal case, no stealing from the global pool)
g_MemoryConfig.threadSoftBaseline = MemoryMap::VIRT_ZONE_TA_BASELINE;

size_t totalControlTrackBytes = maxEngineWorkers * (sizeof(ThreadExecutionContext) + MemoryMap::VIRT_ZONE_QUEUE_SIZE);
size_t totalPrivateArenaBytes = maxEngineWorkers * MemoryMap::VIRT_ZONE_BASELINE_SUM;
size_t rawLockBudget = totalControlTrackBytes + totalPrivateArenaBytes;

g_TotalLockedBytes.store(0, std::memory_order_relaxed);
g_MemoryConfig.activeLockAllocation = (rawLockBudget + (pageSize - 1)) & ~(pageSize - 1);
g_MemoryConfig.globalPoolSize = g_MemoryConfig.maxAllowedPhysical - g_MemoryConfig.activeLockAllocation;
assert(g_MemoryConfig.activeLockAllocation <= g_MemoryConfig.globalPoolSize);
}

void MemoryConfig_Shutdown()
{
g_MemoryConfig = {};
g_TotalLockedBytes.store(0, std::memory_order_relaxed);
}
}
46 changes: 41 additions & 5 deletions Engine/src/delta/core/MemoryConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,55 @@

namespace delta::core
{
// TODO: This is actually crap. In this file, there should be a tight, flat memory map for each thread
// possibly modificable via config macros or maybe slightly dynamic.
// FUTURE TODO: Make it configurable via compile definitions
namespace MemoryMap
{
inline constexpr size_t VIRT_ZONE_SPACE_LENGTH = (1ull << 35);

// COMPONENTS:
// QUEUE
inline constexpr size_t VIRT_ZONE_QUEUE_OFFSET = 0ull;
inline constexpr size_t VIRT_ZONE_QUEUE_SIZE = (1ull << 16); // 64KB
inline constexpr size_t VIRT_ZONE_QUEUE_BASELINE = UINT64_MAX; // No baseline, we commit it all

// TRANSIENT ARENA
inline constexpr size_t VIRT_ZONE_TA_OFFSET = VIRT_ZONE_QUEUE_OFFSET + VIRT_ZONE_QUEUE_SIZE;
inline constexpr size_t VIRT_ZONE_TA_SIZE = (1ull << 30); // 1GB
inline constexpr size_t VIRT_ZONE_TA_BASELINE = (1ull << 26); // 64MB

// COMPONENT POOL ARENA
inline constexpr size_t VIRT_ZONE_CPA_OFFSET = VIRT_ZONE_TA_OFFSET + VIRT_ZONE_TA_SIZE;
inline constexpr size_t VIRT_ZONE_CPA_SIZE = (1ull << 33); // 8GB
inline constexpr size_t VIRT_ZONE_CPA_BASELINE = (1ull << 27); // 128MB

// SCENE ARENA
inline constexpr size_t VIRT_ZONE_SA_OFFSET = VIRT_ZONE_CPA_OFFSET + VIRT_ZONE_CPA_SIZE;
inline constexpr size_t VIRT_ZONE_SA_SIZE = (1ull << 32); // 4GB
inline constexpr size_t VIRT_ZONE_SA_BASELINE = (1ull << 26); // 64MB

// IO STREAMING SPACE
inline constexpr size_t VIRT_ZONE_IO_OFFSET = VIRT_ZONE_SA_OFFSET + VIRT_ZONE_SA_SIZE;
inline constexpr size_t VIRT_ZONE_IO_SIZE = (1ull << 30); // 1GB (to be reconsidered)
inline constexpr size_t VIRT_ZONE_IO_BASELINE = UINT64_MAX; // No memory commited, thus no baseline

// BASELINE SUMMARY
inline constexpr size_t VIRT_ZONE_BASELINE_SUM =
VIRT_ZONE_TA_BASELINE +
VIRT_ZONE_CPA_BASELINE +
VIRT_ZONE_SA_BASELINE;
}

struct EngineMemoryConfig
{
size_t totalPhysicalRam;
size_t globalLockCeiling;
size_t maxAllowedPhysical;
size_t threadSoftBaseline;
size_t activeLockAllocation;
size_t globalPoolSize;
};

extern EngineMemoryConfig g_MemoryConfig;
extern std::atomic<size_t> g_TotalLockedBytes; // TODO: Remove, redesign. completely unnecessary

void MemoryConfig_Initialize(size_t physicalRamInstalled, uint32_t maxEngineWorkers);
void MemoryConfig_Initialize(size_t physicalRamInstalled, size_t pageSize, uint32_t maxEngineWorkers);
void MemoryConfig_Shutdown();
}
40 changes: 30 additions & 10 deletions Engine/src/delta/core/ThreadContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,27 @@ namespace delta::core
static ThreadExecutionContext* g_ThreadContexts = nullptr;
thread_local ThreadExecutionContext* tl_CurrentThreadContext = nullptr;

DLT_FORCE_INLINE static void InitializePageCoordinator(ThreadPageCoordinator& pageCoord, size_t pageSize, uint8_t* baseAddress)
{
pageCoord.pageSize = pageSize;
pageCoord.virtualAddressBase = baseAddress;
pageCoord.commitedOffset = 0;
pageCoord.reservedCapacity = MemoryMap::VIRT_ZONE_SPACE_LENGTH;
}

DLT_FORCE_INLINE static void InitializeArena(const ThreadPageCoordinator& pageCoord, ThreadArena& arena, size_t offset, size_t baseline)
{
uint8_t* pTarget = pageCoord.virtualAddressBase + offset;
void* res = delta::platform::Memory_Commit(pTarget, baseline);
assert(res != nullptr);

// TODO: Lock

arena.backingMemory = pTarget;
arena.capacity = baseline;
arena.offset = 0;
}

void ThreadContext_Initialize(uint32_t workerCount, size_t pageSize)
{
uint32_t totalThreads = workerCount + 1; // include main thread
Expand Down Expand Up @@ -41,14 +62,14 @@ namespace delta::core
ctx.threadIx = i;
ctx.threadId = 0; // to be set later

ctx.pageCoordinator.pageSize = pageSize;
ctx.pageCoordinator.virtualAddressBase = virtualRunwayCursor;
ctx.pageCoordinator.commitedOffset = 0;
ctx.pageCoordinator.reservedCapacity = ADDR_SLICE_PER_THREAD;

InitializePageCoordinator(ctx.pageCoordinator, pageSize, virtualRunwayCursor);
virtualRunwayCursor += ADDR_SLICE_PER_THREAD;

uint8_t* initialPageTarget = ctx.pageCoordinator.virtualAddressBase + ctx.pageCoordinator.commitedOffset;
InitializeArena(ctx.pageCoordinator, ctx.transientArena, MemoryMap::VIRT_ZONE_TA_OFFSET, MemoryMap::VIRT_ZONE_TA_BASELINE);
InitializeArena(ctx.pageCoordinator, ctx.componentPoolArena, MemoryMap::VIRT_ZONE_CPA_OFFSET, MemoryMap::VIRT_ZONE_CPA_BASELINE);
InitializeArena(ctx.pageCoordinator, ctx.sceneArena, MemoryMap::VIRT_ZONE_SA_OFFSET, MemoryMap::VIRT_ZONE_SA_BASELINE);

/*uint8_t* initialPageTarget = ctx.pageCoordinator.virtualAddressBase + ctx.pageCoordinator.commitedOffset;
void* initialPageMemory = delta::platform::Memory_Commit(initialPageTarget, pageSize);
assert(initialPageMemory != nullptr && "Failed to commit initial arena page!");

Expand All @@ -58,21 +79,20 @@ namespace delta::core
ctx.pageCoordinator.commitedOffset += pageSize;
ctx.transientArena.backingMemory = reinterpret_cast<uint8_t*>(initialPageTarget);
ctx.transientArena.capacity = pageSize;
ctx.transientArena.offset = 0;
ctx.transientArena.offset = 0;*/

delta::platform::Timer_Initialize(&ctx.perThreadTimer);
}

tl_CurrentThreadContext = &g_ThreadContexts[0];
g_TotalLockedBytes.fetch_add(totalThreads * pageSize + alignedContextArraySize, std::memory_order_relaxed);
}

void ThreadContext_Shutdown()
{
delta::platform::Memory_Release(g_ThreadContexts);
}

void* ThreadArena_Allocate(EngineArena* arena, size_t size, size_t alignment)
void* ThreadArena_Allocate(ThreadArena* arena, size_t size, size_t alignment)
{
uintptr_t currentAddress = reinterpret_cast<uintptr_t>(arena->backingMemory) + arena->offset;
uintptr_t alignedAddress = ALIGN(currentAddress, alignment);
Expand Down Expand Up @@ -101,7 +121,7 @@ namespace delta::core
return ptr;
}

void ThreadArena_Reset(EngineArena* arena)
void ThreadArena_Reset(ThreadArena* arena)
{
arena->offset = 0;
}
Expand Down
4 changes: 2 additions & 2 deletions Engine/src/delta/core/ThreadContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ namespace delta::core
void ThreadContext_Shutdown();

// Engine Arena API
void* ThreadArena_Allocate(EngineArena* arena, size_t size, size_t alignment = 8);
void ThreadArena_Reset(EngineArena* arena);
void* ThreadArena_Allocate(ThreadArena* arena, size_t size, size_t alignment = 8);
void ThreadArena_Reset(ThreadArena* arena);
}
8 changes: 1 addition & 7 deletions Engine/src/delta/core/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,7 @@ void delta::Engine::Initialize(Context& context)
const auto* osInfo = delta::platform::getOSInfo();
const auto memStatus = delta::platform::getMemoryStatus();

delta::core::MemoryConfig_Initialize(memStatus.physicalInstalled, osInfo->maxEngineWorkerCount);
if (!delta::platform::Memory_ElevateLockLimit(delta::core::g_MemoryConfig.globalLockCeiling))
{
context.isRunning = false;
return;
}

delta::core::MemoryConfig_Initialize(memStatus.physicalInstalled, osInfo->osPageSize, osInfo->maxEngineWorkerCount);
delta::core::ThreadContext_Initialize(osInfo->maxEngineWorkerCount, osInfo->osPageSize);
}

Expand Down