rexglue-skate3/include/rex/kernel/crt/heap.h
2026-05-18 22:41:13 +01:00

77 lines
2.1 KiB
C++

/**
* @file kernel/crt/heap.h
* @brief ReXHeap -- O(1) native heap for guest memory using o1heap.
* Provides rexcrt hooks for RtlAllocateHeap, RtlFreeHeap, etc.
*
* @copyright Copyright (c) 2026 Tom Clay <tomc@tctechstuff.com>
* @license BSD 3-Clause License
*/
#pragma once
#include <cstdint>
#include <mutex>
#include <vector>
#include <rex/cvar.h>
REXCVAR_DECLARE(bool, rexcrt_heap_enable);
REXCVAR_DECLARE(uint32_t, rexcrt_heap_size_mb);
struct O1HeapInstance;
namespace rex::memory {
class Memory;
}
namespace rex::kernel::crt {
/// Mirrors O1HeapDiagnostics without requiring o1heap.h in consumer headers.
struct HeapDiagnostics {
uint64_t capacity;
uint64_t allocated;
uint64_t peak_allocated;
uint64_t peak_request_size;
uint64_t oom_count;
};
class ReXHeap {
public:
bool Init(uint32_t heap_size_bytes, rex::memory::Memory* memory);
uint32_t Alloc(uint32_t size, bool zero = false);
void Free(uint32_t guest_addr);
uint32_t Size(uint32_t guest_addr);
uint32_t Realloc(uint32_t guest_addr, uint32_t new_size, bool zero_new = false);
bool InHeap(uint32_t guest_addr) const;
HeapDiagnostics GetDiagnostics() const;
private:
struct HeapSegment {
O1HeapInstance* heap = nullptr;
uint32_t guest_base = 0;
uint32_t guest_end = 0;
};
mutable std::mutex mutex_;
std::vector<HeapSegment> segments_;
uint8_t* membase_ = nullptr;
uint32_t initial_segment_size_ = 0;
rex::memory::Memory* memory_ = nullptr;
void* GuestToHost(uint32_t guest_addr) const;
uint32_t HostToGuest(void* host_ptr) const;
bool AllocateSegmentLocked(uint32_t segment_size_bytes);
uint32_t AllocLocked(uint32_t size, bool zero = false);
HeapSegment* FindSegmentByGuestLocked(uint32_t guest_addr);
const HeapSegment* FindSegmentByGuestLocked(uint32_t guest_addr) const;
HeapDiagnostics GetDiagnosticsLocked() const;
};
/// Initialize the global rexcrt heap. Called by Runtime::Setup() when enabled.
bool InitHeap(uint32_t heap_size_mb, rex::memory::Memory* memory);
/// Access the global heap instance (valid after InitHeap).
ReXHeap& GetHeap();
} // namespace rex::kernel::crt