revolver

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

platform_core.c (5794B)


      1 //////////////////////////////////////////////////////////////////
      2 // platform_core.c
      3 
      4 //////////////////////////////////////////////////////////////////
      5 // Utils
      6 
      7 RV_GLOBAL void rv_abort_msg_(const char* file, const char* func, s32 line_no, s32 exit_code, const char* message, ...)
      8 {
      9 
     10     char buf[512] = {0};
     11     va_list args;
     12     va_start(args, message);
     13     vsnprintf(buf, sizeof(buf), message, args);
     14     va_end(args);
     15 
     16     fprintf(stderr, "rv_abort[%d]: '%s' at %s:%d (%s)\n", exit_code, buf, file, line_no, func);
     17 
     18 
     19 
     20 #if RV_OS_WINDOWS
     21     ExitProcess(exit_code);
     22 #else
     23     _exit(exit_code);
     24 #endif
     25 }
     26 
     27 RV_GLOBAL f64 rv_time(void) {
     28     f64 res = 0;
     29 
     30 #if RV_OS_WINDOWS
     31     s64 wintime;
     32     GetSystemTimeAsFileTime((FILETIME*)&wintime);
     33     wintime -= 116444736000000000i64;            // 1jan1601 to 1jan1970
     34     res  += wintime / 10000000i64;               // seconds
     35     res += (wintime % 10000000i64 * 100) * 1e-9; // nano-seconds
     36 #else
     37     struct timespec ts_now;
     38     clock_gettime(CLOCK_MONOTONIC, &ts_now);
     39 
     40     res  = ts_now.tv_sec;
     41     res += ts_now.tv_nsec * 1e-9;
     42 #endif
     43     return res;
     44 }
     45 
     46 //////////////////////////////////////////////////////////////////
     47 // Memory
     48 
     49 RV_GLOBAL void* rv_mem_reserve(s64 size)
     50 {
     51     void* result = NULL;
     52 #if RV_OS_WINDOWS
     53     result = VirtualAlloc(0, size, MEM_RESERVE, PAGE_READWRITE);
     54 #else
     55     result = mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, (off_t)0);
     56     if (result == MAP_FAILED) result = 0;
     57 #endif
     58     return result;
     59 }
     60 RV_GLOBAL void* rv_mem_reserve_large(s64 size)
     61 {
     62     void* result = NULL;
     63 #if RV_OS_WINDOWS
     64     // we commit on reserve because windows
     65     result = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_LARGE_PAGES, PAGE_READWRITE);
     66 #else
     67     result = mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB, -1, (off_t)0);
     68     if (result == MAP_FAILED) result = 0;
     69 #endif
     70     return result;
     71 }
     72 
     73 RV_GLOBAL void rv_mem_commit(void* ptr, s64 size)
     74 {
     75 #if RV_OS_WINDOWS
     76     VirtualAlloc(ptr, size, MEM_COMMIT, PAGE_READWRITE);
     77 #else
     78     mprotect(ptr, size, PROT_READ|PROT_WRITE);
     79 #endif
     80 }
     81 RV_GLOBAL void rv_mem_commit_large(void* ptr, s64 size)
     82 {
     83 #if RV_OS_WINDOWS
     84     // do nothing, already commited
     85 #else
     86     mprotect(ptr, size, PROT_READ|PROT_WRITE);
     87 #endif
     88 }
     89 
     90 RV_GLOBAL void rv_mem_decommit(void* ptr, s64 size)
     91 {
     92 #if RV_OS_WINDOWS
     93     VirtualFree(ptr, size, MEM_DECOMMIT);
     94 #else
     95     mprotect(ptr, size, PROT_NONE);
     96     madvise(ptr, size, MADV_DONTNEED);
     97 #endif
     98 }
     99 
    100 RV_GLOBAL void rv_mem_release(void* ptr, s64 size)
    101 {
    102 #if RV_OS_WINDOWS
    103     VirtualFree(ptr, 0, MEM_RELEASE);
    104 #else
    105     munmap(ptr, size);
    106 #endif
    107 }
    108 
    109 RV_GLOBAL s64 rv_mem_get_page_size(bool32 is_large)
    110 {
    111     s64 result = 0;
    112 
    113 #if RV_OS_WINDOWS
    114 
    115     if (is_large) {
    116         result = GetLargePageMinimum();
    117     } else {
    118         SYSTEM_INFO sysinfo = {0};
    119         GetSystemInfo(&sysinfo);
    120         result = sysinfo.dwPageSiz;
    121     }
    122 
    123 #else
    124 
    125     if (is_large) {
    126         // I hate this
    127 
    128         rv_str8 filename = S("/proc/meminfo");
    129 
    130         int readerr;
    131         long val;
    132 
    133         rv_temp_arena scratch = rv_scratch_begin(0, 0);
    134 
    135         char* buffer = rv_push_array(scratch.arena, char, KB(4));
    136         FILE* f = fopen("/proc/meminfo", "rb");
    137         if (f) {
    138             fread(buffer, KB(4) - 1, 1, f);
    139         }
    140         rv_str8 proc_meminfo = rv_str8_from_cstr(buffer);
    141 
    142         rv_str8 tag = S("Hugepagesize:");
    143         rv_str8 found = rv_str8_skip(proc_meminfo, rv_str8_find_needle(proc_meminfo, 0, tag, 0) + tag.len);
    144 
    145         // chop around number + byte size
    146         found = rv_str8_skip_chop_whitespace(found);
    147         found = rv_str8_prefix(found, rv_str8_find_needle(found, 0, S("\n"), 0));
    148 
    149         bool32 kb = rv_str8_find_needle(found, 0, S("kb"), rv_str8_match_flag_case_insensetive) < found.len;
    150         bool32 mb = rv_str8_find_needle(found, 0, S("mb"), rv_str8_match_flag_case_insensetive) < found.len;
    151         bool32 gb = rv_str8_find_needle(found, 0, S("gb"), rv_str8_match_flag_case_insensetive) < found.len;
    152 
    153         // remove byte part
    154         found = rv_str8_prefix(found, rv_str8_find_needle(found, 0, S(" "), 0));
    155 
    156         result = rv_s64_from_str8(found, 10);
    157         if (kb) result = KB(result);
    158         if (mb) result = MB(result);
    159         if (gb) result = GB(result);
    160 
    161         rv_scratch_end(scratch);
    162     } else {
    163         result = getpagesize();
    164     }
    165 #endif
    166     return result;
    167 }
    168 
    169 RV_GLOBAL void* rv_mem_set(void* mem, u8 set_byte, s64 size)
    170 {
    171     u8* bytes = mem;
    172     for (s64 i = 0; i < size; i++) {
    173         bytes[i] = set_byte;
    174     }
    175     return mem;
    176 }
    177 
    178 RV_GLOBAL void* rv_mem_zero(void* mem, s64 size)
    179 {
    180     return rv_mem_set(mem, 0, size);
    181 }
    182 
    183 RV_GLOBAL void* rv_mem_copy(void* restrict target, const void* restrict source, s64 size)
    184 {
    185     u8* t = target;
    186     const u8* s = source;
    187     for (s64 i = 0; i < size; i++) {
    188         t[i] = s[i];
    189     }
    190     return target;
    191 }
    192 
    193 RV_GLOBAL void* rv_mem_move(void* target, const void* source, s64 size)
    194 {
    195     rv_temp_arena scratch = rv_scratch_begin(0, 0);
    196 
    197     u8* temp = rv_push_array_no_zero(scratch.arena, u8, size);
    198 
    199     rv_mem_copy(temp, source, size);
    200     rv_mem_copy(target, temp, size);
    201 
    202     rv_scratch_end(scratch);
    203 
    204     return target;
    205 }
    206 
    207 RV_GLOBAL bool32 rv_mem_eq(const void* a, const void* b, s64 size)
    208 {
    209     const u8* a_char = a;
    210     const u8* b_char = b;
    211     for (s64 i = 0; i < size; i++) {
    212         if (a_char[i] != b_char[i])
    213             return false;
    214     }
    215     return true;
    216 }
    217 
    218 #if !defined(RV_NO_GLOBAL_ALLOC)
    219 RV_GLOBAL void* rv_mem_global_alloc_nz_(s64 size, s64 align)                        { return malloc(size); }
    220 RV_GLOBAL void* rv_mem_global_realloc_nz_(void* old_ptr, s64 new_size, s64 align)   { return realloc(old_ptr, new_size);}
    221 RV_GLOBAL void  rv_mem_global_alloc_free(void* ptr, s64 size)                       { free(ptr);           }
    222 #endif