Browse Source

Merge branch 'master' into pr/1726

Jeroen van Rijn 3 years ago
parent
commit
694c13fe86

+ 10 - 3
core/encoding/xml/xml_reader.odin

@@ -493,7 +493,16 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err
 	return doc, .None
 	return doc, .None
 }
 }
 
 
-parse_from_file :: proc(filename: string, options := DEFAULT_Options, error_handler := default_error_handler, allocator := context.allocator) -> (doc: ^Document, err: Error) {
+parse_from_string :: proc(data: string, options := DEFAULT_Options, path := "", error_handler := default_error_handler, allocator := context.allocator) -> (doc: ^Document, err: Error) {
+	_data := transmute([]u8)data
+
+	return parse_from_slice(_data, options, path, error_handler, allocator)
+}
+
+parse :: proc { parse_from_string, parse_from_slice }
+
+// Load an XML file
+load_from_file :: proc(filename: string, options := DEFAULT_Options, error_handler := default_error_handler, allocator := context.allocator) -> (doc: ^Document, err: Error) {
 	context.allocator = allocator
 	context.allocator = allocator
 	options := options
 	options := options
 
 
@@ -505,8 +514,6 @@ parse_from_file :: proc(filename: string, options := DEFAULT_Options, error_hand
 	return parse_from_slice(data, options, filename, error_handler, allocator)
 	return parse_from_slice(data, options, filename, error_handler, allocator)
 }
 }
 
 
-parse :: proc { parse_from_file, parse_from_slice }
-
 destroy :: proc(doc: ^Document) {
 destroy :: proc(doc: ^Document) {
 	if doc == nil { return }
 	if doc == nil { return }
 
 

+ 1 - 1
core/image/common.odin

@@ -1185,4 +1185,4 @@ write_bytes :: proc(buf: ^bytes.Buffer, data: []u8) -> (err: compress.General_Er
 		return .Resize_Failed
 		return .Resize_Failed
 	}
 	}
 	return nil
 	return nil
-}
+}

+ 1 - 0
core/intrinsics/intrinsics.odin

@@ -141,6 +141,7 @@ type_is_valid_matrix_elements :: proc($T: typeid) -> bool ---
 
 
 type_is_named            :: proc($T: typeid) -> bool ---
 type_is_named            :: proc($T: typeid) -> bool ---
 type_is_pointer          :: proc($T: typeid) -> bool ---
 type_is_pointer          :: proc($T: typeid) -> bool ---
+type_is_multi_pointer    :: proc($T: typeid) -> bool ---
 type_is_array            :: proc($T: typeid) -> bool ---
 type_is_array            :: proc($T: typeid) -> bool ---
 type_is_enumerated_array :: proc($T: typeid) -> bool ---
 type_is_enumerated_array :: proc($T: typeid) -> bool ---
 type_is_slice            :: proc($T: typeid) -> bool ---
 type_is_slice            :: proc($T: typeid) -> bool ---

+ 2 - 2
core/sync/atomic.odin

