#if OS_WINDOWS // This file is included in Arena.cpp, so we don't need to include headers here. void platform_init (Arena* arena, s64 new_reserve) { s64 page_aligned_reserve_size = Align_To_Page_Size(new_reserve); void* address_start = VirtualAlloc(nullptr, (u64)page_aligned_reserve_size, MEM_RESERVE, PAGE_READWRITE); if (address_start == nullptr) { // get error value and string? s32 error_code = GetLastError(); return; // #TODO(LOG) log_error("In Arena:platform_init, VirtualAlloc failed with code %d\n", error_code) } arena->memory_base = (u8*)address_start; } void extend_committed_pages (Arena* arena, u8* end) { s64 delta = end - arena->first_uncommitted_page; Assert(delta >= 0); s64 size = Align_To_Page_Size(delta); VirtualAlloc(arena->first_uncommitted_page, (u64)size, MEM_COMMIT, PAGE_READWRITE); // arena_lock_pages(arena, arena->first_uncommitted_page, size); arena->first_uncommitted_page += size; } void free_pages_down_to (Arena* arena, s64 pages_to_keep) { if (arena == nullptr) return; Assert(pages_to_keep >= 0); s64 bytes_to_keep = pages_to_keep * PLATFORM_MEMORY_PAGE_SIZE; if (bytes_to_keep >= reserve_size(arena)) { Assert(false); // Break in debug builds, but release we just do nothing. return; // just do nothing here. Maybe we should assert? } u64 bytes_committed = (u64)(arena->first_uncommitted_page - arena->memory_base); if (bytes_to_keep > (s64)bytes_committed) { return; // nothing to free } u8* start_address = arena->memory_base + bytes_to_keep; u64 bytes_to_decommit = (u64)(arena->first_uncommitted_page - start_address); // arena_unlock_pages(arena, start_address, (s64)bytes_to_decommit); VirtualFree(start_address, bytes_to_decommit, MEM_DECOMMIT); arena->first_uncommitted_page = start_address; } void arena_delete (Arena* arena) { if (!is_valid(arena)) return; bool arena_was_boostrapped = (arena->flags & Arena_Flags::Is_Bootstrapped) == Arena_Flags::Is_Bootstrapped; VirtualFree(arena->memory_base, 0, MEM_RELEASE); if (!arena_was_boostrapped) { arena->memory_base = nullptr; } } #endif