WIP: fleshing out cod2 for once a bit more
Planning to try out a flavor of Ryan's multi-threaded laned procs with the some extra threads hooked up separately to a job system. Will most likely do 2 threads main/helper on live lanes, then 2 others on job queue loops
This commit is contained in:
@@ -2,16 +2,19 @@ package vefontcache
|
||||
|
||||
// Add profiling hookup here
|
||||
|
||||
// import ""
|
||||
import "codebase:grime"
|
||||
|
||||
@(deferred_none = profile_end, disabled = DISABLE_PROFILING)
|
||||
profile :: #force_inline proc "contextless" ( name : string, loc := #caller_location ) {
|
||||
grime.profile_begin(name, loc)
|
||||
}
|
||||
|
||||
@(disabled = DISABLE_PROFILING)
|
||||
profile_begin :: #force_inline proc "contextless" ( name : string, loc := #caller_location ) {
|
||||
grime.profile_begin(name, loc)
|
||||
}
|
||||
|
||||
@(disabled = DISABLE_PROFILING)
|
||||
profile_end :: #force_inline proc "contextless" () {
|
||||
grime.profile_end()
|
||||
}
|
||||
|
7
code2/grime/Readme.md
Normal file
7
code2/grime/Readme.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Grime
|
||||
|
||||
This is a top-level package to adjust odin to my personalized usage.
|
||||
|
||||
I curate all usage of odin's provided package definitons through here. The client and host packages should never directly import them.
|
||||
|
||||
There are no implicit static allocations in Grime. Ideally there are also none from the base/core packages but some probably leak.
|
1
code2/grime/arenas.odin
Normal file
1
code2/grime/arenas.odin
Normal file
@@ -0,0 +1 @@
|
||||
package grime
|
8
code2/grime/context.odin
Normal file
8
code2/grime/context.odin
Normal file
@@ -0,0 +1,8 @@
|
||||
package grime
|
||||
|
||||
// Context :: struct {
|
||||
// }
|
||||
|
||||
// context_usr :: #force_inline proc( $ Type : typeid ) -> (^Type) {
|
||||
// return cast(^Type) context.user_ptr
|
||||
// }
|
20
code2/grime/linked_list.odin
Normal file
20
code2/grime/linked_list.odin
Normal file
@@ -0,0 +1,20 @@
|
||||
package grime
|
||||
|
||||
sll_stack_push_n :: proc "contextless" (curr, n, n_link: ^^$Type) {
|
||||
(n_link ^) = (curr ^)
|
||||
(curr ^) = (n ^)
|
||||
}
|
||||
sll_queue_push_nz :: proc "contextless" (first: ^$ParentType, last, n: ^^$Type, nil_val: ^Type) {
|
||||
if (first ^) == nil_val {
|
||||
(first ^) = n^
|
||||
(last ^) = n^
|
||||
n^.next = nil_val
|
||||
}
|
||||
else {
|
||||
(last ^).next = n^
|
||||
(last ^) = n^
|
||||
n^.next = nil_val
|
||||
}
|
||||
}
|
||||
sll_queue_push_n :: #force_inline proc "contextless" (first: $ParentType, last, n: ^^$Type) { sll_queue_push_nz(first, last, n, nil) }
|
||||
|
226
code2/grime/memory.odin
Normal file
226
code2/grime/memory.odin
Normal file
@@ -0,0 +1,226 @@
|
||||
package grime
|
||||
|
||||
Kilo :: 1024
|
||||
Mega :: Kilo * 1024
|
||||
Giga :: Mega * 1024
|
||||
Tera :: Giga * 1024
|
||||
|
||||
ptr_cursor :: #force_inline proc "contextless" (ptr: ^$Type) -> [^]Type { return transmute([^]Type) ptr }
|
||||
|
||||
align_pow2 :: proc(x: int, b: int) -> int {
|
||||
assert(b != 0)
|
||||
assert((b & (b - 1)) == 0) // Check power of 2
|
||||
return ((x + b - 1) & ~(b - 1))
|
||||
}
|
||||
memory_zero_explicit :: proc "contextless" (data: rawptr, len: int) -> rawptr {
|
||||
mem_zero_volatile(data, len) // Use the volatile mem_zero
|
||||
atomic_thread_fence(.Seq_Cst) // Prevent reordering
|
||||
return data
|
||||
}
|
||||
memory_copy :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {
|
||||
mem_copy(dst, src, len)
|
||||
return dst
|
||||
}
|
||||
|
||||
SliceByte :: struct {
|
||||
data: [^]byte,
|
||||
len: int
|
||||
}
|
||||
SliceRaw :: struct ($Type: typeid) {
|
||||
data: [^]Type,
|
||||
len: int,
|
||||
}
|
||||
slice :: #force_inline proc "contextless" (s: [^] $Type, num: $Some_Integer) -> [ ]Type { return transmute([]Type) SliceRaw(Type) { s, cast(int) num } }
|
||||
slice_cursor :: #force_inline proc "contextless" (s: []$Type) -> [^]Type { return transmute([^]Type) raw_data(s) }
|
||||
slice_assert :: #force_inline proc (s: $SliceType / []$Type) {
|
||||
assert(len(s) > 0)
|
||||
assert(s != nil)
|
||||
}
|
||||
slice_end :: #force_inline proc "contextless" (s : $SliceType / []$Type) -> ^Type { return & cursor(s)[len(s)] }
|
||||
|
||||
slice_copy :: proc "contextless" (dst, src: $SliceType / []$Type) -> int {
|
||||
n := max(0, min(len(dst), len(src)))
|
||||
if n > 0 {
|
||||
mem_copy(raw_data(dst), raw_data(src), n * size_of(Type))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
@(require_results) slice_to_bytes :: proc "contextless" (s: []$Type) -> []byte { return ([^]byte)(raw_data(s))[:len(s) * size_of(Type)] }
|
||||
@(require_results) slice_raw :: proc "contextless" (s: []$Type) -> SliceRaw(Type) { return transmute(SliceRaw(Type)) s }
|
||||
|
||||
//region Allocator Interface
|
||||
AllocatorOp :: enum u32 {
|
||||
Alloc_NoZero = 0, // If Alloc exist, so must No_Zero
|
||||
Alloc,
|
||||
Free,
|
||||
Reset,
|
||||
Grow_NoZero,
|
||||
Grow,
|
||||
Shrink,
|
||||
Rewind,
|
||||
SavePoint,
|
||||
Query, // Must always be implemented
|
||||
}
|
||||
AllocatorQueryFlag :: enum u64 {
|
||||
Alloc,
|
||||
Free,
|
||||
Reset, // Wipe the allocator's state
|
||||
|
||||
Shrink,
|
||||
Grow,
|
||||
Resize, // Supports both grow and shrink
|
||||
|
||||
Rewind, // Ability to rewind to a save point (ex: arenas, stack), must also be able to save such a point
|
||||
|
||||
// Actually_Resize,
|
||||
// Is_This_Yours,
|
||||
|
||||
Hint_Fast_Bump,
|
||||
Hint_General_Heap,
|
||||
Hint_Per_Frame_Temporary,
|
||||
Hint_Debug_Support,
|
||||
}
|
||||
AllocatorQueryFlags :: bit_set[AllocatorQueryFlag; u64]
|
||||
AllocatorSP :: struct {
|
||||
type_sig: AllocatorProc,
|
||||
slot: int,
|
||||
}
|
||||
AllocatorProc :: #type proc (input: AllocatorProc_In, out: ^AllocatorProc_Out)
|
||||
AllocatorProc_In :: struct {
|
||||
data: rawptr,
|
||||
requested_size: int,
|
||||
alignment: int,
|
||||
using _ : struct #raw_union {
|
||||
old_allocation: []byte,
|
||||
save_point : AllocatorSP,
|
||||
},
|
||||
op: AllocatorOp,
|
||||
}
|
||||
AllocatorProc_Out :: struct {
|
||||
using _ : struct #raw_union {
|
||||
allocation: []byte,
|
||||
save_point: AllocatorSP,
|
||||
},
|
||||
features: AllocatorQueryFlags,
|
||||
left: int,
|
||||
max_alloc: int,
|
||||
min_alloc: int,
|
||||
continuity_break: b32,
|
||||
}
|
||||
AllocatorQueryInfo :: struct {
|
||||
save_point: AllocatorSP,
|
||||
features: AllocatorQueryFlags,
|
||||
left: int,
|
||||
max_alloc: int,
|
||||
min_alloc: int,
|
||||
continuity_break: b32,
|
||||
}
|
||||
AllocatorInfo :: struct {
|
||||
procedure: AllocatorProc,
|
||||
data: rawptr,
|
||||
}
|
||||
// #assert(size_of(AllocatorQueryInfo) == size_of(AllocatorProc_Out))
|
||||
|
||||
MEMORY_ALIGNMENT_DEFAULT :: 2 * size_of(rawptr)
|
||||
|
||||
allocator_query :: proc(ainfo := context.allocator) -> AllocatorQueryInfo {
|
||||
assert(ainfo.procedure != nil)
|
||||
out: AllocatorQueryInfo; (cast(AllocatorProc)ainfo.procedure)({data = ainfo.data, op = .Query}, transmute(^AllocatorProc_Out) & out)
|
||||
return out
|
||||
}
|
||||
mem_free :: proc(mem: []byte, ainfo := context.allocator) {
|
||||
assert(ainfo.procedure != nil)
|
||||
(cast(AllocatorProc)ainfo.procedure)({data = ainfo.data, op = .Free, old_allocation = mem}, & {})
|
||||
}
|
||||
mem_reset :: proc(ainfo := context.allocator) {
|
||||
assert(ainfo.procedure != nil)
|
||||
(cast(AllocatorProc)ainfo.procedure)({data = ainfo.data, op = .Reset}, &{})
|
||||
}
|
||||
mem_rewind :: proc(ainfo := context.allocator, save_point: AllocatorSP) {
|
||||
assert(ainfo.procedure != nil)
|
||||
(cast(AllocatorProc)ainfo.procedure)({data = ainfo.data, op = .Rewind, save_point = save_point}, & {})
|
||||
}
|
||||
mem_save_point :: proc(ainfo := context.allocator) -> AllocatorSP {
|
||||
assert(ainfo.procedure != nil)
|
||||
out: AllocatorProc_Out
|
||||
(cast(AllocatorProc)ainfo.procedure)({data = ainfo.data, op = .SavePoint}, & out)
|
||||
return out.save_point
|
||||
}
|
||||
mem_alloc :: proc(size: int, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: b32 = false, ainfo := context.allocator) -> []byte {
|
||||
assert(ainfo.procedure != nil)
|
||||
input := AllocatorProc_In {
|
||||
data = ainfo.data,
|
||||
op = no_zero ? .Alloc_NoZero : .Alloc,
|
||||
requested_size = size,
|
||||
alignment = alignment,
|
||||
}
|
||||
output: AllocatorProc_Out
|
||||
(cast(AllocatorProc)ainfo.procedure)(input, & output)
|
||||
return output.allocation
|
||||
}
|
||||
mem_grow :: proc(mem: []byte, size: int, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: b32 = false, ainfo := context.allocator) -> []byte {
|
||||
assert(ainfo.procedure != nil)
|
||||
input := AllocatorProc_In {
|
||||
data = ainfo.data,
|
||||
op = no_zero ? .Grow_NoZero : .Grow,
|
||||
requested_size = size,
|
||||
alignment = alignment,
|
||||
old_allocation = mem,
|
||||
}
|
||||
output: AllocatorProc_Out
|
||||
(cast(AllocatorProc)ainfo.procedure)(input, & output)
|
||||
return output.allocation
|
||||
}
|
||||
mem_resize :: proc(mem: []byte, size: int, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: b32 = false, ainfo := context.allocator) -> []byte {
|
||||
assert(ainfo.procedure != nil)
|
||||
input := AllocatorProc_In {
|
||||
data = ainfo.data,
|
||||
op = len(mem) < size ? .Shrink : no_zero ? .Grow_NoZero : .Grow,
|
||||
requested_size = size,
|
||||
alignment = alignment,
|
||||
old_allocation = mem,
|
||||
}
|
||||
output: AllocatorProc_Out
|
||||
(cast(AllocatorProc)ainfo.procedure)(input, & output)
|
||||
return output.allocation
|
||||
}
|
||||
mem_shrink :: proc(mem: []byte, size: int, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: b32 = false, ainfo := context.allocator) -> []byte {
|
||||
assert(ainfo.procedure != nil)
|
||||
input := AllocatorProc_In {
|
||||
data = ainfo.data,
|
||||
op = .Shrink,
|
||||
requested_size = size,
|
||||
alignment = alignment,
|
||||
old_allocation = mem,
|
||||
}
|
||||
output: AllocatorProc_Out
|
||||
(cast(AllocatorProc)ainfo.procedure)(input, & output)
|
||||
return output.allocation
|
||||
}
|
||||
|
||||
alloc_type :: proc($Type: typeid, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: b32 = false, ainfo := context.allocator) -> ^Type {
|
||||
assert(ainfo.procedure != nil)
|
||||
input := AllocatorProc_In {
|
||||
data = ainfo.data,
|
||||
op = no_zero ? .Alloc_NoZero : .Alloc,
|
||||
requested_size = size_of(Type),
|
||||
alignment = alignment,
|
||||
}
|
||||
output: AllocatorProc_Out
|
||||
(cast(AllocatorProc)ainfo.procedure)(input, & output)
|
||||
return transmute(^Type) raw_data(output.allocation)
|
||||
}
|
||||
alloc_slice :: proc($SliceType: typeid / []$Type, num : int, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: b32 = false, ainfo := context.allocator) -> []Type {
|
||||
assert(ainfo.procedure != nil)
|
||||
input := AllocatorProc_In {
|
||||
data = ainfo.data,
|
||||
op = no_zero ? .Alloc_NoZero : .Alloc,
|
||||
requested_size = size_of(Type) * num,
|
||||
alignment = alignment,
|
||||
}
|
||||
output: AllocatorProc_Out
|
||||
(cast(AllocatorProc)ainfo.procedure)(input, & output)
|
||||
return transmute([]Type) slice(raw_data(output.allocation), num)
|
||||
}
|
||||
//endregion Allocator Interface
|
1
code2/grime/os.odin
Normal file
1
code2/grime/os.odin
Normal file
@@ -0,0 +1 @@
|
||||
package grime
|
@@ -0,0 +1,23 @@
|
||||
package grime
|
||||
|
||||
import "base:builtin"
|
||||
Odin_OS_Type :: type_of(ODIN_OS)
|
||||
|
||||
import "base:intrinsics"
|
||||
atomic_thread_fence :: intrinsics.atomic_thread_fence
|
||||
mem_zero :: intrinsics.mem_zero
|
||||
mem_zero_volatile :: intrinsics.mem_zero_volatile
|
||||
mem_copy :: intrinsics.mem_copy_non_overlapping
|
||||
mem_copy_overlapping :: intrinsics.mem_copy
|
||||
|
||||
import "base:runtime"
|
||||
Assertion_Failure_Proc :: runtime.Assertion_Failure_Proc
|
||||
Logger :: runtime.Logger
|
||||
Random_Generator :: runtime.Random_Generator
|
||||
slice_copy_overlapping :: runtime.copy_slice
|
||||
|
||||
import core_os "core:os"
|
||||
// ODIN_OS :: core_os.ODIN_OS
|
||||
|
||||
import "core:slice"
|
||||
slice_zero :: slice.zero
|
||||
|
3
code2/host/Readme.md
Normal file
3
code2/host/Readme.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Host Module
|
||||
|
||||
The sole job of this module is to provide a bare launch pad and runtime module hot-reload support for the client module (sectr). To achieve this the static memory of the client module is tracked by the host and provides an api for the client to reload itself when a change is detected. The client is reponsible for populating the static memory reference and doing anything else it needs via the host api that it cannot do on its own.
|
@@ -1,8 +0,0 @@
|
||||
package host
|
||||
|
||||
|
||||
|
||||
main :: proc()
|
||||
{
|
||||
|
||||
}
|
24
code2/host/launch.odin
Normal file
24
code2/host/launch.odin
Normal file
@@ -0,0 +1,24 @@
|
||||
package host
|
||||
|
||||
Path_Logs :: "../logs"
|
||||
when ODIN_OS == .Windows
|
||||
{
|
||||
Path_Sectr_Module :: "sectr.dll"
|
||||
Path_Sectr_Live_Module :: "sectr_live.dll"
|
||||
Path_Sectr_Debug_Symbols :: "sectr.pdb"
|
||||
}
|
||||
|
||||
// Only static memory host has.
|
||||
host_memory: HostMemory
|
||||
|
||||
main :: proc()
|
||||
{
|
||||
host_memory.host_api.sync_client_module = sync_client_api
|
||||
host_memory.client_api.startup(& host_memory)
|
||||
}
|
||||
|
||||
@export
|
||||
sync_client_api :: proc()
|
||||
{
|
||||
// Fill out detection and reloading of client api.
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
package host
|
||||
|
||||
import "base:builtin"
|
||||
// Odin_OS_Type :: type_of(ODIN_OS)
|
||||
|
||||
import "base:intrinsics"
|
||||
// atomic_thread_fence :: intrinsics.atomic_thread_fence
|
||||
// mem_zero :: intrinsics.mem_zero
|
||||
// mem_zero_volatile :: intrinsics.mem_zero_volatile
|
||||
// mem_copy :: intrinsics.mem_copy_non_overlapping
|
||||
// mem_copy_overlapping :: intrinsics.mem_copy
|
||||
|
||||
import "base:runtime"
|
||||
// Assertion_Failure_Proc :: runtime.Assertion_Failure_Proc
|
||||
// Logger :: runtime.Logger
|
||||
|
||||
import core_os "core:os"
|
||||
|
||||
import grime "codebase:grime"
|
||||
|
||||
import "codebase:sectr"
|
||||
Client_API :: sectr.ModuleAPI
|
||||
HostMemory :: sectr.HostMemory
|
||||
|
||||
|
@@ -1,2 +1,3 @@
|
||||
# Sectr Package
|
||||
|
||||
|
||||
|
@@ -12,23 +12,21 @@ ModuleAPI :: struct {
|
||||
lib: dynlib.Library,
|
||||
// write-time: FileTime,
|
||||
|
||||
startup: type_of( startup ),
|
||||
shutdown: type_of( sectr_shutdown ),
|
||||
reload: type_of( hot_reload ),
|
||||
tick: type_of( tick ),
|
||||
clean_frame: type_of( clean_frame ),
|
||||
startup: type_of( startup ),
|
||||
hot_reload: type_of( hot_reload ),
|
||||
}
|
||||
|
||||
StartupContext :: struct {}
|
||||
|
||||
@export
|
||||
startup :: proc(ctx: StartupContext)
|
||||
startup :: proc(host_mem: ^HostMemory)
|
||||
{
|
||||
|
||||
|
||||
thread_wide_startup()
|
||||
}
|
||||
|
||||
@export
|
||||
sectr_shutdown :: proc()
|
||||
thread_wide_startup :: proc()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -38,15 +36,3 @@ hot_reload :: proc()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@export
|
||||
tick :: proc()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@export
|
||||
clean_frame ::proc()
|
||||
{
|
||||
|
||||
}
|
||||
|
16
code2/sectr/engine/host_api.odin
Normal file
16
code2/sectr/engine/host_api.odin
Normal file
@@ -0,0 +1,16 @@
|
||||
package sectr
|
||||
|
||||
HostMemory :: struct {
|
||||
client_api: ModuleAPI,
|
||||
client_memory: ^State,
|
||||
host_api: Host_API,
|
||||
}
|
||||
|
||||
Host_API :: struct {
|
||||
launch_thread: #type proc(),
|
||||
|
||||
request_virtual_memory: #type proc(),
|
||||
request_virtual_mapped_io: #type proc(),
|
||||
|
||||
sync_client_module : #type proc(),
|
||||
}
|
@@ -1 +1,3 @@
|
||||
package sectr
|
||||
|
||||
|
||||
|
@@ -1 +1,9 @@
|
||||
package sectr
|
||||
|
||||
// This should be the only global on client module side.
|
||||
host_memory: ^HostMemory
|
||||
|
||||
|
||||
State :: struct {
|
||||
|
||||
}
|
||||
|
@@ -66,10 +66,12 @@ $command_run = 'run'
|
||||
|
||||
$flag_build_mode = '-build-mode:'
|
||||
$flag_build_mode_dll = '-build-mode:dll'
|
||||
$flag_build_diagnostics = '-build-diagnostics'
|
||||
$flag_collection = '-collection:'
|
||||
$flag_debug = '-debug'
|
||||
$flag_define = '-define:'
|
||||
$flag_default_allocator_nil = '-default-to-nil-allocator'
|
||||
$flag_default_allocator_panic = '-default-to-panic-allocator'
|
||||
$flag_disable_assert = '-disable-assert'
|
||||
$flag_dynamic_map_calls = '-dynamic-map-calls'
|
||||
$flag_extra_assembler_flags = '-extra_assembler-flags:'
|
||||
@@ -139,7 +141,7 @@ push-location $path_root
|
||||
function build-prototype
|
||||
{
|
||||
push-location $path_code
|
||||
$project_name = 'sectr2'
|
||||
$project_name = 'sectr'
|
||||
|
||||
write-host "`nBuilding Sectr Prototype`n"
|
||||
|
||||
@@ -213,24 +215,26 @@ push-location $path_root
|
||||
$build_args += $flag_microarch_zen5
|
||||
$build_args += $flag_use_separate_modules
|
||||
$build_args += $flag_thread_count + $CoreCount_Physical
|
||||
$build_args += $flag_optimize_none
|
||||
# $build_args += $flag_optimize_minimal
|
||||
# $build_args += $flag_optimize_none
|
||||
$build_args += $flag_optimize_minimal
|
||||
# $build_args += $flag_optimize_speed
|
||||
# $build_args += $falg_optimize_aggressive
|
||||
$build_args += $flag_debug
|
||||
$build_args += $flag_pdb_name + $pdb
|
||||
$build_args += $flag_subsystem + 'windows'
|
||||
# $build_args += $flag_show_system_calls
|
||||
$build_args += $flag_show_timings
|
||||
$build_args += ($flag_extra_linker_flags + $linker_args )
|
||||
# $build_args += $flag_no_bounds_check
|
||||
# $build_args += $flag_no_thread_checker
|
||||
# $build_args += $flag_dynamic_map_calls
|
||||
$build_args += $flag_default_allocator_nil
|
||||
# $build_args += $flag_default_allocator_nil
|
||||
$build_args += $flag_default_allocator_panic
|
||||
$build_args += ($flag_max_error_count + '10')
|
||||
# $build_args += $flag_sanitize_address
|
||||
# $build_args += $flag_sanitize_memory
|
||||
# $build_args += $flag_show_debug_messages
|
||||
$build_args += $flag_show_timings
|
||||
# $build_args += $flag_build_diagnostics
|
||||
# TODO(Ed): Enforce nil default allocator
|
||||
|
||||
# foreach ($arg in $build_args) {
|
||||
@@ -297,8 +301,8 @@ push-location $path_root
|
||||
# $build_args += $flag_micro_architecture_native
|
||||
$build_args += $flag_microarch_zen5
|
||||
$build_args += $flag_thread_count + $CoreCount_Physical
|
||||
$build_args += $flag_optimize_none
|
||||
# $build_args += $flag_optimize_minimal
|
||||
# $build_args += $flag_optimize_none
|
||||
$build_args += $flag_optimize_minimal
|
||||
# $build_args += $flag_optimize_speed
|
||||
# $build_args += $falg_optimize_aggressive
|
||||
$build_args += $flag_debug
|
||||
@@ -309,10 +313,11 @@ push-location $path_root
|
||||
# $build_args += $flag_show_system_call
|
||||
# $build_args += $flag_no_bounds_check
|
||||
# $build_args += $flag_no_thread_checker
|
||||
$build_args += $flag_default_allocator_nil
|
||||
$build_args += $flag_default_allocator_panic
|
||||
$build_args += ($flag_max_error_count + '10')
|
||||
# $build_args += $flag_sanitize_address
|
||||
# $build_args += $flag_sanitize_memory
|
||||
# $build_args += $flag_build_diagnostics
|
||||
# TODO(Ed): Enforce nil default allocator
|
||||
|
||||
# foreach ($arg in $build_args) {
|
||||
|
Reference in New Issue
Block a user