#include "System.h" #include #include #include #include #ifdef PLATFORM_WINDOWS #include "windows.h" #else #include #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; }