diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-07-20 23:57:56 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-07-20 23:57:56 +0100 |
| commit | dbddec33c8247beb5984d0c3fbcdf86a94054248 (patch) | |
| tree | 6f711915422e3a2b76013d4bf6d488ce1221d84e /core | |
| parent | 401a5955a4ed1746e96f29db8e521cb4831a863d (diff) | |
Internal changes; thread.odin for windows only
Diffstat (limited to 'core')
| -rw-r--r-- | core/fmt.odin | 6 | ||||
| -rw-r--r-- | core/mem.odin | 10 | ||||
| -rw-r--r-- | core/thread.odin | 76 |
3 files changed, 87 insertions, 5 deletions
diff --git a/core/fmt.odin b/core/fmt.odin index c8723f6c4..3d16e309c 100644 --- a/core/fmt.odin +++ b/core/fmt.odin @@ -7,6 +7,7 @@ import ( "raw.odin"; ) + _BUFFER_SIZE :: 1<<12; StringBuffer :: union { @@ -749,6 +750,11 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) { fmt_bad_verb(fi, verb); return; } + if b.is_raw_union { + write_string(fi.buf, info.name); + write_string(fi.buf, "{}"); + return; + } write_string(fi.buf, info.name); write_byte(fi.buf, '{'); for _, i in b.names { diff --git a/core/mem.odin b/core/mem.odin index 91d70937a..ded520da7 100644 --- a/core/mem.odin +++ b/core/mem.odin @@ -73,17 +73,17 @@ AllocationHeader :: struct { allocation_header_fill :: proc(header: ^AllocationHeader, data: rawptr, size: int) { header.size = size; - ptr := cast(^int)(header+1); - n := cast(^int)data - ptr; + ptr := cast(^uint)(header+1); + n := cast(^uint)data - ptr; for i in 0..n { - (ptr+i)^ = -1; + (ptr+i)^ = ~uint(0); } } allocation_header :: proc(data: rawptr) -> ^AllocationHeader { if data == nil do return nil; - p := cast(^int)data; - for (p-1)^ == -1 do p = (p-1); + p := cast(^uint)data; + for (p-1)^ == ~uint(0) do p = (p-1); return cast(^AllocationHeader)(p-1); } diff --git a/core/thread.odin b/core/thread.odin new file mode 100644 index 000000000..b6a39cd89 --- /dev/null +++ b/core/thread.odin @@ -0,0 +1,76 @@ +_ :: compile_assert(ODIN_OS == "windows"); + +import win32 "sys/windows.odin"; + +Thread :: struct { + using specific: OsSpecific; + procedure: Proc; + data: rawptr; + user_index: int; + + init_context: Context; + use_init_context: bool; + + Proc :: #type proc(^Thread) -> int; + OsSpecific :: struct { + win32_thread: win32.Handle; + win32_thread_id: u32; + } +} + + +create :: proc(procedure: Thread.Proc) -> ^Thread { + win32_thread_id: u32; + + __windows_thread_entry_proc :: proc(data: rawptr) -> i32 #cc_c { + if data == nil do return 0; + + t := cast(^Thread)data; + + c := context; + if t.use_init_context { + c = t.init_context; + } + + exit := 0; + push_context c { + exit = t.procedure(t); + } + + return cast(i32)exit; + } + + + win32_thread_proc := cast(rawptr)__windows_thread_entry_proc; + thread := new(Thread); + + win32_thread := win32.create_thread(nil, 0, win32_thread_proc, thread, win32.CREATE_SUSPENDED, &win32_thread_id); + if win32_thread == nil { + free(thread); + return nil; + } + thread.procedure = procedure; + thread.win32_thread = win32_thread; + thread.win32_thread_id = win32_thread_id; + + return thread; +} + +start :: proc(using thread: ^Thread) { + win32.resume_thread(win32_thread); +} + +is_done :: proc(using thread: ^Thread) -> bool { + res := win32.wait_for_single_object(win32_thread, 0); + return res != win32.WAIT_TIMEOUT; +} + +join :: proc(using thread: ^Thread) { + win32.wait_for_single_object(win32_thread, win32.INFINITE); + win32.close_handle(win32_thread); + win32_thread = win32.INVALID_HANDLE; +} +destroy :: proc(thread: ^Thread) { + join(thread); + free(thread); +} |