106 lines
2.5 KiB
C++
106 lines
2.5 KiB
C++
#include "System.h"
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdint.h>
|
|
#include <fcntl.h>
|
|
#ifdef PLATFORM_WINDOWS
|
|
#include "windows.h"
|
|
#else
|
|
#include <sys/mman.h>
|
|
#endif
|
|
|
|
unsigned long System::page_size;
|
|
unsigned int System::page_size_log;
|
|
unsigned long System::page_base_mask;
|
|
unsigned long System::page_offset_mask;
|
|
static std::string Executable_Path;
|
|
|
|
bool System::init(char * argv[])
|
|
{
|
|
#if defined(PLATFORM_LINUX)
|
|
long system_page_size = sysconf(_SC_PAGESIZE);
|
|
if (system_page_size < 0)
|
|
{
|
|
fprintf(stderr, "Unable to determine operating system page size.\n");
|
|
return false;
|
|
}
|
|
#elif defined(PLATFORM_WINDOWS)
|
|
SYSTEM_INFO system_info = {0};
|
|
GetSystemInfo(&system_info);
|
|
unsigned long system_page_size = system_info.dwPageSize;
|
|
#endif
|
|
|
|
System::page_size = (unsigned long)system_page_size;
|
|
System::page_size_log = 0u;
|
|
System::page_offset_mask = System::page_size - 1u;
|
|
System::page_base_mask = ~System::page_offset_mask;
|
|
|
|
for (uint_fast8_t i = 0u; i < 32u; i++)
|
|
{
|
|
unsigned long v = 1u << i;
|
|
if (v == System::page_size)
|
|
{
|
|
System::page_size_log = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((System::page_size < 256u) ||
|
|
(System::page_size > (4u * 1024u * 1024u)) ||
|
|
(System::page_size_log == 0u))
|
|
{
|
|
fprintf(stderr, "Unsupported page size detected: 0x%lx\n", System::page_size);
|
|
return false;
|
|
}
|
|
|
|
#if defined(PLATFORM_LINUX)
|
|
char link_buffer[1000];
|
|
ssize_t len = readlink("/proc/self/exe", link_buffer, sizeof(link_buffer));
|
|
if ((len > 0) && (len < (ssize_t)sizeof(link_buffer)))
|
|
{
|
|
Executable_Path = std::string(link_buffer, len);
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
#elif defined(PLATFORM_WINDOWS)
|
|
Executable_Path = argv[0];
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
void * System::alloc_pages(int num)
|
|
{
|
|
#ifdef PLATFORM_WINDOWS
|
|
return VirtualAlloc(
|
|
NULL,
|
|
num << System::page_size_log,
|
|
MEM_COMMIT | MEM_RESERVE,
|
|
PAGE_READWRITE);
|
|
#else
|
|
return mmap(
|
|
NULL,
|
|
num << System::page_size_log,
|
|
PROT_READ | PROT_WRITE,
|
|
MAP_PRIVATE | MAP_ANONYMOUS,
|
|
-1,
|
|
0);
|
|
#endif
|
|
}
|
|
|
|
void System::free_pages(void * addr, int num)
|
|
{
|
|
#ifdef PLATFORM_WINDOWS
|
|
(void)VirtualFree(addr, 0, MEM_RELEASE);
|
|
#else
|
|
(void)munmap(addr, num << System::page_size_log);
|
|
#endif
|
|
}
|
|
|
|
std::string System::executable_path()
|
|
{
|
|
return Executable_Path;
|
|
}
|