@@ -6,8 +6,8 @@ cpu_relax :: intrinsics.cpu_relax
 
 
 /*
 /*
 Atomic_Memory_Order :: enum {
 Atomic_Memory_Order :: enum {
-	Relaxed = 0,
-	Consume = 1,
+	Relaxed = 0, // Unordered
+	Consume = 1, // Monotonic
 	Acquire = 2,
 	Acquire = 2,
 	Release = 3,
 	Release = 3,
 	Acq_Rel = 4,
 	Acq_Rel = 4,

+ 61 - 10
core/sync/extended.odin

@@ -16,8 +16,7 @@ wait_group_add :: proc(wg: ^Wait_Group, delta: int) {
 		return
 		return
 	}
 	}
 
 
-	mutex_lock(&wg.mutex)
-	defer mutex_unlock(&wg.mutex)
+	guard(&wg.mutex)
 
 
 	atomic_add(&wg.counter, delta)
 	atomic_add(&wg.counter, delta)
 	if wg.counter < 0 {
 	if wg.counter < 0 {
@@ -36,8 +35,7 @@ wait_group_done :: proc(wg: ^Wait_Group) {
 }
 }
 
 
 wait_group_wait :: proc(wg: ^Wait_Group) {
 wait_group_wait :: proc(wg: ^Wait_Group) {
-	mutex_lock(&wg.mutex)
-	defer mutex_unlock(&wg.mutex)
+	guard(&wg.mutex)
 
 
 	if wg.counter != 0 {
 	if wg.counter != 0 {
 		cond_wait(&wg.cond, &wg.mutex)
 		cond_wait(&wg.cond, &wg.mutex)
@@ -51,8 +49,7 @@ wait_group_wait_with_timeout :: proc(wg: ^Wait_Group, duration: time.Duration) -
 	if duration <= 0 {
 	if duration <= 0 {
 		return false
 		return false
 	}
 	}
-	mutex_lock(&wg.mutex)
-	defer mutex_unlock(&wg.mutex)
+	guard(&wg.mutex)
 
 
 	if wg.counter != 0 {
 	if wg.counter != 0 {
 		if !cond_wait_with_timeout(&wg.cond, &wg.mutex, duration) {
 		if !cond_wait_with_timeout(&wg.cond, &wg.mutex, duration) {
@@ -119,8 +116,7 @@ barrier_init :: proc(b: ^Barrier, thread_count: int) {
 // Block the current thread until all threads have rendezvoused
 // Block the current thread until all threads have rendezvoused
 // Barrier can be reused after all threads rendezvoused once, and can be used continuously
 // Barrier can be reused after all threads rendezvoused once, and can be used continuously
 barrier_wait :: proc(b: ^Barrier) -> (is_leader: bool) {
 barrier_wait :: proc(b: ^Barrier) -> (is_leader: bool) {
-	mutex_lock(&b.mutex)
-	defer mutex_unlock(&b.mutex)
+	guard(&b.mutex)
 	local_gen := b.generation_id
 	local_gen := b.generation_id
 	b.index += 1
 	b.index += 1
 	if b.index < b.thread_count {
 	if b.index < b.thread_count {
@@ -289,8 +285,7 @@ Once :: struct {
 once_do :: proc(o: ^Once, fn: proc()) {
 once_do :: proc(o: ^Once, fn: proc()) {
 	@(cold)
 	@(cold)
 	do_slow :: proc(o: ^Once, fn: proc()) {
 	do_slow :: proc(o: ^Once, fn: proc()) {
-		mutex_lock(&o.m)
-		defer mutex_unlock(&o.m)
+		guard(&o.m)
 		if !o.done {
 		if !o.done {
 			fn()
 			fn()
 			atomic_store_explicit(&o.done, true, .Release)
 			atomic_store_explicit(&o.done, true, .Release)
@@ -302,3 +297,59 @@ once_do :: proc(o: ^Once, fn: proc()) {
 		do_slow(o, fn)
 		do_slow(o, fn)
 	}
 	}
 }
 }
+
+
+
+// A Parker is an associated token which is initially not present:
+//     * The `park` procedure blocks the current thread unless or until the token
+//       is available, at which point the token is consumed.
+//     * The `park_with_timeout` procedures works the same as `park` but only
+//       blocks for the specified duration.
+//     * The `unpark` procedure automatically makes the token available if it
+//       was not already.
+Parker :: struct {
+	state: Futex,
+}
+
+// Blocks the current thread until the token is made available.
+//
+// Assumes this is only called by the thread that owns the Parker.
+park :: proc(p: ^Parker) {
+	EMPTY    :: 0
+	NOTIFIED :: 1
+	PARKED   :: max(u32)
+	if atomic_sub_explicit(&p.state, 1, .Acquire) == NOTIFIED {
+		return
+	}
+	for {
+		futex_wait(&p.state, PARKED)
+		if _, ok := atomic_compare_exchange_strong_explicit(&p.state, NOTIFIED, EMPTY, .Acquire, .Acquire); ok {
+			return
+		}
+	}
+}
+
+// Blocks the current thread until the token is made available, but only
+// for a limited duration.
+//
+// Assumes this is only called by the thread that owns the Parker
+park_with_timeout :: proc(p: ^Parker, duration: time.Duration) {
+	EMPTY    :: 0
+	NOTIFIED :: 1
+	PARKED   :: max(u32)
+	if atomic_sub_explicit(&p.state, 1, .Acquire) == NOTIFIED {
+		return
+	}
+	futex_wait_with_timeout(&p.state, PARKED, duration)
+	atomic_exchange_explicit(&p.state, EMPTY, .Acquire)
+}
+
+// Automatically makes thee token available if it was not already.
+unpark :: proc(p: ^Parker)  {
+	EMPTY    :: 0
+	NOTIFIED :: 1
+	PARKED   :: max(Futex)
+	if atomic_exchange_explicit(&p.state, NOTIFIED, .Release) == PARKED {
+		futex_signal(&p.state)
+	}
+}

+ 2 - 2
core/sync/primitives.odin

@@ -195,7 +195,7 @@ sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool {
 Futex :: distinct u32
 Futex :: distinct u32
 
 
 futex_wait :: proc(f: ^Futex, expected: u32) {
 futex_wait :: proc(f: ^Futex, expected: u32) {
-	if u32(atomic_load(f)) != expected {
+	if u32(atomic_load_explicit(f, .Acquire)) != expected {
 		return
 		return
 	}
 	}
 	
 	
@@ -204,7 +204,7 @@ futex_wait :: proc(f: ^Futex, expected: u32) {
 
 
 // returns true if the wait happened within the duration, false if it exceeded the time duration
 // returns true if the wait happened within the duration, false if it exceeded the time duration
 futex_wait_with_timeout :: proc(f: ^Futex, expected: u32, duration: time.Duration) -> bool {
 futex_wait_with_timeout :: proc(f: ^Futex, expected: u32, duration: time.Duration) -> bool {
-	if u32(atomic_load(f)) != expected {
+	if u32(atomic_load_explicit(f, .Acquire)) != expected {
 		return true
 		return true
 	}
 	}
 	if duration <= 0 {
 	if duration <= 0 {

+ 13 - 93
core/sync/primitives_atomic.odin

@@ -281,118 +281,39 @@ atomic_recursive_mutex_guard :: proc(m: ^Atomic_Recursive_Mutex) -> bool {
 
 
 
 
 
 
-
-@(private="file")
-Queue_Item :: struct {
-	next: ^Queue_Item,
-	futex: Futex,
-}
-
-@(private="file")
-queue_item_wait :: proc(item: ^Queue_Item) {
-	for atomic_load_explicit(&item.futex, .Acquire) == 0 {
-		futex_wait(&item.futex, 0)
-		cpu_relax()
-	}
-}
-@(private="file")
-queue_item_wait_with_timeout :: proc(item: ^Queue_Item, duration: time.Duration) -> bool {
-	start := time.tick_now()
-	for atomic_load_explicit(&item.futex, .Acquire) == 0 {
-		remaining := duration - time.tick_since(start)
-		if remaining < 0 {
-			return false
-		}
-		if !futex_wait_with_timeout(&item.futex, 0, remaining) {
-			return false
-		}
-		cpu_relax()
-	}
-	return true
-}
-@(private="file")
-queue_item_signal :: proc(item: ^Queue_Item) {
-	atomic_store_explicit(&item.futex, 1, .Release)
-	futex_signal(&item.futex)
-}
-
-
 // Atomic_Cond implements a condition variable, a rendezvous point for threads
 // Atomic_Cond implements a condition variable, a rendezvous point for threads
 // waiting for signalling the occurence of an event
 // waiting for signalling the occurence of an event
 //
 //
 // An Atomic_Cond must not be copied after first use
 // An Atomic_Cond must not be copied after first use
 Atomic_Cond :: struct {
 Atomic_Cond :: struct {
-	queue_mutex: Atomic_Mutex,
-	queue_head:  ^Queue_Item,
-	pending:     bool,
+	state: Futex,
 }
 }
 
 
 atomic_cond_wait :: proc(c: ^Atomic_Cond, m: ^Atomic_Mutex) {
 atomic_cond_wait :: proc(c: ^Atomic_Cond, m: ^Atomic_Mutex) {
-	waiter := &Queue_Item{}
-
-	atomic_mutex_lock(&c.queue_mutex)
-	waiter.next = c.queue_head
-	c.queue_head = waiter
+	state := u32(atomic_load_explicit(&c.state, .Relaxed))
+	unlock(m)
+	futex_wait(&c.state, state)
+	lock(m)
 
 
-	atomic_store(&c.pending, true)
-	atomic_mutex_unlock(&c.queue_mutex)
-
-	atomic_mutex_unlock(m)
-	queue_item_wait(waiter)
-	atomic_mutex_lock(m)
 }
 }
 
 
 atomic_cond_wait_with_timeout :: proc(c: ^Atomic_Cond, m: ^Atomic_Mutex, duration: time.Duration) -> (ok: bool) {
 atomic_cond_wait_with_timeout :: proc(c: ^Atomic_Cond, m: ^Atomic_Mutex, duration: time.Duration) -> (ok: bool) {
-	waiter := &Queue_Item{}
-
-	atomic_mutex_lock(&c.queue_mutex)
-	waiter.next = c.queue_head
-	c.queue_head = waiter
-
-	atomic_store(&c.pending, true)
-	atomic_mutex_unlock(&c.queue_mutex)
-
-	atomic_mutex_unlock(m)
-	ok = queue_item_wait_with_timeout(waiter, duration)
-	atomic_mutex_lock(m)
+	state := u32(atomic_load_explicit(&c.state, .Relaxed))
+	unlock(m)
+	ok = futex_wait_with_timeout(&c.state, state, duration)
+	lock(m)
 	return
 	return
 }
 }
 
 
 
 
 atomic_cond_signal :: proc(c: ^Atomic_Cond) {
 atomic_cond_signal :: proc(c: ^Atomic_Cond) {
-	if !atomic_load(&c.pending) {
-		return
-	}
-
-	atomic_mutex_lock(&c.queue_mutex)
-	waiter := c.queue_head
-	if c.queue_head != nil {
-		c.queue_head = c.queue_head.next
-	}
-	atomic_store(&c.pending, c.queue_head != nil)
-	atomic_mutex_unlock(&c.queue_mutex)
-
-	if waiter != nil {
-		queue_item_signal(waiter)
-	}
+	atomic_add_explicit(&c.state, 1, .Release)
+	futex_signal(&c.state)
 }
 }
 
 
 atomic_cond_broadcast :: proc(c: ^Atomic_Cond) {
 atomic_cond_broadcast :: proc(c: ^Atomic_Cond) {
-	if !atomic_load(&c.pending) {
-		return
-	}
-
-	atomic_store(&c.pending, false)
-
-	atomic_mutex_lock(&c.queue_mutex)
-	waiters := c.queue_head
-	c.queue_head = nil
-	atomic_mutex_unlock(&c.queue_mutex)
-
-	for waiters != nil {
-		queue_item_signal(waiters)
-		waiters = waiters.next
-	}
+	atomic_add_explicit(&c.state, 1, .Release)
+	futex_broadcast(&c.state)
 }
 }
 
 
 // When waited upon, blocks until the internal count is greater than zero, then subtracts one.
 // When waited upon, blocks until the internal count is greater than zero, then subtracts one.
@@ -430,7 +351,6 @@ atomic_sema_wait_with_timeout :: proc(s: ^Atomic_Sema, duration: time.Duration)
 		return false
 		return false
 	}
 	}
 	for {
 	for {
-
 		original_count := atomic_load_explicit(&s.count, .Relaxed)
 		original_count := atomic_load_explicit(&s.count, .Relaxed)
 		for start := time.tick_now(); original_count == 0; /**/ {
 		for start := time.tick_now(); original_count == 0; /**/ {
 			remaining := duration - time.tick_since(start)
 			remaining := duration - time.tick_since(start)

+ 0 - 39
core/sync/primitives_darwin.odin

@@ -3,7 +3,6 @@
 package sync
 package sync
 
 
 import "core:c"
 import "core:c"
-import "core:time"
 import "core:intrinsics"
 import "core:intrinsics"
 
 
 foreign import pthread "System.framework"
 foreign import pthread "System.framework"
@@ -17,41 +16,3 @@ _current_thread_id :: proc "contextless" () -> int {
 	pthread_threadid_np(nil, &tid)
 	pthread_threadid_np(nil, &tid)
 	return int(tid)
 	return int(tid)
 }
 }
-
-
-
-_Mutex :: struct {
-	mutex: Atomic_Mutex,
-}
-
-_mutex_lock :: proc(m: ^Mutex) {
-	atomic_mutex_lock(&m.impl.mutex)
-}
-
-_mutex_unlock :: proc(m: ^Mutex) {
-	atomic_mutex_unlock(&m.impl.mutex)
-}
-
-_mutex_try_lock :: proc(m: ^Mutex) -> bool {
-	return atomic_mutex_try_lock(&m.impl.mutex)
-}
-
-_Cond :: struct {
-	cond: Atomic_Cond,
-}
-
-_cond_wait :: proc(c: ^Cond, m: ^Mutex) {
-	atomic_cond_wait(&c.impl.cond, &m.impl.mutex)
-}
-
-_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool {
-	return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration)
-}
-
-_cond_signal :: proc(c: ^Cond) {
-	atomic_cond_signal(&c.impl.cond)
-}
-
-_cond_broadcast :: proc(c: ^Cond) {
-	atomic_cond_broadcast(&c.impl.cond)
-}

+ 0 - 37
core/sync/primitives_freebsd.odin

@@ -3,44 +3,7 @@
 package sync
 package sync
 
 
 import "core:os"
 import "core:os"
-import "core:time"
 
 
 _current_thread_id :: proc "contextless" () -> int {
 _current_thread_id :: proc "contextless" () -> int {
 	return os.current_thread_id()
 	return os.current_thread_id()
 }
 }
-
-_Mutex :: struct {
-	mutex: Atomic_Mutex,
-}
-
-_mutex_lock :: proc(m: ^Mutex) {
-	atomic_mutex_lock(&m.impl.mutex)
-}
-
-_mutex_unlock :: proc(m: ^Mutex) {
-	atomic_mutex_unlock(&m.impl.mutex)
-}
-
-_mutex_try_lock :: proc(m: ^Mutex) -> bool {
-	return atomic_mutex_try_lock(&m.impl.mutex)
-}
-
-_Cond :: struct {
-	cond: Atomic_Cond,
-}
-
-_cond_wait :: proc(c: ^Cond, m: ^Mutex) {
-	atomic_cond_wait(&c.impl.cond, &m.impl.mutex)
-}
-
-_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool {
-	return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration)
-}
-
-_cond_signal :: proc(c: ^Cond) {
-	atomic_cond_signal(&c.impl.cond)
-}
-
-_cond_broadcast :: proc(c: ^Cond) {
-	atomic_cond_broadcast(&c.impl.cond)
-}

+ 80 - 72
core/sync/primitives_internal.odin

@@ -1,99 +1,108 @@
 //+private
 //+private
 package sync
 package sync
 
 
-when #config(ODIN_SYNC_RECURSIVE_MUTEX_USE_FUTEX, true) {
-	_Recursive_Mutex :: struct {
-		owner:     Futex,
-		recursion: i32,
-	}
-
-	_recursive_mutex_lock :: proc(m: ^Recursive_Mutex) {
-		tid := Futex(current_thread_id())
-		for {
-			prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, 0, tid, .Acquire, .Acquire)
-			switch prev_owner {
-			case 0, tid:
-				m.impl.recursion += 1
-				// inside the lock
-				return
-			}
-
-			futex_wait(&m.impl.owner, u32(prev_owner))
-		}
-	}
+import "core:time"
 
 
-	_recursive_mutex_unlock :: proc(m: ^Recursive_Mutex) {
-		m.impl.recursion -= 1
-		if m.impl.recursion != 0 {
-			return
-		}
-		atomic_exchange_explicit(&m.impl.owner, 0, .Release)
-		
-		futex_signal(&m.impl.owner)
-		// outside the lock
+_Sema :: struct {
+	atomic: Atomic_Sema,
+}
 
 
-	}
+_sema_post :: proc(s: ^Sema, count := 1) {
+	atomic_sema_post(&s.impl.atomic, count)
+}
 
 
-	_recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool {
-		tid := Futex(current_thread_id())
+_sema_wait :: proc(s: ^Sema) {
+	atomic_sema_wait(&s.impl.atomic)
+}
+
+_sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool {
+	return atomic_sema_wait_with_timeout(&s.impl.atomic, duration)
+}
+
+
+_Recursive_Mutex :: struct {
+	owner:     Futex,
+	recursion: i32,
+}
+
+_recursive_mutex_lock :: proc(m: ^Recursive_Mutex) {
+	tid := Futex(current_thread_id())
+	for {
 		prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, 0, tid, .Acquire, .Acquire)
 		prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, 0, tid, .Acquire, .Acquire)
 		switch prev_owner {
 		switch prev_owner {
 		case 0, tid:
 		case 0, tid:
 			m.impl.recursion += 1
 			m.impl.recursion += 1
 			// inside the lock
 			// inside the lock
-			return true
+			return
 		}
 		}
-		return false
-	}
-} else {
-	_Recursive_Mutex :: struct {
-		owner:     int,
-		recursion: int,
-		mutex:     Mutex,
+
+		futex_wait(&m.impl.owner, u32(prev_owner))
 	}
 	}
+}
 
 
-	_recursive_mutex_lock :: proc(m: ^Recursive_Mutex) {
-		tid := current_thread_id()
-		if tid != m.impl.owner {
-			mutex_lock(&m.impl.mutex)
-		}
-		// inside the lock
-		m.impl.owner = tid
-		m.impl.recursion += 1
+_recursive_mutex_unlock :: proc(m: ^Recursive_Mutex) {
+	m.impl.recursion -= 1
+	if m.impl.recursion != 0 {
+		return
 	}
 	}
+	atomic_exchange_explicit(&m.impl.owner, 0, .Release)
 
 
-	_recursive_mutex_unlock :: proc(m: ^Recursive_Mutex) {
-		tid := current_thread_id()
-		assert(tid == m.impl.owner)
-		m.impl.recursion -= 1
-		recursion := m.impl.recursion
-		if recursion == 0 {
-			m.impl.owner = 0
-		}
-		if recursion == 0 {
-			mutex_unlock(&m.impl.mutex)
-		}
-		// outside the lock
+	futex_signal(&m.impl.owner)
+	// outside the lock
 
 
-	}
+}
 
 
-	_recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool {
-		tid := current_thread_id()
-		if m.impl.owner == tid {
-			return mutex_try_lock(&m.impl.mutex)
-		}
-		if !mutex_try_lock(&m.impl.mutex) {
-			return false
-		}
-		// inside the lock
-		m.impl.owner = tid
+_recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool {
+	tid := Futex(current_thread_id())
+	prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, 0, tid, .Acquire, .Acquire)
+	switch prev_owner {
+	case 0, tid:
 		m.impl.recursion += 1
 		m.impl.recursion += 1
+		// inside the lock
 		return true
 		return true
 	}
 	}
+	return false
 }
 }
 
 
 
 
 when ODIN_OS != .Windows {
 when ODIN_OS != .Windows {
+	_Mutex :: struct {
+		mutex: Atomic_Mutex,
+	}
+
+	_mutex_lock :: proc(m: ^Mutex) {
+		atomic_mutex_lock(&m.impl.mutex)
+	}
+
+	_mutex_unlock :: proc(m: ^Mutex) {
+		atomic_mutex_unlock(&m.impl.mutex)
+	}
+
+	_mutex_try_lock :: proc(m: ^Mutex) -> bool {
+		return atomic_mutex_try_lock(&m.impl.mutex)
+	}
+
+	_Cond :: struct {
+		cond: Atomic_Cond,
+	}
+
+	_cond_wait :: proc(c: ^Cond, m: ^Mutex) {
+		atomic_cond_wait(&c.impl.cond, &m.impl.mutex)
+	}
+
+	_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool {
+		return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration)
+	}
+
+	_cond_signal :: proc(c: ^Cond) {
+		atomic_cond_signal(&c.impl.cond)
+	}
+
+	_cond_broadcast :: proc(c: ^Cond) {
+		atomic_cond_broadcast(&c.impl.cond)
+	}
+
+
 	_RW_Mutex :: struct {
 	_RW_Mutex :: struct {
 		mutex: Atomic_RW_Mutex,
 		mutex: Atomic_RW_Mutex,
 	}
 	}
@@ -121,5 +130,4 @@ when ODIN_OS != .Windows {
 	_rw_mutex_try_shared_lock :: proc(rw: ^RW_Mutex) -> bool {
 	_rw_mutex_try_shared_lock :: proc(rw: ^RW_Mutex) -> bool {
 		return atomic_rw_mutex_try_shared_lock(&rw.impl.mutex)
 		return atomic_rw_mutex_try_shared_lock(&rw.impl.mutex)
 	}
 	}
-
 }
 }

+ 0 - 38
core/sync/primitives_linux.odin

@@ -3,45 +3,7 @@
 package sync
 package sync
 
 
 import "core:sys/unix"
 import "core:sys/unix"
-import "core:time"
 
 
 _current_thread_id :: proc "contextless" () -> int {
 _current_thread_id :: proc "contextless" () -> int {
 	return unix.sys_gettid()
 	return unix.sys_gettid()
 }
 }
-
-
-_Mutex :: struct {
-	mutex: Atomic_Mutex,
-}
-
-_mutex_lock :: proc(m: ^Mutex) {
-	atomic_mutex_lock(&m.impl.mutex)
-}
-
-_mutex_unlock :: proc(m: ^Mutex) {
-	atomic_mutex_unlock(&m.impl.mutex)
-}
-
-_mutex_try_lock :: proc(m: ^Mutex) -> bool {
-	return atomic_mutex_try_lock(&m.impl.mutex)
-}
-
-_Cond :: struct {
-	cond: Atomic_Cond,
-}
-
-_cond_wait :: proc(c: ^Cond, m: ^Mutex) {
-	atomic_cond_wait(&c.impl.cond, &m.impl.mutex)
-}
-
-_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool {
-	return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration)
-}
-
-_cond_signal :: proc(c: ^Cond) {
-	atomic_cond_signal(&c.impl.cond)
-}
-
-_cond_broadcast :: proc(c: ^Cond) {
-	atomic_cond_broadcast(&c.impl.cond)
-}

+ 0 - 37
core/sync/primitives_openbsd.odin

@@ -3,44 +3,7 @@
 package sync
 package sync
 
 
 import "core:os"
 import "core:os"
-import "core:time"
 
 
 _current_thread_id :: proc "contextless" () -> int {
 _current_thread_id :: proc "contextless" () -> int {
 	return os.current_thread_id()
 	return os.current_thread_id()
 }
 }
-
-_Mutex :: struct {
-	mutex: Atomic_Mutex,
-}
-
-_mutex_lock :: proc(m: ^Mutex) {
-	atomic_mutex_lock(&m.impl.mutex)
-}
-
-_mutex_unlock :: proc(m: ^Mutex) {
-	atomic_mutex_unlock(&m.impl.mutex)
-}
-
-_mutex_try_lock :: proc(m: ^Mutex) -> bool {
-	return atomic_mutex_try_lock(&m.impl.mutex)
-}
-
-_Cond :: struct {
-	cond: Atomic_Cond,
-}
-
-_cond_wait :: proc(c: ^Cond, m: ^Mutex) {
-	atomic_cond_wait(&c.impl.cond, &m.impl.mutex)
-}
-
-_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool {
-	return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration)
-}
-
-_cond_signal :: proc(c: ^Cond) {
-	atomic_cond_signal(&c.impl.cond)
-}
-
-_cond_broadcast :: proc(c: ^Cond) {
-	atomic_cond_broadcast(&c.impl.cond)
-}

+ 0 - 39
core/sync/sema_internal.odin

@@ -1,39 +0,0 @@
-//+private
-package sync
-
-import "core:time"
-
-
-when #config(ODIN_SYNC_SEMA_USE_FUTEX, true) {
-	_Sema :: struct {
-		atomic: Atomic_Sema,
-	}
-
-	_sema_post :: proc(s: ^Sema, count := 1) {
-		atomic_sema_post(&s.impl.atomic, count)
-	}
-
-	_sema_wait :: proc(s: ^Sema) {
-		atomic_sema_wait(&s.impl.atomic)
-	}
-
-	_sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool {
-		return atomic_sema_wait_with_timeout(&s.impl.atomic, duration)
-	}
-} else {
-	_Sema :: struct {
-		wg: Wait_Group,
-	}
-
-	_sema_post :: proc(s: ^Sema, count := 1) {
-		wait_group_add(&s.impl.wg, count)
-	}
-
-	_sema_wait :: proc(s: ^Sema) {
-		wait_group_wait(&s.impl.wg)
-	}
-
-	_sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool {
-		return wait_group_wait_with_timeout(&s.impl.wg, duration)
-	}
-}

+ 8 - 0
core/sys/windows/gdi32.odin

@@ -62,5 +62,13 @@ foreign gdi32 {
 	ChoosePixelFormat :: proc(hdc: HDC, ppfd: ^PIXELFORMATDESCRIPTOR) -> c_int ---
 	ChoosePixelFormat :: proc(hdc: HDC, ppfd: ^PIXELFORMATDESCRIPTOR) -> c_int ---
 	SwapBuffers :: proc(HDC) -> BOOL ---
 	SwapBuffers :: proc(HDC) -> BOOL ---
 
 
+	SetDCBrushColor :: proc(hdc: HDC, color: COLORREF) -> COLORREF ---
+	GetDCBrushColor :: proc(hdc: HDC) -> COLORREF ---
 	PatBlt :: proc(hdc: HDC, x, y, w, h: c_int, rop: DWORD) -> BOOL ---
 	PatBlt :: proc(hdc: HDC, x, y, w, h: c_int, rop: DWORD) -> BOOL ---
 }
 }
+
+// Windows colors are packed as ABGR
+RGB :: #force_inline proc "contextless" (r, g, b: u8) -> COLORREF {
+	res: [4]u8 = {0, b, g, r}
+	return transmute(COLORREF)res
+}

+ 2 - 0
core/sys/windows/types.odin

@@ -55,6 +55,8 @@ UINT_PTR :: uintptr
 ULONG :: c_ulong
 ULONG :: c_ulong
 UCHAR :: BYTE
 UCHAR :: BYTE
 NTSTATUS :: c.long
 NTSTATUS :: c.long
+COLORREF :: DWORD // Windows colors are packed as ABGR
+LPCOLORREF :: ^COLORREF
 LPARAM :: LONG_PTR
 LPARAM :: LONG_PTR
 WPARAM :: UINT_PTR
 WPARAM :: UINT_PTR
 LRESULT :: LONG_PTR
 LRESULT :: LONG_PTR

+ 1 - 1
tests/core/encoding/xml/test_core_xml.odin

@@ -295,7 +295,7 @@ run_tests :: proc(t: ^testing.T) {
 		path := test_file_path(test.filename)
 		path := test_file_path(test.filename)
 		log(t, fmt.tprintf("Trying to parse %v", path))
 		log(t, fmt.tprintf("Trying to parse %v", path))
 
 
-		doc, err := xml.parse(path, test.options, Silent)
+		doc, err := xml.load_from_file(path, test.options, Silent)
 		defer xml.destroy(doc)
 		defer xml.destroy(doc)
 
 
 		tree_string := doc_to_string(doc)
 		tree_string := doc_to_string(doc)

+ 4 - 4
vendor/OpenGL/impl.odin

@@ -199,7 +199,7 @@ load_1_1 :: proc(set_proc_address: Set_Proc_Address_Type) {
 
 
 // VERSION_1_2
 // VERSION_1_2
 impl_DrawRangeElements: proc "c" (mode: u32, start: u32, end: u32, count: i32, type: u32, indices: rawptr)
 impl_DrawRangeElements: proc "c" (mode: u32, start: u32, end: u32, count: i32, type: u32, indices: rawptr)
-impl_TexImage3D:        proc "c" (target: u32, level: i32, internalformat: i32, width: i32, height: i32, depth: i32, border: i32, format: u32, type: u32, pixels: rawptr)
+impl_TexImage3D:        proc "c" (target: u32, level: i32, internalformat: i32, width: i32, height: i32, depth: i32, border: i32, format: u32, type: u32, data: rawptr)
 impl_TexSubImage3D:     proc "c" (target: u32, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, width: i32, height: i32, depth: i32, format: u32, type: u32, pixels: rawptr)
 impl_TexSubImage3D:     proc "c" (target: u32, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, width: i32, height: i32, depth: i32, format: u32, type: u32, pixels: rawptr)
 impl_CopyTexSubImage3D: proc "c" (target: u32, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, x: i32, y: i32, width: i32, height: i32)
 impl_CopyTexSubImage3D: proc "c" (target: u32, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, x: i32, y: i32, width: i32, height: i32)
 
 
@@ -1250,14 +1250,14 @@ impl_VertexAttribLFormat:             proc "c" (attribindex: u32, size: i32, typ
 impl_VertexAttribBinding:             proc "c" (attribindex: u32, bindingindex: u32)
 impl_VertexAttribBinding:             proc "c" (attribindex: u32, bindingindex: u32)
 impl_VertexBindingDivisor:            proc "c" (bindingindex: u32, divisor: u32)
 impl_VertexBindingDivisor:            proc "c" (bindingindex: u32, divisor: u32)
 impl_DebugMessageControl:             proc "c" (source: u32, type: u32, severity: u32, count: i32, ids: [^]u32, enabled: bool)
 impl_DebugMessageControl:             proc "c" (source: u32, type: u32, severity: u32, count: i32, ids: [^]u32, enabled: bool)
-impl_DebugMessageInsert:              proc "c" (source: u32, type: u32, id: u32, severity: u32, length: i32, buf: [^]u8)
+impl_DebugMessageInsert:              proc "c" (source: u32, type: u32, id: u32, severity: u32, length: i32, message: cstring)
 impl_DebugMessageCallback:            proc "c" (callback: debug_proc_t, userParam: rawptr)
 impl_DebugMessageCallback:            proc "c" (callback: debug_proc_t, userParam: rawptr)
 impl_GetDebugMessageLog:              proc "c" (count: u32, bufSize: i32, sources: [^]u32, types: [^]u32, ids: [^]u32, severities: [^]u32, lengths: [^]i32, messageLog: [^]u8) -> u32
 impl_GetDebugMessageLog:              proc "c" (count: u32, bufSize: i32, sources: [^]u32, types: [^]u32, ids: [^]u32, severities: [^]u32, lengths: [^]i32, messageLog: [^]u8) -> u32
 impl_PushDebugGroup:                  proc "c" (source: u32, id: u32, length: i32, message: cstring)
 impl_PushDebugGroup:                  proc "c" (source: u32, id: u32, length: i32, message: cstring)
 impl_PopDebugGroup:                   proc "c" ()
 impl_PopDebugGroup:                   proc "c" ()
-impl_ObjectLabel:                     proc "c" (identifier: u32, name: u32, length: i32, label: [^]u8)
+impl_ObjectLabel:                     proc "c" (identifier: u32, name: u32, length: i32, label: cstring)
 impl_GetObjectLabel:                  proc "c" (identifier: u32, name: u32, bufSize: i32, length: ^i32, label: [^]u8)
 impl_GetObjectLabel:                  proc "c" (identifier: u32, name: u32, bufSize: i32, length: ^i32, label: [^]u8)
-impl_ObjectPtrLabel:                  proc "c" (ptr: rawptr, length: i32, label: [^]u8)
+impl_ObjectPtrLabel:                  proc "c" (ptr: rawptr, length: i32, label: cstring)
 impl_GetObjectPtrLabel:               proc "c" (ptr: rawptr, bufSize: i32, length: ^i32, label: [^]u8)
 impl_GetObjectPtrLabel:               proc "c" (ptr: rawptr, bufSize: i32, length: ^i32, label: [^]u8)
 
 
 load_4_3 :: proc(set_proc_address: Set_Proc_Address_Type) {
 load_4_3 :: proc(set_proc_address: Set_Proc_Address_Type) {

+ 7 - 7
vendor/OpenGL/wrappers.odin

@@ -70,7 +70,7 @@ when !ODIN_DEBUG {
 
 
 	// VERSION_1_2
 	// VERSION_1_2
 	DrawRangeElements :: proc "c" (mode, start, end: u32, count: i32, type: u32, indices: rawptr)                                               { impl_DrawRangeElements(mode, start, end, count, type, indices)                                           }
 	DrawRangeElements :: proc "c" (mode, start, end: u32, count: i32, type: u32, indices: rawptr)                                               { impl_DrawRangeElements(mode, start, end, count, type, indices)                                           }
-	TexImage3D        :: proc "c" (target: u32, level, internalformat, width, height, depth, border: i32, format, type: u32, pixels: rawptr)    { impl_TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels)       }
+	TexImage3D        :: proc "c" (target: u32, level, internalformat, width, height, depth, border: i32, format, type: u32, data: rawptr)    { impl_TexImage3D(target, level, internalformat, width, height, depth, border, format, type, data)       }
 	TexSubImage3D     :: proc "c" (target: u32, level, xoffset, yoffset, zoffset, width, height, depth: i32, format, type: u32, pixels: rawptr) { impl_TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) }
 	TexSubImage3D     :: proc "c" (target: u32, level, xoffset, yoffset, zoffset, width, height, depth: i32, format, type: u32, pixels: rawptr) { impl_TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) }
 	CopyTexSubImage3D :: proc "c" (target: u32, level, xoffset, yoffset, zoffset, x, y, width, height: i32)                                     { impl_CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height)                    }
 	CopyTexSubImage3D :: proc "c" (target: u32, level, xoffset, yoffset, zoffset, x, y, width, height: i32)                                     { impl_CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height)                    }
 
 
@@ -589,14 +589,14 @@ when !ODIN_DEBUG {
 	VertexAttribBinding             :: proc "c" (attribindex: u32, bindingindex: u32)                                                                                                                                                                      {        impl_VertexAttribBinding(attribindex, bindingindex)                                                                                                              }
 	VertexAttribBinding             :: proc "c" (attribindex: u32, bindingindex: u32)                                                                                                                                                                      {        impl_VertexAttribBinding(attribindex, bindingindex)                                                                                                              }
 	VertexBindingDivisor            :: proc "c" (bindingindex: u32, divisor: u32)                                                                                                                                                                          {        impl_VertexBindingDivisor(bindingindex, divisor)                                                                                                                 }
 	VertexBindingDivisor            :: proc "c" (bindingindex: u32, divisor: u32)                                                                                                                                                                          {        impl_VertexBindingDivisor(bindingindex, divisor)                                                                                                                 }
 	DebugMessageControl             :: proc "c" (source: u32, type: u32, severity: u32, count: i32, ids: [^]u32, enabled: bool)                                                                                                                            {        impl_DebugMessageControl(source, type, severity, count, ids, enabled)                                                                                           }
 	DebugMessageControl             :: proc "c" (source: u32, type: u32, severity: u32, count: i32, ids: [^]u32, enabled: bool)                                                                                                                            {        impl_DebugMessageControl(source, type, severity, count, ids, enabled)                                                                                           }
-	DebugMessageInsert              :: proc "c" (source: u32, type: u32, id: u32, severity: u32, length: i32, buf: ^u8)                                                                                                                                    {        impl_DebugMessageInsert(source, type, id, severity, length, buf)                                                                                                }
+	DebugMessageInsert              :: proc "c" (source: u32, type: u32, id: u32, severity: u32, length: i32, message: cstring)                                                                                                                                    {        impl_DebugMessageInsert(source, type, id, severity, length, message)                                                                                                }
 	DebugMessageCallback            :: proc "c" (callback: debug_proc_t, userParam: rawptr)                                                                                                                                                                {        impl_DebugMessageCallback(callback, userParam)                                                                                                                   }
 	DebugMessageCallback            :: proc "c" (callback: debug_proc_t, userParam: rawptr)                                                                                                                                                                {        impl_DebugMessageCallback(callback, userParam)                                                                                                                   }
 	GetDebugMessageLog              :: proc "c" (count: u32, bufSize: i32, sources: [^]u32, types: [^]u32, ids: [^]u32, severities: [^]u32, lengths: [^]i32, messageLog: [^]u8) -> u32                                                                     { ret := impl_GetDebugMessageLog(count, bufSize, sources, types, ids, severities, lengths, messageLog);                                                        return ret }
 	GetDebugMessageLog              :: proc "c" (count: u32, bufSize: i32, sources: [^]u32, types: [^]u32, ids: [^]u32, severities: [^]u32, lengths: [^]i32, messageLog: [^]u8) -> u32                                                                     { ret := impl_GetDebugMessageLog(count, bufSize, sources, types, ids, severities, lengths, messageLog);                                                        return ret }
 	PushDebugGroup                  :: proc "c" (source: u32, id: u32, length: i32, message: cstring)                                                                                                                                                      {        impl_PushDebugGroup(source, id, length, message)                                                                                                                 }
 	PushDebugGroup                  :: proc "c" (source: u32, id: u32, length: i32, message: cstring)                                                                                                                                                      {        impl_PushDebugGroup(source, id, length, message)                                                                                                                 }
 	PopDebugGroup                   :: proc "c" ()                                                                                                                                                                                                         {        impl_PopDebugGroup()                                                                                                                                             }
 	PopDebugGroup                   :: proc "c" ()                                                                                                                                                                                                         {        impl_PopDebugGroup()                                                                                                                                             }
-	ObjectLabel                     :: proc "c" (identifier: u32, name: u32, length: i32, label: [^]u8)                                                                                                                                                    {        impl_ObjectLabel(identifier, name, length, label)                                                                                                                }
+	ObjectLabel                     :: proc "c" (identifier: u32, name: u32, length: i32, label: cstring)                                                                                                                                                    {        impl_ObjectLabel(identifier, name, length, label)                                                                                                                }
 	GetObjectLabel                  :: proc "c" (identifier: u32, name: u32, bufSize: i32, length: ^i32, label: [^]u8)                                                                                                                                     {        impl_GetObjectLabel(identifier, name, bufSize, length, label)                                                                                                    }
 	GetObjectLabel                  :: proc "c" (identifier: u32, name: u32, bufSize: i32, length: ^i32, label: [^]u8)                                                                                                                                     {        impl_GetObjectLabel(identifier, name, bufSize, length, label)                                                                                                    }
-	ObjectPtrLabel                  :: proc "c" (ptr: rawptr, length: i32, label: [^]u8)                                                                                                                                                                   {        impl_ObjectPtrLabel(ptr, length, label)                                                                                                                          }
+	ObjectPtrLabel                  :: proc "c" (ptr: rawptr, length: i32, label: cstring)                                                                                                                                                                   {        impl_ObjectPtrLabel(ptr, length, label)                                                                                                                          }
 	GetObjectPtrLabel               :: proc "c" (ptr: rawptr, bufSize: i32, length: ^i32, label: [^]u8)                                                                                                                                                    {        impl_GetObjectPtrLabel(ptr, bufSize, length, label)                                                                                                              }
 	GetObjectPtrLabel               :: proc "c" (ptr: rawptr, bufSize: i32, length: ^i32, label: [^]u8)                                                                                                                                                    {        impl_GetObjectPtrLabel(ptr, bufSize, length, label)                                                                                                              }
 
 
 	// VERSION_4_4
 	// VERSION_4_4
@@ -1389,14 +1389,14 @@ when !ODIN_DEBUG {
 	VertexAttribBinding             :: proc "c" (attribindex: u32, bindingindex: u32, loc := #caller_location)                                                                                                                                                                      {        impl_VertexAttribBinding(attribindex, bindingindex);                                                                                                  debug_helper(loc, 0, attribindex, bindingindex)                                                                                                                 }
 	VertexAttribBinding             :: proc "c" (attribindex: u32, bindingindex: u32, loc := #caller_location)                                                                                                                                                                      {        impl_VertexAttribBinding(attribindex, bindingindex);                                                                                                  debug_helper(loc, 0, attribindex, bindingindex)                                                                                                                 }
 	VertexBindingDivisor            :: proc "c" (bindingindex: u32, divisor: u32, loc := #caller_location)                                                                                                                                                                          {        impl_VertexBindingDivisor(bindingindex, divisor);                                                                                                     debug_helper(loc, 0, bindingindex, divisor)                                                                                                                     }
 	VertexBindingDivisor            :: proc "c" (bindingindex: u32, divisor: u32, loc := #caller_location)                                                                                                                                                                          {        impl_VertexBindingDivisor(bindingindex, divisor);                                                                                                     debug_helper(loc, 0, bindingindex, divisor)                                                                                                                     }
 	DebugMessageControl             :: proc "c" (source: u32, type: u32, severity: u32, count: i32, ids: [^]u32, enabled: bool, loc := #caller_location)                                                                                                                              {        impl_DebugMessageControl(source, type, severity, count, ids, enabled);                                                                               debug_helper(loc, 0, source, type, severity, count, ids, enabled)                                                                                              }
 	DebugMessageControl             :: proc "c" (source: u32, type: u32, severity: u32, count: i32, ids: [^]u32, enabled: bool, loc := #caller_location)                                                                                                                              {        impl_DebugMessageControl(source, type, severity, count, ids, enabled);                                                                               debug_helper(loc, 0, source, type, severity, count, ids, enabled)                                                                                              }
-	DebugMessageInsert              :: proc "c" (source: u32, type: u32, id: u32, severity: u32, length: i32, buf: ^u8, loc := #caller_location)                                                                                                                                    {        impl_DebugMessageInsert(source, type, id, severity, length, buf);                                                                                    debug_helper(loc, 0, source, type, id, severity, length, buf)                                                                                                  }
+	DebugMessageInsert              :: proc "c" (source: u32, type: u32, id: u32, severity: u32, length: i32, message: cstring, loc := #caller_location)                                                                                                                                    {        impl_DebugMessageInsert(source, type, id, severity, length, message);                                                                                    debug_helper(loc, 0, source, type, id, severity, length, message)                                                                                                  }
 	DebugMessageCallback            :: proc "c" (callback: debug_proc_t, userParam: rawptr, loc := #caller_location)                                                                                                                                                                {        impl_DebugMessageCallback(callback, userParam);                                                                                                       debug_helper(loc, 0, callback, userParam)                                                                                                                       }
 	DebugMessageCallback            :: proc "c" (callback: debug_proc_t, userParam: rawptr, loc := #caller_location)                                                                                                                                                                {        impl_DebugMessageCallback(callback, userParam);                                                                                                       debug_helper(loc, 0, callback, userParam)                                                                                                                       }
 	GetDebugMessageLog              :: proc "c" (count: u32, bufSize: i32, sources: [^]u32, types: [^]u32, ids: [^]u32, severities: [^]u32, lengths: [^]i32, messageLog: [^]u8, loc := #caller_location) -> u32                                                                     { ret := impl_GetDebugMessageLog(count, bufSize, sources, types, ids, severities, lengths, messageLog);                                                        debug_helper(loc, 1, ret, count, bufSize, sources, types, ids, severities, lengths, messageLog);                                                     return ret }
 	GetDebugMessageLog              :: proc "c" (count: u32, bufSize: i32, sources: [^]u32, types: [^]u32, ids: [^]u32, severities: [^]u32, lengths: [^]i32, messageLog: [^]u8, loc := #caller_location) -> u32                                                                     { ret := impl_GetDebugMessageLog(count, bufSize, sources, types, ids, severities, lengths, messageLog);                                                        debug_helper(loc, 1, ret, count, bufSize, sources, types, ids, severities, lengths, messageLog);                                                     return ret }
 	PushDebugGroup                  :: proc "c" (source: u32, id: u32, length: i32, message: cstring, loc := #caller_location)                                                                                                                                                      {        impl_PushDebugGroup(source, id, length, message);                                                                                                     debug_helper(loc, 0, source, id, length, message)                                                                                                               }
 	PushDebugGroup                  :: proc "c" (source: u32, id: u32, length: i32, message: cstring, loc := #caller_location)                                                                                                                                                      {        impl_PushDebugGroup(source, id, length, message);                                                                                                     debug_helper(loc, 0, source, id, length, message)                                                                                                               }
 	PopDebugGroup                   :: proc "c" (loc := #caller_location)                                                                                                                                                                                                           {        impl_PopDebugGroup();                                                                                                                                 debug_helper(loc, 0)                                                                                                                                            }
 	PopDebugGroup                   :: proc "c" (loc := #caller_location)                                                                                                                                                                                                           {        impl_PopDebugGroup();                                                                                                                                 debug_helper(loc, 0)                                                                                                                                            }
-	ObjectLabel                     :: proc "c" (identifier: u32, name: u32, length: i32, label: [^]u8, loc := #caller_location)                                                                                                                                                    {        impl_ObjectLabel(identifier, name, length, label);                                                                                                    debug_helper(loc, 0, identifier, name, length, label)                                                                                                           }
+	ObjectLabel                     :: proc "c" (identifier: u32, name: u32, length: i32, label: cstring, loc := #caller_location)                                                                                                                                                    {        impl_ObjectLabel(identifier, name, length, label);                                                                                                    debug_helper(loc, 0, identifier, name, length, label)                                                                                                           }
 	GetObjectLabel                  :: proc "c" (identifier: u32, name: u32, bufSize: i32, length: ^i32, label: [^]u8, loc := #caller_location)                                                                                                                                     {        impl_GetObjectLabel(identifier, name, bufSize, length, label);                                                                                        debug_helper(loc, 0, identifier, name, bufSize, length, label)                                                                                                  }
 	GetObjectLabel                  :: proc "c" (identifier: u32, name: u32, bufSize: i32, length: ^i32, label: [^]u8, loc := #caller_location)                                                                                                                                     {        impl_GetObjectLabel(identifier, name, bufSize, length, label);                                                                                        debug_helper(loc, 0, identifier, name, bufSize, length, label)                                                                                                  }
-	ObjectPtrLabel                  :: proc "c" (ptr: rawptr, length: i32, label: [^]u8, loc := #caller_location)                                                                                                                                                                   {        impl_ObjectPtrLabel(ptr, length, label);                                                                                                              debug_helper(loc, 0, ptr, length, label)                                                                                                                        }
+	ObjectPtrLabel                  :: proc "c" (ptr: rawptr, length: i32, label: cstring, loc := #caller_location)                                                                                                                                                                   {        impl_ObjectPtrLabel(ptr, length, label);                                                                                                              debug_helper(loc, 0, ptr, length, label)                                                                                                                        }
 	GetObjectPtrLabel               :: proc "c" (ptr: rawptr, bufSize: i32, length: ^i32, label: [^]u8, loc := #caller_location)                                                                                                                                                    {        impl_GetObjectPtrLabel(ptr, bufSize, length, label);                                                                                                  debug_helper(loc, 0, ptr, bufSize, length, label)                                                                                                               }
 	GetObjectPtrLabel               :: proc "c" (ptr: rawptr, bufSize: i32, length: ^i32, label: [^]u8, loc := #caller_location)                                                                                                                                                    {        impl_GetObjectPtrLabel(ptr, bufSize, length, label);                                                                                                  debug_helper(loc, 0, ptr, bufSize, length, label)                                                                                                               }
 
 
 	// VERSION_4_4
 	// VERSION_4_4