diff --git a/core/_preload.odin b/core/_preload.odin index 4d438aad3..203347692 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -133,7 +133,8 @@ Allocator :: struct #ordered { Context :: struct #ordered { - thread_id: int, + thread_guid: int, + thread_index: int, allocator: Allocator, @@ -229,8 +230,8 @@ __init_context_from_ptr :: proc(c: ^Context, other: ^Context) #cc_contextless { if c.allocator.procedure == nil { c.allocator = default_allocator(); } - if c.thread_id == 0 { - c.thread_id = os.current_thread_id(); + if c.thread_guid == 0 { + c.thread_guid = os.current_thread_id(); } } @@ -240,8 +241,8 @@ __init_context :: proc(c: ^Context) #cc_contextless { if c.allocator.procedure == nil { c.allocator = default_allocator(); } - if c.thread_id == 0 { - c.thread_id = os.current_thread_id(); + if c.thread_guid == 0 { + c.thread_guid = os.current_thread_id(); } } @@ -328,7 +329,7 @@ append :: proc(array: ^[dynamic]$T, args: ...T) -> int { pop :: proc(array: ^[]$T) -> T #cc_contextless { res: T; - if array do return res; + if array != nil do return res; assert(len(array) > 0); res = array[len(array)-1]; ^raw.Slice(array).len -= 1; @@ -337,7 +338,7 @@ pop :: proc(array: ^[]$T) -> T #cc_contextless { pop :: proc(array: ^[dynamic]$T) -> T #cc_contextless { res: T; - if array do return res; + if array != nil do return res; assert(len(array) > 0); res = array[len(array)-1]; ^raw.DynamicArray(array).len -= 1; @@ -352,7 +353,7 @@ clear :: proc(array: ^[dynamic]$T) #cc_contextless #inline { } clear :: proc(m: ^map[$K]$V) #cc_contextless #inline { if m == nil do return; - raw_map := ^raw.DynamicMap(array); + raw_map := ^raw.DynamicMap(m); hashes := ^raw.DynamicArray(&raw_map.hashes); entries := ^raw.DynamicArray(&raw_map.entries); hashes.len = 0; @@ -391,7 +392,8 @@ __get_map_header :: proc(m: ^map[$K]$V) -> __MapHeader #cc_contextless { value: V, } - header.is_key_string = types.is_string(type_info(K)); + _, is_string := type_info_base(type_info(K)).(^TypeInfo.String); + header.is_key_string = is_string; header.entry_size = size_of(Entry); header.entry_align = align_of(Entry); header.value_offset = offset_of(Entry, value); diff --git a/core/os_windows.odin b/core/os_windows.odin index 3144089a0..ba607cfa7 100644 --- a/core/os_windows.odin +++ b/core/os_windows.odin @@ -75,8 +75,8 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errn } share_mode := u32(win32.FILE_SHARE_READ|win32.FILE_SHARE_WRITE); - sa: ^win32.Security_Attributes = nil; - sa_inherit := win32.Security_Attributes{length = size_of(win32.Security_Attributes), inherit_handle = 1}; + sa: ^win32.SecurityAttributes = nil; + sa_inherit := win32.SecurityAttributes{length = size_of(win32.SecurityAttributes), inherit_handle = 1}; if mode&O_CLOEXEC == 0 { sa = &sa_inherit; } diff --git a/core/sync_windows.odin b/core/sync_windows.odin index e96d9a0e5..71728dd32 100644 --- a/core/sync_windows.odin +++ b/core/sync_windows.odin @@ -7,12 +7,18 @@ Semaphore :: struct { _handle: win32.Handle, } +/* Mutex :: struct { _semaphore: Semaphore, _counter: i32, _owner: i32, _recursion: i32, } +*/ + +Mutex :: struct { + _critical_section: win32.CriticalSection, +} current_thread_id :: proc() -> i32 { return i32(win32.get_current_thread_id()); @@ -37,6 +43,29 @@ semaphore_wait :: proc(s: ^Semaphore) { } +mutex_init :: proc(m: ^Mutex, spin_count := 0) { + win32.initialize_critical_section_and_spin_count(&m._critical_section, u32(spin_count)); +} + +mutex_destroy :: proc(m: ^Mutex) { + win32.delete_critical_section(&m._critical_section); +} + +mutex_lock :: proc(m: ^Mutex) { + win32.enter_critical_section(&m._critical_section); +} + +mutex_try_lock :: proc(m: ^Mutex) -> bool { + return win32.try_enter_critical_section(&m._critical_section) != 0; +} + +mutex_unlock :: proc(m: ^Mutex) { + win32.leave_critical_section(&m._critical_section); +} + + + +/* mutex_init :: proc(m: ^Mutex) { atomics.store(&m._counter, 0); atomics.store(&m._owner, current_thread_id()); @@ -90,4 +119,4 @@ mutex_unlock :: proc(m: ^Mutex) { } } } - +*/ diff --git a/core/sys/windows.odin b/core/sys/windows.odin index f485244c3..171215800 100644 --- a/core/sys/windows.odin +++ b/core/sys/windows.odin @@ -103,7 +103,7 @@ FindData :: struct #ordered { alternate_file_name: [14]u8, } -Security_Attributes :: struct #ordered { +SecurityAttributes :: struct #ordered { length: u32, security_descriptor: rawptr, inherit_handle: Bool, @@ -142,6 +142,30 @@ PixelFormatDescriptor :: struct #ordered { damage_mask: u32, } +CriticalSection :: struct #ordered { + debug_info: ^CriticalSectionDebug, + + lock_count: i32, + recursion_count: i32, + owning_thread: Handle, + lock_semaphore: Handle, + spin_count: ^u32, +} + +CriticalSectionDebug :: struct #ordered { + typ: u16, + creator_back_trace_index: u16, + critical_section: ^CriticalSection, + process_locks_list: ^ListEntry, + entry_count: u32, + contention_count: u32, + flags: u32, + creator_back_trace_index_high: u16, + spare_word: u16, +} + +ListEntry :: struct #ordered {flink, blink: ^ListEntry}; + MAPVK_VK_TO_VSC :: 0; @@ -154,6 +178,12 @@ MAPVK_VSC_TO_VK_EX :: 3; INVALID_HANDLE :: Handle(~int(0)); +CREATE_SUSPENDED :: 0x00000004; +STACK_SIZE_PARAM_IS_A_RESERVATION :: 0x00010000; +WAIT_ABANDONED :: 0x00000080; +WAIT_OBJECT_0 :: 0; +WAIT_TIMEOUT :: 0x00000102; +WAIT_FAILED :: 0xffffffff; CS_VREDRAW :: 0x0001; CS_HREDRAW :: 0x0002; @@ -316,28 +346,44 @@ foreign kernel32 { get_process_heap :: proc() -> Handle #cc_std #link_name "GetProcessHeap" ---; - create_semaphore_a :: proc(attributes: ^Security_Attributes, initial_count, maximum_count: i32, name: ^u8) -> Handle #cc_std #link_name "CreateSemaphoreA" ---; + create_semaphore_a :: proc(attributes: ^SecurityAttributes, initial_count, maximum_count: i32, name: ^u8) -> Handle #cc_std #link_name "CreateSemaphoreA" ---; release_semaphore :: proc(semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool #cc_std #link_name "ReleaseSemaphore" ---; wait_for_single_object :: proc(handle: Handle, milliseconds: u32) -> u32 #cc_std #link_name "WaitForSingleObject" ---; - interlocked_compare_exchange :: proc(dst: ^i32, exchange, comparand: i32) -> i32 #cc_std #link_name "InterlockedCompareExchange" ---; - interlocked_exchange :: proc(dst: ^i32, desired: i32) -> i32 #cc_std #link_name "InterlockedExchange" ---; - interlocked_exchange_add :: proc(dst: ^i32, desired: i32) -> i32 #cc_std #link_name "InterlockedExchangeAdd" ---; - interlocked_and :: proc(dst: ^i32, desired: i32) -> i32 #cc_std #link_name "InterlockedAnd" ---; - interlocked_or :: proc(dst: ^i32, desired: i32) -> i32 #cc_std #link_name "InterlockedOr" ---; + interlocked_compare_exchange :: proc(dst: ^i32, exchange, comparand: i32) -> i32 #cc_c #link_name "InterlockedCompareExchange" ---; + interlocked_exchange :: proc(dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedExchange" ---; + interlocked_exchange_add :: proc(dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedExchangeAdd" ---; + interlocked_and :: proc(dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedAnd" ---; + interlocked_or :: proc(dst: ^i32, desired: i32) -> i32 #cc_c #link_name "InterlockedOr" ---; - interlocked_compare_exchange64 :: proc(dst: ^i64, exchange, comparand: i64) -> i64 #cc_std #link_name "InterlockedCompareExchange64" ---; - interlocked_exchange64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_std #link_name "InterlockedExchange64" ---; - interlocked_exchange_add64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_std #link_name "InterlockedExchangeAdd64" ---; - interlocked_and64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_std #link_name "InterlockedAnd64" ---; - interlocked_or64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_std #link_name "InterlockedOr64" ---; + interlocked_compare_exchange64 :: proc(dst: ^i64, exchange, comparand: i64) -> i64 #cc_c #link_name "InterlockedCompareExchange64" ---; + interlocked_exchange64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedExchange64" ---; + interlocked_exchange_add64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedExchangeAdd64" ---; + interlocked_and64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedAnd64" ---; + interlocked_or64 :: proc(dst: ^i64, desired: i64) -> i64 #cc_c #link_name "InterlockedOr64" ---; mm_pause :: proc() #cc_std #link_name "_mm_pause" ---; read_write_barrier :: proc() #cc_std #link_name "ReadWriteBarrier" ---; write_barrier :: proc() #cc_std #link_name "WriteBarrier" ---; read_barrier :: proc() #cc_std #link_name "ReadBarrier" ---; + create_thread :: proc(thread_attributes: ^SecurityAttributes, stack_size: int, start_routine: rawptr, + parameter: rawptr, creation_flags: u32, thread_id: ^u32) -> Handle #cc_std #link_name "CreateThread" ---; + resume_thread :: proc(thread: Handle) -> u32 #cc_std #link_name "ResumeThread" ---; + get_thread_priority :: proc(thread: Handle) -> i32 #cc_std #link_name "GetThreadPriority" ---; + set_thread_priority :: proc(thread: Handle, priority: i32) -> Bool #cc_std #link_name "SetThreadPriority" ---; + get_exit_code_thread :: proc(thread: Handle, exit_code: ^u32) -> Bool #cc_std #link_name "GetExitCodeThread" ---; + + initialize_critical_section :: proc(critical_section: ^CriticalSection) #cc_std #link_name "InitializeCriticalSection" ---; + initialize_critical_section_and_spin_count :: proc(critical_section: ^CriticalSection, spin_count: u32) #cc_std #link_name "InitializeCriticalSectionAndSpinCount" ---; + delete_critical_section :: proc(critical_section: ^CriticalSection) #cc_std #link_name "DeleteCriticalSection" ---; + set_critical_section_spin_count :: proc(critical_section: ^CriticalSection, spin_count: u32) -> u32 #cc_std #link_name "SetCriticalSectionSpinCount" ---; + try_enter_critical_section :: proc(critical_section: ^CriticalSection) -> Bool #cc_std #link_name "TryEnterCriticalSection" ---; + enter_critical_section :: proc(critical_section: ^CriticalSection) #cc_std #link_name "EnterCriticalSection" ---; + leave_critical_section :: proc(critical_section: ^CriticalSection) #cc_std #link_name "LeaveCriticalSection" ---; + + create_event_a :: proc(event_attributes: ^SecurityAttributes, manual_reset, initial_state: Bool, name: ^u8) -> Handle #cc_std #link_name "CreateEventA" ---; load_library_a :: proc(c_str: ^u8) -> Hmodule #cc_std #link_name "LoadLibraryA" ---; free_library :: proc(h: Hmodule) #cc_std #link_name "FreeLibrary" ---; diff --git a/src/parser.cpp b/src/parser.cpp index b52fb21b7..c2286e25b 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -3992,7 +3992,25 @@ AstNode *parse_for_stmt(AstFile *f) { if (f->curr_token.kind != Token_OpenBrace && f->curr_token.kind != Token_do) { isize prev_level = f->expr_level; + defer (f->expr_level = prev_level); f->expr_level = -1; + + if (f->curr_token.kind == Token_in) { + Token in_token = expect_token(f, Token_in); + AstNode *rhs = nullptr; + bool prev_allow_range = f->allow_range; + f->allow_range = true; + rhs = parse_expr(f, false); + f->allow_range = prev_allow_range; + + if (allow_token(f, Token_do)) { + body = convert_stmt_to_body(f, parse_stmt(f)); + } else { + body = parse_block_stmt(f, false); + } + return ast_range_stmt(f, token, nullptr, nullptr, in_token, rhs, body); + } + if (f->curr_token.kind != Token_Semicolon) { cond = parse_simple_stmt(f, StmtAllowFlag_In); if (cond->kind == AstNode_AssignStmt && cond->AssignStmt.op.kind == Token_in) { @@ -4014,7 +4032,6 @@ AstNode *parse_for_stmt(AstFile *f) { } } - f->expr_level = prev_level; } if (allow_token(f, Token_do)) { diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 31d1e8933..b1fff3305 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -94,14 +94,14 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \ TOKEN_KIND(Token_if, "if"), \ TOKEN_KIND(Token_else, "else"), \ TOKEN_KIND(Token_for, "for"), \ - TOKEN_KIND(Token_in, "in"), \ TOKEN_KIND(Token_match, "match"), \ + TOKEN_KIND(Token_in, "in"), \ + TOKEN_KIND(Token_do, "do"), \ TOKEN_KIND(Token_case, "case"), \ TOKEN_KIND(Token_break, "break"), \ TOKEN_KIND(Token_continue, "continue"), \ TOKEN_KIND(Token_fallthrough, "fallthrough"), \ TOKEN_KIND(Token_defer, "defer"), \ - TOKEN_KIND(Token_do, "do"), \ TOKEN_KIND(Token_return, "return"), \ TOKEN_KIND(Token_proc, "proc"), \ TOKEN_KIND(Token_macro, "macro"), \ @@ -111,9 +111,9 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \ TOKEN_KIND(Token_enum, "enum"), \ TOKEN_KIND(Token_bit_field, "bit_field"), \ TOKEN_KIND(Token_vector, "vector"), \ + TOKEN_KIND(Token_map, "map"), \ TOKEN_KIND(Token_static, "static"), \ TOKEN_KIND(Token_dynamic, "dynamic"), \ - TOKEN_KIND(Token_map, "map"), \ TOKEN_KIND(Token_using, "using"), \ TOKEN_KIND(Token_context, "context"), \ TOKEN_KIND(Token_push_context, "push_context"), \