Last active
July 9, 2020 17:51
-
-
Save lerno/acb9c9fd821c6287890aa72e5c9a9418 to your computer and use it in GitHub Desktop.
Mem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright (c) 2020 Christoffer Lerno. All rights reserved. | |
// Use of this source code is governed by a LGPLv3.0 | |
// a copy of which can be found in the LICENSE file. | |
#include "vmem.h" | |
#include "common.h" | |
#if defined( _WIN32 ) || defined( __WIN32__ ) || defined( _WIN64 ) | |
#define PLATFORM_WINDOWS 1 | |
#define PLATFORM_POSIX 0 | |
#else | |
#define PLATFORM_WINDOWS 0 | |
#define PLATFORM_POSIX 1 | |
#endif | |
#if PLATFORM_POSIX | |
#include <sys/mman.h> | |
#endif | |
#if PLATFORM_WINDOWS | |
#include <Windows.h> | |
#define COMMIT_PAGE_SIZE 0x10000 | |
#endif | |
typedef struct | |
{ | |
void *ptr; | |
size_t allocated; | |
#if PLATFORM_WINDOWS | |
size_t committed; | |
#endif | |
} Vmem; | |
static void* mmap_os(Vmem *vmem, size_t size) | |
{ | |
#if PLATFORM_WINDOWS | |
void* ptr = VirtualAlloc(0, size, MEM_RESERVE, PAGE_NOACCESS); | |
vmem->committed = 0; | |
if (!ptr) | |
{ | |
FATAL_ERROR("Failed to map virtual memory block"); | |
} | |
#elif PLATFORM_POSIX | |
void* ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, -1, 0); | |
if ((ptr == MAP_FAILED) || !ptr) | |
{ | |
FATAL_ERROR("Failed to map virtual memory block"); | |
} | |
#else | |
FATAL_ERROR("Unsupported platform."); | |
#endif | |
vmem->ptr = vmem; | |
vmem->allocated = 0; | |
return ptr; | |
} | |
static void* mmap_allocate(Vmem *vmem, size_t to_allocate) | |
{ | |
size_t allocated_after = to_allocate + vmem->allocated; | |
#if PLATFORM_WINDOWS | |
size_t blocks_committed = vmem->committed / COMMIT_PAGE_SIZE; | |
size_t end_block = (allocated_after) / COMMIT_PAGE_SIZE; | |
size_t blocks_to_allocate = end_block - blocks_committed; | |
if (blocks_to_allocate > 0) | |
{ | |
size_t to_commit = blocks_to_allocate * COMMIT_PAGE_SIZE; | |
void *res = VirtualAlloc(vmem->ptr + vmem->committed, to_commit, MEM_COMMIT, PAGE_READWRITE); | |
if (!res) FATAL_ERROR("Failed to allocate more memory."); | |
vmem->committed += to_commit; | |
} | |
#endif | |
void *ptr = vmem->ptr + vmem->allocated; | |
vmem->allocated = allocated_after; | |
return ptr; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment