Beginning to lift the "grime" files to their own pacakge
This commit is contained in:
parent
65386372fc
commit
3998776f4b
@ -7,7 +7,7 @@ Update 5-26-2024:
|
||||
TODO(Ed): Raw_Dynamic_Array is defined within base:runtime/core.odin and exposes what we need for worst case hot-reloads.
|
||||
So its best to go back to regular dynamic arrays at some point.
|
||||
*/
|
||||
package sectr
|
||||
package grime
|
||||
|
||||
import "core:c/libc"
|
||||
import "core:mem"
|
||||
@ -295,6 +295,7 @@ array_set_capacity :: proc( self : ^Array( $ Type ), new_capacity : u64 ) -> All
|
||||
|
||||
if result_code != AllocatorError.None {
|
||||
ensure( false, "Failed to allocate for new array capacity" )
|
||||
log( "Failed to allocate for new array capacity", level = LogLevel.Warning )
|
||||
return result_code
|
||||
}
|
||||
if new_mem == nil {
|
@ -1,4 +1,4 @@
|
||||
package sectr
|
||||
package grime
|
||||
|
||||
import "base:runtime"
|
||||
import "core:io"
|
||||
@ -18,8 +18,6 @@ dump_stacktrace :: proc( allocator := context.temp_allocator ) -> string
|
||||
}
|
||||
table.build(log_table)
|
||||
|
||||
// writer_builder_backing : [Kilobyte * 16] u8
|
||||
// writer_builder := from_bytes( writer_builder_backing[:] )
|
||||
writer_builder : StringBuilder
|
||||
str_builder_init( & writer_builder, allocator = allocator )
|
||||
|
||||
@ -34,7 +32,7 @@ dump_stacktrace :: proc( allocator := context.temp_allocator ) -> string
|
||||
return to_string( writer_builder )
|
||||
}
|
||||
|
||||
ensure :: proc( condition : b32, msg : string, location := #caller_location )
|
||||
ensure :: #force_inline proc( condition : b32, msg : string, location := #caller_location )
|
||||
{
|
||||
if condition {
|
||||
return
|
||||
@ -44,14 +42,15 @@ ensure :: proc( condition : b32, msg : string, location := #caller_location )
|
||||
}
|
||||
|
||||
// TODO(Ed) : Setup exit codes!
|
||||
fatal :: proc( msg : string, exit_code : int = -1, location := #caller_location )
|
||||
fatal :: #force_inline proc( msg : string, exit_code : int = -1, location := #caller_location )
|
||||
{
|
||||
log( msg, LogLevel.Fatal, location )
|
||||
runtime.debug_trap()
|
||||
os.exit( exit_code )
|
||||
}
|
||||
|
||||
verify :: proc( condition : b32, msg : string, exit_code : int = -1, location := #caller_location )
|
||||
// TODO(Ed) : Setup exit codes!
|
||||
verify :: #force_inline proc( condition : b32, msg : string, exit_code : int = -1, location := #caller_location )
|
||||
{
|
||||
if condition {
|
||||
return
|
@ -1,4 +1,4 @@
|
||||
package sectr
|
||||
package grime
|
||||
|
||||
Nanosecond_To_Microsecond :: 1.0 / (1000.0)
|
||||
Nanosecond_To_Millisecond :: 1.0 / (1000.0 * 1000.0)
|
||||
@ -31,5 +31,3 @@ MS_To_S :: Millisecond_To_Second
|
||||
S_To_NS :: Second_To_Nanosecond
|
||||
S_To_US :: Second_To_Microsecnd
|
||||
S_To_MS :: Second_To_Millisecond
|
||||
|
||||
Frametime_High_Perf_Threshold_MS :: 1 / 240.0
|
@ -1,12 +1,11 @@
|
||||
package sectr
|
||||
|
||||
// TODO(Ed): Review these when os2 is done.
|
||||
package grime
|
||||
// TODO(Ed): Review when os2 is done.
|
||||
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
import "base:runtime"
|
||||
|
||||
file_copy_sync :: proc( path_src, path_dst: string, allocator := context.temp_allocator ) -> b32
|
||||
file_copy_sync :: proc( path_src, path_dst: string, allocator := context.allocator ) -> b32
|
||||
{
|
||||
file_size : i64
|
||||
{
|
||||
@ -34,8 +33,8 @@ file_copy_sync :: proc( path_src, path_dst: string, allocator := context.temp_al
|
||||
return true
|
||||
}
|
||||
|
||||
file_exists :: proc( file_path : string ) -> b32 {
|
||||
path_info, result := file_status( file_path, frame_allocator() )
|
||||
file_exists :: proc( file_path : string, allocator := context.allocator ) -> b32 {
|
||||
path_info, result := file_status( file_path, allocator )
|
||||
if result != os.ERROR_NONE {
|
||||
return false
|
||||
}
|
@ -1,4 +1,9 @@
|
||||
package sectr
|
||||
/*
|
||||
An intersive singly & double linked list implementation
|
||||
|
||||
|
||||
*/
|
||||
package grime
|
||||
|
||||
LL_Node :: struct ( $ Type : typeid ) {
|
||||
next : ^Type,
|
||||
@ -17,7 +22,7 @@ ll_pop :: #force_inline proc "contextless" ( list_ptr : ^(^ ($ Type)) ) -> ( nod
|
||||
return list
|
||||
}
|
||||
|
||||
//region Intrusive Doubly-Linked-List
|
||||
//#region("Intrusive Doubly-Linked-List")
|
||||
|
||||
DLL_Node :: struct ( $ Type : typeid ) #raw_union {
|
||||
using _ : struct {
|
||||
@ -35,11 +40,12 @@ DLL_Node :: struct ( $ Type : typeid ) #raw_union {
|
||||
}
|
||||
|
||||
DLL_NodeFull :: struct ( $ Type : typeid ) {
|
||||
// using _ : DLL_NodeFL(Type),
|
||||
first, last : ^Type,
|
||||
prev, next : ^Type,
|
||||
}
|
||||
|
||||
// I have specific members commented out here as the RAD Debugger currently doesn't support transparently exposing using members of a struct (yet).
|
||||
|
||||
DLL_NodePN :: struct ( $ Type : typeid ) {
|
||||
// using _ : struct {
|
||||
prev, next : ^Type,
|
||||
@ -187,4 +193,4 @@ dll_full_push_back :: proc "contextless" ( parent : ^$ParentType, node : ^$Type,
|
||||
dll_full_insert_raw( null, parent, parent.last, node )
|
||||
}
|
||||
|
||||
//endregion Intrusive Doubly-Linked-List
|
||||
//#endregion("Intrusive Doubly-Linked-List")
|
@ -1,4 +1,4 @@
|
||||
package sectr
|
||||
package grime
|
||||
|
||||
import "base:runtime"
|
||||
import "core:fmt"
|
||||
@ -27,12 +27,7 @@ logger_init :: proc( logger : ^ Logger, id : string, file_path : string, file :
|
||||
if file == os.INVALID_HANDLE
|
||||
{
|
||||
logger_file, result_code := file_open( file_path, os.O_RDWR | os.O_CREATE )
|
||||
if result_code != os.ERROR_NONE {
|
||||
// Log failures are fatal and must never occur at runtime (there is no logging)
|
||||
runtime.debug_trap()
|
||||
os.exit( -1 )
|
||||
// TODO(Ed) : Figure out the error code enums..
|
||||
}
|
||||
assert( result_code == os.ERROR_NONE, "Log failures are fatal and must never occur at runtime (there is no logging)" )
|
||||
logger.file = logger_file
|
||||
}
|
||||
else {
|
||||
@ -45,7 +40,6 @@ logger_init :: proc( logger : ^ Logger, id : string, file_path : string, file :
|
||||
log("Initialized Logger")
|
||||
when false {
|
||||
log("This sentence is over 80 characters long on purpose to test the ability of this logger to properfly wrap long as logs with a new line and then at the end of that pad it with the appropraite signature.")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,7 +112,6 @@ logger_interface :: proc(
|
||||
str_to_file_ln( logger.file, to_string(builder) )
|
||||
}
|
||||
|
||||
|
||||
// This buffer is used below excluisvely to prevent any allocator recusion when verbose logging from allocators.
|
||||
Logger_Allocator_Buffer : [32 * Kilobyte]u8
|
||||
|
150
code/grime/mappings.odin
Normal file
150
code/grime/mappings.odin
Normal file
@ -0,0 +1,150 @@
|
||||
package grime
|
||||
|
||||
//#region("base")
|
||||
|
||||
import "base:builtin"
|
||||
copy :: builtin.copy
|
||||
|
||||
import "base:intrinsics"
|
||||
mem_zero :: intrinsics.mem_zero
|
||||
ptr_sub :: intrinsics.ptr_sub
|
||||
type_has_field :: intrinsics.type_has_field
|
||||
type_elem_type :: intrinsics.type_elem_type
|
||||
|
||||
import "base:runtime"
|
||||
Byte :: runtime.Byte
|
||||
Kilobyte :: runtime.Kilobyte
|
||||
Megabyte :: runtime.Megabyte
|
||||
Gigabyte :: runtime.Gigabyte
|
||||
Terabyte :: runtime.Terabyte
|
||||
Petabyte :: runtime.Petabyte
|
||||
Exabyte :: runtime.Exabyte
|
||||
resize_non_zeroed :: runtime.non_zero_mem_resize
|
||||
SourceCodeLocation :: runtime.Source_Code_Location
|
||||
|
||||
//#endregion("base")
|
||||
|
||||
//#region("core")
|
||||
|
||||
import c "core:c/libc"
|
||||
mem_fmt :: c.memset
|
||||
|
||||
import "core:dynlib"
|
||||
|
||||
import "core:hash"
|
||||
crc32 :: hash.crc32
|
||||
|
||||
import "core:hash/xxhash"
|
||||
xxh32 :: xxhash.XXH32
|
||||
|
||||
import fmt_io "core:fmt"
|
||||
str_fmt_out :: fmt_io.printf
|
||||
str_fmt_tmp :: fmt_io.tprintf
|
||||
str_fmt :: fmt_io.aprintf // Decided to make aprintf the default. (It will always be the default allocator)
|
||||
str_fmt_builder :: fmt_io.sbprintf
|
||||
str_fmt_buffer :: fmt_io.bprintf
|
||||
str_to_file_ln :: fmt_io.fprintln
|
||||
str_tmp_from_any :: fmt_io.tprint
|
||||
|
||||
import "core:math"
|
||||
|
||||
import "core:mem"
|
||||
align_forward_int :: mem.align_forward_int
|
||||
align_forward_uint :: mem.align_forward_uint
|
||||
align_forward_uintptr :: mem.align_forward_uintptr
|
||||
Allocator :: mem.Allocator
|
||||
AllocatorError :: mem.Allocator_Error
|
||||
AllocatorMode :: mem.Allocator_Mode
|
||||
AllocatorModeSet :: mem.Allocator_Mode_Set
|
||||
alloc :: mem.alloc
|
||||
alloc_bytes :: mem.alloc_bytes
|
||||
alloc_bytes_non_zeroed :: mem.alloc_bytes_non_zeroed
|
||||
Arena :: mem.Arena
|
||||
arena_allocator :: mem.arena_allocator
|
||||
arena_init :: mem.arena_init
|
||||
byte_slice :: mem.byte_slice
|
||||
copy_non_overlapping :: mem.copy_non_overlapping
|
||||
free :: mem.free
|
||||
is_power_of_two_uintptr :: mem.is_power_of_two
|
||||
ptr_offset :: mem.ptr_offset
|
||||
resize :: mem.resize
|
||||
slice_ptr :: mem.slice_ptr
|
||||
TrackingAllocator :: mem.Tracking_Allocator
|
||||
tracking_allocator :: mem.tracking_allocator
|
||||
tracking_allocator_init :: mem.tracking_allocator_init
|
||||
|
||||
import "core:mem/virtual"
|
||||
VirtualProtectFlags :: virtual.Protect_Flags
|
||||
|
||||
// TODO(Ed): Use os2 when the package is considered complete.
|
||||
import "core:os"
|
||||
FileFlag_Create :: os.O_CREATE
|
||||
FileFlag_ReadWrite :: os.O_RDWR
|
||||
FileTime :: os.File_Time
|
||||
file_close :: os.close
|
||||
file_open :: os.open
|
||||
file_read :: os.read
|
||||
file_remove :: os.remove
|
||||
file_seek :: os.seek
|
||||
file_status :: os.stat
|
||||
file_write :: os.write
|
||||
|
||||
import "core:path/filepath"
|
||||
file_name_from_path :: filepath.short_stem
|
||||
|
||||
import "core:strconv"
|
||||
parse_f32 :: strconv.parse_f32
|
||||
parse_u64 :: strconv.parse_u64
|
||||
parse_uint :: strconv.parse_uint
|
||||
|
||||
import str "core:strings"
|
||||
StringBuilder :: str.Builder
|
||||
str_builder_from_bytes :: str.builder_from_bytes
|
||||
str_builder_init :: str.builder_init
|
||||
str_builder_to_writer :: str.to_writer
|
||||
str_builder_to_string :: str.to_string
|
||||
|
||||
import "core:time"
|
||||
Duration :: time.Duration
|
||||
duration_seconds :: time.duration_seconds
|
||||
duration_ms :: time.duration_milliseconds
|
||||
thread_sleep :: time.sleep
|
||||
|
||||
import "core:unicode"
|
||||
is_white_space :: unicode.is_white_space
|
||||
|
||||
import "core:unicode/utf8"
|
||||
str_rune_count :: utf8.rune_count_in_string
|
||||
runes_to_string :: utf8.runes_to_string
|
||||
// string_to_runes :: utf8.string_to_runes
|
||||
|
||||
//#endregion("core")
|
||||
|
||||
import "thirdparty:backtrace"
|
||||
StackTraceData :: backtrace.Trace_Const
|
||||
stacktrace :: backtrace.trace
|
||||
stacktrace_lines :: backtrace.lines
|
||||
|
||||
//#region("Proc overload mappings")
|
||||
|
||||
array_append :: proc {
|
||||
array_append_value,
|
||||
array_append_array,
|
||||
array_append_slice,
|
||||
}
|
||||
|
||||
is_power_of_two :: proc {
|
||||
is_power_of_two_u32,
|
||||
is_power_of_two_uintptr,
|
||||
}
|
||||
|
||||
to_string :: proc {
|
||||
runes_to_string,
|
||||
str_builder_to_string,
|
||||
}
|
||||
|
||||
to_writer :: proc {
|
||||
str_builder_to_writer,
|
||||
}
|
||||
|
||||
//#endregion("Proc overload mappings")
|
6
code/grime/math.odin
Normal file
6
code/grime/math.odin
Normal file
@ -0,0 +1,6 @@
|
||||
package grime
|
||||
|
||||
is_power_of_two_u32 :: #force_inline proc "contextless" ( value : u32 ) -> b32
|
||||
{
|
||||
return value != 0 && ( value & ( value - 1 )) == 0
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
// TODO(Ed) : Move this to a grime package problably
|
||||
package sectr
|
||||
package grime
|
||||
|
||||
import "core:fmt"
|
||||
import "core:mem"
|
||||
@ -89,3 +88,5 @@ memory_aign_forward :: #force_inline proc( address, alignment : uintptr) -> uint
|
||||
}
|
||||
|
||||
//endregion Memory Math
|
||||
|
||||
swap :: #force_inline proc( a, b : ^ $Type ) -> ( ^ Type, ^ Type ) { return b, a }
|
@ -6,7 +6,7 @@
|
||||
|
||||
I'm keeping it around as an artifact & for future allocators I may make.
|
||||
*/
|
||||
package sectr
|
||||
package grime
|
||||
|
||||
MemoryTrackerEntry :: struct {
|
||||
start, end : rawptr,
|
||||
@ -19,14 +19,10 @@ MemoryTracker :: struct {
|
||||
|
||||
Track_Memory :: false
|
||||
|
||||
// tracker_msg_buffer : [Kilobyte * 16]u8
|
||||
|
||||
memtracker_clear :: proc ( tracker : MemoryTracker ) {
|
||||
when ! Track_Memory {
|
||||
return
|
||||
}
|
||||
// temp_arena : Arena; arena_init(& temp_arena, tracker_msg_buffer[:])
|
||||
// context.temp_allocator = arena_allocator(& temp_arena)
|
||||
|
||||
logf("Clearing tracker: %v", tracker.name)
|
||||
memtracker_dump_entries(tracker);
|
||||
@ -38,8 +34,6 @@ memtracker_init :: proc ( tracker : ^MemoryTracker, allocator : Allocator, num_e
|
||||
when ! Track_Memory {
|
||||
return
|
||||
}
|
||||
// temp_arena : Arena; arena_init(& temp_arena, tracker_msg_buffer[:])
|
||||
// context.temp_allocator = arena_allocator(& temp_arena)
|
||||
|
||||
tracker.name = name
|
||||
|
||||
@ -56,8 +50,6 @@ memtracker_register :: proc( tracker : ^MemoryTracker, new_entry : MemoryTracker
|
||||
return
|
||||
}
|
||||
profile(#procedure)
|
||||
// temp_arena : Arena; arena_init(& temp_arena, tracker_msg_buffer[:])
|
||||
// context.temp_allocator = arena_allocator(& temp_arena)
|
||||
|
||||
if tracker.entries.num == tracker.entries.capacity {
|
||||
ensure(false, "Memory tracker entries array full, can no longer register any more allocations")
|
||||
@ -110,8 +102,6 @@ memtracker_unregister :: proc( tracker : MemoryTracker, to_remove : MemoryTracke
|
||||
return
|
||||
}
|
||||
profile(#procedure)
|
||||
// temp_arena : Arena; arena_init(& temp_arena, tracker_msg_buffer[:])
|
||||
// context.temp_allocator = arena_allocator(& temp_arena)
|
||||
|
||||
entries := array_to_slice(tracker.entries)
|
||||
for idx in 0..< tracker.entries.num
|
||||
@ -139,8 +129,6 @@ memtracker_check_for_collisions :: proc ( tracker : MemoryTracker )
|
||||
return
|
||||
}
|
||||
profile(#procedure)
|
||||
// temp_arena : Arena; arena_init(& temp_arena, tracker_msg_buffer[:])
|
||||
// context.temp_allocator = arena_allocator(& temp_arena)
|
||||
|
||||
entries := array_to_slice(tracker.entries)
|
||||
for idx in 1 ..< tracker.entries.num {
|
||||
@ -161,8 +149,6 @@ memtracker_dump_entries :: proc( tracker : MemoryTracker )
|
||||
when ! Track_Memory {
|
||||
return
|
||||
}
|
||||
// temp_arena : Arena; arena_init(& temp_arena, tracker_msg_buffer[:])
|
||||
// context.temp_allocator = arena_allocator(& temp_arena)
|
||||
|
||||
log( "Dumping Memory Tracker:")
|
||||
for idx in 0 ..< tracker.entries.num {
|
3
code/grime/os.odin
Normal file
3
code/grime/os.odin
Normal file
@ -0,0 +1,3 @@
|
||||
package grime
|
||||
|
||||
OS_Type :: type_of(ODIN_OS)
|
29
code/grime/profiler.odin
Normal file
29
code/grime/profiler.odin
Normal file
@ -0,0 +1,29 @@
|
||||
package grime
|
||||
|
||||
import "base:runtime"
|
||||
import "core:prof/spall"
|
||||
|
||||
SpallProfiler :: struct {
|
||||
ctx : spall.Context,
|
||||
buffer : spall.Buffer,
|
||||
}
|
||||
|
||||
@(private)
|
||||
Module_Context : ^SpallProfiler
|
||||
|
||||
set_profiler_module_context :: #force_inline proc "contextless" ( ctx : ^SpallProfiler ) {
|
||||
Module_Context = ctx
|
||||
}
|
||||
|
||||
@(deferred_none = profile_end)
|
||||
profile :: #force_inline proc "contextless" ( name : string, loc := #caller_location ) {
|
||||
spall._buffer_begin( & Module_Context.ctx, & Module_Context.buffer, name, "", loc )
|
||||
}
|
||||
|
||||
profile_begin :: #force_inline proc "contextless" ( name : string, loc := #caller_location ) {
|
||||
spall._buffer_begin( & Module_Context.ctx, & Module_Context.buffer, name, "", loc )
|
||||
}
|
||||
|
||||
profile_end :: #force_inline proc "contextless" () {
|
||||
spall._buffer_end( & Module_Context.ctx, & Module_Context.buffer)
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package sectr
|
||||
package grime
|
||||
|
||||
// Provides an alternative syntax for pointers
|
||||
|
@ -1,6 +1,6 @@
|
||||
// This provides a string generator using a token replacement approach instead of a %<id> verb-syntax to parse.
|
||||
// This was done just for preference as I personally don't like the c-printf-like syntax.
|
||||
package sectr
|
||||
package grime
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package sectr
|
||||
package grime
|
||||
|
||||
import "core:c"
|
||||
import "core:c/libc"
|
||||
@ -8,8 +8,6 @@ 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
|
||||
@ -72,41 +70,3 @@ set__scheduler_granularity :: proc "contextless" ( desired_ms : u32 ) -> b32 {
|
||||
|
||||
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) memory_align_formula(size_of(VirtualMemoryRegionHeader), mem.DEFAULT_ALIGNMENT)
|
||||
|
||||
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 = cast([^]byte) (uintptr(vmem.base_address) + uintptr(header_size))
|
||||
vmem.reserved = size
|
||||
vmem.committed = header_size
|
||||
alloc_error = .None
|
||||
return
|
||||
}
|
||||
|
||||
} // END: ODIN_OS == runtime.Odin_OS_Type.Windows
|
@ -1,10 +1,7 @@
|
||||
package sectr
|
||||
package grime
|
||||
|
||||
rune16 :: distinct u16
|
||||
|
||||
|
||||
|
||||
|
||||
// Exposing the alloc_error
|
||||
@(require_results)
|
||||
string_to_runes :: proc ( content : string, allocator := context.allocator) -> (runes : []rune, alloc_error : AllocatorError) #optional_allocator_error {
|
@ -12,7 +12,7 @@ No other part of the program will directly touch the vitual memory interface dir
|
||||
Thus for the scope of this prototype the Virtual Arena are the only interfaces to dynamic address spaces for the runtime of the client app.
|
||||
The host application as well ideally (although this may not be the case for a while)
|
||||
*/
|
||||
package sectr
|
||||
package grime
|
||||
|
||||
import "base:intrinsics"
|
||||
import "base:runtime"
|
||||
@ -25,8 +25,8 @@ VArena_GrowthPolicyProc :: #type proc( commit_used, committed, reserved, request
|
||||
|
||||
VArena :: struct {
|
||||
using vmem : VirtualMemoryRegion,
|
||||
dbg_name : string,
|
||||
tracker : MemoryTracker,
|
||||
dbg_name : string,
|
||||
commit_used : uint,
|
||||
growth_policy : VArena_GrowthPolicyProc,
|
||||
allow_any_reize : b32,
|
||||
@ -242,12 +242,14 @@ varena_allocator_proc :: proc(
|
||||
old_memory_offset := uintptr(old_memory) + uintptr(old_size)
|
||||
current_offset := uintptr(arena.reserve_start) + uintptr(arena.commit_used)
|
||||
|
||||
// if old_size < page_size {
|
||||
// // We're dealing with an allocation that requested less than the minimum allocated on vmem.
|
||||
// // Provide them more of their actual memory
|
||||
// data = byte_slice( old_memory, size )
|
||||
// return
|
||||
// }
|
||||
when false {
|
||||
if old_size < page_size {
|
||||
// We're dealing with an allocation that requested less than the minimum allocated on vmem.
|
||||
// Provide them more of their actual memory
|
||||
data = byte_slice( old_memory, size )
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
verify( old_memory_offset == current_offset || arena.allow_any_reize,
|
||||
"Cannot resize existing allocation in vitual arena to a larger size unless it was the last allocated" )
|
@ -1,7 +1,7 @@
|
||||
/* Virtual Memory OS Interface
|
||||
This is an alternative to the virtual core library provided by odin, suppport setting the base address among other things.
|
||||
*/
|
||||
package sectr
|
||||
package grime
|
||||
|
||||
import core_virtual "core:mem/virtual"
|
||||
import "core:os"
|
40
code/grime/virtual_memory_windows.odin
Normal file
40
code/grime/virtual_memory_windows.odin
Normal file
@ -0,0 +1,40 @@
|
||||
package grime
|
||||
|
||||
import "core:mem"
|
||||
import win32 "core:sys/windows"
|
||||
|
||||
@(require_results)
|
||||
virtual__reserve :: proc "contextless" ( base_address : uintptr, size : uint ) -> ( vmem : VirtualMemoryRegion, alloc_error : AllocatorError )
|
||||
{
|
||||
header_size := cast(uint) memory_align_formula(size_of(VirtualMemoryRegionHeader), mem.DEFAULT_ALIGNMENT)
|
||||
|
||||
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 = cast([^]byte) (uintptr(vmem.base_address) + uintptr(header_size))
|
||||
vmem.reserved = size
|
||||
vmem.committed = header_size
|
||||
alloc_error = .None
|
||||
return
|
||||
}
|
@ -62,12 +62,15 @@ import "core:time"
|
||||
thread_sleep :: time.sleep
|
||||
import "core:prof/spall"
|
||||
import rl "vendor:raylib"
|
||||
import sectr "../sectr"
|
||||
|
||||
import "codebase:grime"
|
||||
file_copy_sync :: grime.file_copy_sync
|
||||
file_is_locked :: grime.file_is_locked
|
||||
varena_init :: grime.varena_init
|
||||
|
||||
import "codebase:sectr"
|
||||
VArena :: sectr.VArena
|
||||
varena_init :: sectr.varena_init
|
||||
fatal :: sectr.fatal
|
||||
file_is_locked :: sectr.file_is_locked
|
||||
file_copy_sync :: sectr.file_copy_sync
|
||||
Logger :: sectr.Logger
|
||||
logger_init :: sectr.logger_init
|
||||
LogLevel :: sectr.LogLevel
|
||||
@ -167,7 +170,7 @@ load_sectr_api :: proc( version_id : i32 ) -> (loaded_module : sectr.ModuleAPI)
|
||||
}
|
||||
|
||||
live_file := Path_Sectr_Live_Module
|
||||
file_copy_sync( Path_Sectr_Module, live_file )
|
||||
file_copy_sync( Path_Sectr_Module, live_file, allocator = context.temp_allocator )
|
||||
|
||||
lib, load_result := os_lib_load( live_file )
|
||||
if ! load_result {
|
||||
|
2
code/sectr/Readme.md
Normal file
2
code/sectr/Readme.md
Normal file
@ -0,0 +1,2 @@
|
||||
# Sectr Package
|
||||
|
@ -39,7 +39,8 @@ ModuleAPI :: struct {
|
||||
startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem, files_buffer_mem : ^VArena, host_logger : ^Logger )
|
||||
{
|
||||
spall.SCOPED_EVENT( & prof.ctx, & prof.buffer, #procedure )
|
||||
Memory_App.profiler = prof
|
||||
// Memory_App.profiler = prof
|
||||
set_profiler_module_context( prof )
|
||||
|
||||
startup_tick := time.tick_now()
|
||||
|
||||
@ -376,7 +377,7 @@ sectr_shutdown :: proc()
|
||||
reload :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem, files_buffer_mem : ^VArena, host_logger : ^ Logger )
|
||||
{
|
||||
spall.SCOPED_EVENT( & prof.ctx, & prof.buffer, #procedure )
|
||||
Memory_App.profiler = prof
|
||||
set_profiler_module_context( prof )
|
||||
|
||||
context.logger = to_odin_logger( & Memory_App.logger )
|
||||
using Memory_App;
|
||||
@ -434,6 +435,8 @@ reload :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem,
|
||||
log("Module reloaded")
|
||||
}
|
||||
|
||||
Frametime_High_Perf_Threshold_MS :: 1 / 240.0
|
||||
|
||||
@export
|
||||
tick :: proc( host_delta_time_ms : f64, host_delta_ns : Duration ) -> b32
|
||||
{
|
||||
@ -488,7 +491,7 @@ tick_work_frame :: #force_inline proc( host_delta_time_ms : f64 ) -> b32
|
||||
debug.draw_UI_padding_bounds = false
|
||||
debug.draw_ui_content_bounds = false
|
||||
|
||||
config.engine_refresh_hz = 10000
|
||||
config.engine_refresh_hz = 165
|
||||
|
||||
// config.color_theme = App_Thm_Light
|
||||
// config.color_theme = App_Thm_Dusk
|
||||
|
@ -47,11 +47,7 @@ HMapZPL :: struct ( $ Type : typeid ) {
|
||||
entries : Array( HMapZPL_Entry(Type) ),
|
||||
}
|
||||
|
||||
hamp_zpl_init :: proc( $ Type : typeid, allocator : Allocator ) -> ( HMapZPL( Type), AllocatorError ) {
|
||||
return hamp_zpl_init_reserve( Type, allocator )
|
||||
}
|
||||
|
||||
hamp_zpl_init_reserve :: proc
|
||||
hamp_zpl_init :: proc
|
||||
( $ Type : typeid, allocator : Allocator, num : u64, dbg_name : string = "" ) -> ( HMapZPL( Type), AllocatorError )
|
||||
{
|
||||
result : HMapZPL(Type)
|
||||
@ -126,7 +122,7 @@ hamp_zpl_rehash :: proc( ht : ^ HMapZPL( $ Type ), new_num : u64 ) -> AllocatorE
|
||||
ensure( false, "ZPL HMAP IS REHASHING" )
|
||||
last_added_index : i64
|
||||
|
||||
new_ht, init_result := hamp_zpl_init_reserve( Type, ht.table.backing, new_num, ht.table.dbg_name )
|
||||
new_ht, init_result := hamp_zpl_init( Type, ht.table.backing, new_num, ht.table.dbg_name )
|
||||
if init_result != AllocatorError.None {
|
||||
ensure( false, "New hamp_zpl failed to allocate" )
|
||||
return init_result
|
||||
|
@ -1,15 +1,17 @@
|
||||
|
||||
package sectr
|
||||
|
||||
#region("Import Aliases")
|
||||
#region("base")
|
||||
|
||||
import "base:builtin"
|
||||
copy :: builtin.copy
|
||||
|
||||
import "base:intrinsics"
|
||||
mem_zero :: intrinsics.mem_zero
|
||||
ptr_sub :: intrinsics.ptr_sub
|
||||
type_has_field :: intrinsics.type_has_field
|
||||
type_elem_type :: intrinsics.type_elem_type
|
||||
|
||||
import "base:runtime"
|
||||
Byte :: runtime.Byte
|
||||
Kilobyte :: runtime.Kilobyte
|
||||
@ -20,12 +22,22 @@ import "base:runtime"
|
||||
Exabyte :: runtime.Exabyte
|
||||
resize_non_zeroed :: runtime.non_zero_mem_resize
|
||||
SourceCodeLocation :: runtime.Source_Code_Location
|
||||
debug_trap :: runtime.debug_trap
|
||||
|
||||
#endregion("base")
|
||||
|
||||
#region("core")
|
||||
|
||||
import c "core:c/libc"
|
||||
import "core:dynlib"
|
||||
|
||||
// import "core:dynlib"
|
||||
|
||||
import "core:hash"
|
||||
crc32 :: hash.crc32
|
||||
|
||||
import "core:hash/xxhash"
|
||||
xxh32 :: xxhash.XXH32
|
||||
|
||||
import fmt_io "core:fmt"
|
||||
str_fmt_out :: fmt_io.printf
|
||||
str_fmt_tmp :: fmt_io.tprintf
|
||||
@ -34,7 +46,9 @@ import fmt_io "core:fmt"
|
||||
str_fmt_buffer :: fmt_io.bprintf
|
||||
str_to_file_ln :: fmt_io.fprintln
|
||||
str_tmp_from_any :: fmt_io.tprint
|
||||
|
||||
import "core:math"
|
||||
|
||||
import "core:mem"
|
||||
align_forward_int :: mem.align_forward_int
|
||||
align_forward_uint :: mem.align_forward_uint
|
||||
@ -59,9 +73,12 @@ import "core:mem"
|
||||
TrackingAllocator :: mem.Tracking_Allocator
|
||||
tracking_allocator :: mem.tracking_allocator
|
||||
tracking_allocator_init :: mem.tracking_allocator_init
|
||||
|
||||
import "core:mem/virtual"
|
||||
VirtualProtectFlags :: virtual.Protect_Flags
|
||||
|
||||
// import "core:odin"
|
||||
|
||||
import "core:os"
|
||||
FileFlag_Create :: os.O_CREATE
|
||||
FileFlag_ReadWrite :: os.O_RDWR
|
||||
@ -73,37 +90,152 @@ import "core:os"
|
||||
file_seek :: os.seek
|
||||
file_status :: os.stat
|
||||
file_write :: os.write
|
||||
|
||||
import "core:path/filepath"
|
||||
file_name_from_path :: filepath.short_stem
|
||||
|
||||
import "core:strconv"
|
||||
parse_f32 :: strconv.parse_f32
|
||||
parse_u64 :: strconv.parse_u64
|
||||
parse_uint :: strconv.parse_uint
|
||||
|
||||
import str "core:strings"
|
||||
StringBuilder :: str.Builder
|
||||
str_builder_from_bytes :: str.builder_from_bytes
|
||||
str_builder_init :: str.builder_init
|
||||
str_builder_to_writer :: str.to_writer
|
||||
str_builder_to_string :: str.to_string
|
||||
|
||||
import "core:time"
|
||||
Duration :: time.Duration
|
||||
duration_seconds :: time.duration_seconds
|
||||
duration_ms :: time.duration_milliseconds
|
||||
thread_sleep :: time.sleep
|
||||
|
||||
import "core:unicode"
|
||||
is_white_space :: unicode.is_white_space
|
||||
|
||||
import "core:unicode/utf8"
|
||||
str_rune_count :: utf8.rune_count_in_string
|
||||
runes_to_string :: utf8.runes_to_string
|
||||
// string_to_runes :: utf8.string_to_runes
|
||||
|
||||
#endregion("core")
|
||||
|
||||
import "thirdparty:backtrace"
|
||||
StackTraceData :: backtrace.Trace_Const
|
||||
stacktrace :: backtrace.trace
|
||||
stacktrace_lines :: backtrace.lines
|
||||
|
||||
#endregion("Import Aliases")
|
||||
import "codebase:grime"
|
||||
// asserts
|
||||
ensure :: grime.ensure
|
||||
fatal :: grime.fatal
|
||||
verify :: grime.verify
|
||||
|
||||
#region("Proc overload mappings")
|
||||
// chrono
|
||||
NS_To_MS :: grime.NS_To_MS
|
||||
NS_To_US :: grime.NS_To_US
|
||||
NS_To_S :: grime.NS_To_S
|
||||
|
||||
US_To_NS :: grime.US_To_NS
|
||||
US_To_MS :: grime.US_To_MS
|
||||
US_To_S :: grime.US_To_S
|
||||
|
||||
MS_To_NS :: grime.MS_To_NS
|
||||
MS_To_US :: grime.MS_To_US
|
||||
MS_To_S :: grime.MS_To_S
|
||||
|
||||
S_To_NS :: grime.S_To_NS
|
||||
S_To_US :: grime.S_To_US
|
||||
S_To_MS :: grime.S_To_MS
|
||||
|
||||
// container
|
||||
Array :: grime.Array
|
||||
|
||||
array_to_slice :: grime.array_to_slice
|
||||
array_init_reserve :: grime.array_init_reserve
|
||||
array_append :: grime.array_append
|
||||
array_append_at :: grime.array_append_at
|
||||
array_clear :: grime.array_clear
|
||||
array_free :: grime.array_free
|
||||
array_grow_formula :: grime.array_grow_formula
|
||||
array_remove_at :: grime.array_remove_at
|
||||
array_resize :: grime.array_resize
|
||||
|
||||
// filesystem
|
||||
file_exists :: grime.file_exists
|
||||
file_rewind :: grime.file_rewind
|
||||
|
||||
// linked lists
|
||||
LL_Node :: grime.LL_Node
|
||||
|
||||
ll_push :: grime.ll_push
|
||||
ll_pop :: grime.ll_pop
|
||||
|
||||
DLL_Node :: grime.DLL_Node
|
||||
DLL_NodeFull :: grime.DLL_NodeFull
|
||||
DLL_NodePN :: grime.DLL_NodePN
|
||||
DLL_NodeFL :: grime.DLL_NodeFL
|
||||
|
||||
dll_full_push_back :: grime.dll_full_push_back
|
||||
dll_full_pop :: grime.dll_full_pop
|
||||
dll_push_back :: grime.dll_push_back
|
||||
dll_pop_back :: grime.dll_pop_back
|
||||
|
||||
// logger
|
||||
Logger :: grime.Logger
|
||||
LogLevel :: grime.LogLevel
|
||||
|
||||
to_odin_logger :: grime.to_odin_logger
|
||||
logger_init :: grime.logger_init
|
||||
log :: grime.log
|
||||
logf :: grime.logf
|
||||
|
||||
// memory
|
||||
MemoryTracker :: grime.MemoryTracker
|
||||
MemoryTrackerEntry :: grime.MemoryTrackerEntry
|
||||
|
||||
memtracker_clear :: grime.memtracker_clear
|
||||
memtracker_init :: grime.memtracker_init
|
||||
memtracker_register_auto_name :: grime.memtracker_register_auto_name
|
||||
memtracker_register_auto_name_slice :: grime.memtracker_register_auto_name_slice
|
||||
memtracker_unregister :: grime.memtracker_unregister
|
||||
|
||||
|
||||
calc_padding_with_header :: grime.calc_padding_with_header
|
||||
memory_after_header :: grime.memory_after_header
|
||||
memory_after :: grime.memory_after
|
||||
swap :: grime.swap
|
||||
|
||||
// profiler
|
||||
SpallProfiler :: grime.SpallProfiler
|
||||
|
||||
set_profiler_module_context :: grime.set_profiler_module_context
|
||||
|
||||
profile :: grime.profile
|
||||
profile_begin :: grime.profile_begin
|
||||
profile_end :: grime.profile_end
|
||||
|
||||
// os
|
||||
OS_Type :: grime.OS_Type
|
||||
|
||||
// timing
|
||||
when ODIN_OS == OS_Type.Windows {
|
||||
set__scheduler_granularity :: grime.set__scheduler_granularity
|
||||
}
|
||||
|
||||
// unicode
|
||||
string_to_runes :: grime.string_to_runes
|
||||
string_to_runes_array :: grime.string_to_runes_array
|
||||
|
||||
// virutal memory
|
||||
VArena :: grime.VArena
|
||||
VirtualMemoryRegion :: grime.VirtualMemoryRegion
|
||||
|
||||
varena_allocator :: grime.varena_allocator
|
||||
|
||||
#region("Procedure overload mappings")
|
||||
|
||||
// This has to be done on a per-module basis.
|
||||
|
||||
@ -111,12 +243,6 @@ add :: proc {
|
||||
add_range2,
|
||||
}
|
||||
|
||||
array_append :: proc {
|
||||
array_append_value,
|
||||
array_append_array,
|
||||
array_append_slice,
|
||||
}
|
||||
|
||||
bivec3 :: proc {
|
||||
bivec3_via_f32s,
|
||||
vec3_to_bivec3,
|
||||
@ -359,7 +485,3 @@ wedge :: proc {
|
||||
}
|
||||
|
||||
#endregion("Proc overload mappings")
|
||||
|
||||
OS_Type :: type_of(ODIN_OS)
|
||||
|
||||
swap :: #force_inline proc( a, b : ^ $Type ) -> ( ^ Type, ^ Type ) { return b, a }
|
@ -1,22 +0,0 @@
|
||||
package sectr
|
||||
|
||||
import "base:runtime"
|
||||
import "core:prof/spall"
|
||||
|
||||
SpallProfiler :: struct {
|
||||
ctx : spall.Context,
|
||||
buffer : spall.Buffer,
|
||||
}
|
||||
|
||||
@(deferred_none=profile_end)
|
||||
profile :: #force_inline proc "contextless" ( name : string, loc := #caller_location ) {
|
||||
spall._buffer_begin( & Memory_App.profiler.ctx, & Memory_App.profiler.buffer, name, "", loc )
|
||||
}
|
||||
|
||||
profile_begin :: #force_inline proc "contextless" ( name : string, loc := #caller_location ) {
|
||||
spall._buffer_begin( & Memory_App.profiler.ctx, & Memory_App.profiler.buffer, name, "", loc )
|
||||
}
|
||||
|
||||
profile_end :: #force_inline proc "contextless" () {
|
||||
spall._buffer_end( & Memory_App.profiler.ctx, & Memory_App.profiler.buffer)
|
||||
}
|
@ -66,7 +66,7 @@ str_cache_init :: proc( /*allocator : Allocator*/ ) -> ( cache : StringCache ) {
|
||||
cache.slab, alloc_error = slab_init( & policy, allocator = persistent_allocator(), dbg_name = dbg_name )
|
||||
verify(alloc_error == .None, "Failed to initialize the string cache" )
|
||||
|
||||
cache.table, alloc_error = hamp_zpl_init_reserve( StrRunesPair, persistent_allocator(), 4 * Megabyte, dbg_name )
|
||||
cache.table, alloc_error = hamp_zpl_init( StrRunesPair, persistent_allocator(), 4 * Megabyte, dbg_name )
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ ui_startup :: proc( ui : ^ UI_State, cache_allocator : Allocator /* , cache_rese
|
||||
ui^ = {}
|
||||
|
||||
for & cache in ui.caches {
|
||||
box_cache, allocation_error := hamp_zpl_init_reserve( UI_Box, cache_allocator, UI_Built_Boxes_Array_Size )
|
||||
box_cache, allocation_error := hamp_zpl_init( UI_Box, cache_allocator, UI_Built_Boxes_Array_Size )
|
||||
verify( allocation_error == AllocatorError.None, "Failed to allocate box cache" )
|
||||
cache = box_cache
|
||||
}
|
Loading…
Reference in New Issue
Block a user