SectrPrototype/code/grime_windows.odin

113 lines
3.4 KiB
Odin

package sectr
import "core:c"
import "core:c/libc"
import "core:fmt"
import core_virtual "core:mem/virtual"
import "core:strings"
import win32 "core:sys/windows"
when ODIN_OS == OS_Type.Windows {
thread__highres_wait :: proc( desired_ms : f64, loc := #caller_location ) -> b32
{
// label_backing : [1 * Megabyte]u8
// label_arena : Arena
// arena_init( & label_arena, slice_ptr( & label_backing[0], len(label_backing)) )
// label_u8 := str_fmt_tmp( "SECTR: WAIT TIMER")//, allocator = arena_allocator( &label_arena) )
// label_u16 := win32.utf8_to_utf16( label_u8, context.temp_allocator) //arena_allocator( & label_arena) )
timer := win32.CreateWaitableTimerExW( nil, nil, win32.CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, win32.TIMER_ALL_ACCESS )
if timer == nil {
msg := str_fmt_tmp("Failed to create win32 timer - ErrorCode: %v", win32.GetLastError() )
log( msg, LogLevel.Warning, loc)
return false
}
due_time := win32.LARGE_INTEGER(desired_ms * MS_To_NS)
result := win32.SetWaitableTimerEx( timer, & due_time, 0, nil, nil, nil, 0 )
if ! result {
msg := str_fmt_tmp("Failed to set win32 timer - ErrorCode: %v", win32.GetLastError() )
log( msg, LogLevel.Warning, loc)
return false
}
WAIT_ABANDONED : win32.DWORD : 0x00000080
WAIT_IO_COMPLETION : win32.DWORD : 0x000000C0
WAIT_OBJECT_0 : win32.DWORD : 0x00000000
WAIT_TIMEOUT : win32.DWORD : 0x00000102
WAIT_FAILED : win32.DWORD : 0xFFFFFFFF
wait_result := win32.WaitForSingleObjectEx( timer, win32.INFINITE, win32.BOOL(true) )
switch wait_result
{
case WAIT_ABANDONED:
msg := str_fmt_tmp("Failed to wait for win32 timer - Error: WAIT_ABANDONED" )
log( msg, LogLevel.Error, loc)
return false
case WAIT_IO_COMPLETION:
msg := str_fmt_tmp("Waited for win32 timer: Ended by APC queued to the thread" )
log( msg, LogLevel.Error, loc)
return false
case WAIT_OBJECT_0:
msg := str_fmt_tmp("Waited for win32 timer- Reason : WAIT_OBJECT_0" )
log( msg, loc = loc)
return false
case WAIT_FAILED:
msg := str_fmt_tmp("Waited for win32 timer failed - ErrorCode: $v", win32.GetLastError() )
log( msg, LogLevel.Error, loc)
return false
}
return true
}
set__scheduler_granularity :: proc "contextless" ( desired_ms : u32 ) -> b32 {
return win32.timeBeginPeriod( desired_ms ) == win32.TIMERR_NOERROR
}
WIN32_ERROR_INVALID_ADDRESS :: 487
WIN32_ERROR_COMMITMENT_LIMIT :: 1455
@(require_results)
virtual__reserve ::
proc "contextless" ( base_address : uintptr, size : uint ) -> ( vmem : VirtualMemoryRegion, alloc_error : AllocatorError )
{
header_size :: cast(uint) size_of(VirtualMemoryRegion)
result := win32.VirtualAlloc( rawptr(base_address), header_size + size, win32.MEM_RESERVE, win32.PAGE_READWRITE )
if result == nil {
alloc_error = .Out_Of_Memory
return
}
result = win32.VirtualAlloc( rawptr(base_address), header_size, win32.MEM_COMMIT, win32.PAGE_READWRITE )
if result == nil
{
switch err := win32.GetLastError(); err
{
case 0:
alloc_error = .Invalid_Argument
return
case WIN32_ERROR_INVALID_ADDRESS, WIN32_ERROR_COMMITMENT_LIMIT:
alloc_error = .Out_Of_Memory
return
}
alloc_error = .Out_Of_Memory
return
}
vmem.base_address = cast(^VirtualMemoryRegionHeader) result
vmem.reserve_start = memory_after_header(vmem.base_address)
vmem.reserved = size
vmem.committed = header_size
alloc_error = .None
return
}
} // END: ODIN_OS == runtime.Odin_OS_Type.Windows