瀏覽代碼

Make `sync` calls `contextless` where possible

gingerBill 2 年之前
父節點
當前提交
20943a81c1

+ 28 - 28
core/sync/extended.odin

@@ -11,7 +11,7 @@ Wait_Group :: struct {
 	cond:    Cond,
 	cond:    Cond,
 }
 }
 
 
-wait_group_add :: proc(wg: ^Wait_Group, delta: int) {
+wait_group_add :: proc "contextless" (wg: ^Wait_Group, delta: int) {
 	if delta == 0 {
 	if delta == 0 {
 		return
 		return
 	}
 	}
@@ -20,32 +20,32 @@ wait_group_add :: proc(wg: ^Wait_Group, delta: int) {
 
 
 	atomic_add(&wg.counter, delta)
 	atomic_add(&wg.counter, delta)
 	if wg.counter < 0 {
 	if wg.counter < 0 {
-		panic("sync.Wait_Group negative counter")
+		_panic("sync.Wait_Group negative counter")
 	}
 	}
 	if wg.counter == 0 {
 	if wg.counter == 0 {
 		cond_broadcast(&wg.cond)
 		cond_broadcast(&wg.cond)
 		if wg.counter != 0 {
 		if wg.counter != 0 {
-			panic("sync.Wait_Group misuse: sync.wait_group_add called concurrently with sync.wait_group_wait")
+			_panic("sync.Wait_Group misuse: sync.wait_group_add called concurrently with sync.wait_group_wait")
 		}
 		}
 	}
 	}
 }
 }
 
 
-wait_group_done :: proc(wg: ^Wait_Group) {
+wait_group_done :: proc "contextless" (wg: ^Wait_Group) {
 	wait_group_add(wg, -1)
 	wait_group_add(wg, -1)
 }
 }
 
 
-wait_group_wait :: proc(wg: ^Wait_Group) {
+wait_group_wait :: proc "contextless" (wg: ^Wait_Group) {
 	guard(&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)
 		if wg.counter != 0 {
 		if wg.counter != 0 {
-			panic("sync.Wait_Group misuse: sync.wait_group_add called concurrently with sync.wait_group_wait")
+			_panic("sync.Wait_Group misuse: sync.wait_group_add called concurrently with sync.wait_group_wait")
 		}
 		}
 	}
 	}
 }
 }
 
 
-wait_group_wait_with_timeout :: proc(wg: ^Wait_Group, duration: time.Duration) -> bool {
+wait_group_wait_with_timeout :: proc "contextless" (wg: ^Wait_Group, duration: time.Duration) -> bool {
 	if duration <= 0 {
 	if duration <= 0 {
 		return false
 		return false
 	}
 	}
@@ -56,7 +56,7 @@ wait_group_wait_with_timeout :: proc(wg: ^Wait_Group, duration: time.Duration) -
 			return false
 			return false
 		}
 		}
 		if wg.counter != 0 {
 		if wg.counter != 0 {
-			panic("sync.Wait_Group misuse: sync.wait_group_add called concurrently with sync.wait_group_wait")
+			_panic("sync.Wait_Group misuse: sync.wait_group_add called concurrently with sync.wait_group_wait")
 		}
 		}
 	}
 	}
 	return true
 	return true
@@ -76,7 +76,7 @@ Example:
 
 
 	barrier := &sync.Barrier{}
 	barrier := &sync.Barrier{}
 
 
-	main :: proc() {
+	main :: proc "contextless" () {
 		fmt.println("Start")
 		fmt.println("Start")
 
 
 		THREAD_COUNT :: 4
 		THREAD_COUNT :: 4
@@ -107,7 +107,7 @@ Barrier :: struct {
 	thread_count:  int,
 	thread_count:  int,
 }
 }
 
 
-barrier_init :: proc(b: ^Barrier, thread_count: int) {
+barrier_init :: proc "contextless" (b: ^Barrier, thread_count: int) {
 	b.index = 0
 	b.index = 0
 	b.generation_id = 0
 	b.generation_id = 0
 	b.thread_count = thread_count
 	b.thread_count = thread_count
@@ -115,7 +115,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 "contextless" (b: ^Barrier) -> (is_leader: bool) {
 	guard(&b.mutex)
 	guard(&b.mutex)
 	local_gen := b.generation_id
 	local_gen := b.generation_id
 	b.index += 1
 	b.index += 1
@@ -141,7 +141,7 @@ Auto_Reset_Event :: struct {
 	sema:   Sema,
 	sema:   Sema,
 }
 }
 
 
-auto_reset_event_signal :: proc(e: ^Auto_Reset_Event) {
+auto_reset_event_signal :: proc "contextless" (e: ^Auto_Reset_Event) {
 	old_status := atomic_load_explicit(&e.status, .Relaxed)
 	old_status := atomic_load_explicit(&e.status, .Relaxed)
 	for {
 	for {
 		new_status := old_status + 1 if old_status < 1 else 1
 		new_status := old_status + 1 if old_status < 1 else 1
@@ -155,7 +155,7 @@ auto_reset_event_signal :: proc(e: ^Auto_Reset_Event) {
 	}
 	}
 }
 }
 
 
-auto_reset_event_wait :: proc(e: ^Auto_Reset_Event) {
+auto_reset_event_wait :: proc "contextless" (e: ^Auto_Reset_Event) {
 	old_status := atomic_sub_explicit(&e.status, 1, .Acquire)
 	old_status := atomic_sub_explicit(&e.status, 1, .Acquire)
 	if old_status < 1 {
 	if old_status < 1 {
 		sema_wait(&e.sema)
 		sema_wait(&e.sema)
@@ -169,18 +169,18 @@ Ticket_Mutex :: struct {
 	serving: uint,
 	serving: uint,
 }
 }
 
 
-ticket_mutex_lock :: #force_inline proc(m: ^Ticket_Mutex) {
+ticket_mutex_lock :: #force_inline proc "contextless" (m: ^Ticket_Mutex) {
 	ticket := atomic_add_explicit(&m.ticket, 1, .Relaxed)
 	ticket := atomic_add_explicit(&m.ticket, 1, .Relaxed)
 	for ticket != atomic_load_explicit(&m.serving, .Acquire) {
 	for ticket != atomic_load_explicit(&m.serving, .Acquire) {
 		cpu_relax()
 		cpu_relax()
 	}
 	}
 }
 }
 
 
-ticket_mutex_unlock :: #force_inline proc(m: ^Ticket_Mutex) {
+ticket_mutex_unlock :: #force_inline proc "contextless" (m: ^Ticket_Mutex) {
 	atomic_add_explicit(&m.serving, 1, .Relaxed)
 	atomic_add_explicit(&m.serving, 1, .Relaxed)
 }
 }
 @(deferred_in=ticket_mutex_unlock)
 @(deferred_in=ticket_mutex_unlock)
-ticket_mutex_guard :: proc(m: ^Ticket_Mutex) -> bool {
+ticket_mutex_guard :: proc "contextless" (m: ^Ticket_Mutex) -> bool {
 	ticket_mutex_lock(m)
 	ticket_mutex_lock(m)
 	return true
 	return true
 }
 }
@@ -191,25 +191,25 @@ Benaphore :: struct {
 	sema:    Sema,
 	sema:    Sema,
 }
 }
 
 
-benaphore_lock :: proc(b: ^Benaphore) {
+benaphore_lock :: proc "contextless" (b: ^Benaphore) {
 	if atomic_add_explicit(&b.counter, 1, .Acquire) > 1 {
 	if atomic_add_explicit(&b.counter, 1, .Acquire) > 1 {
 		sema_wait(&b.sema)
 		sema_wait(&b.sema)
 	}
 	}
 }
 }
 
 
-benaphore_try_lock :: proc(b: ^Benaphore) -> bool {
+benaphore_try_lock :: proc "contextless" (b: ^Benaphore) -> bool {
 	v, _ := atomic_compare_exchange_strong_explicit(&b.counter, 0, 1, .Acquire, .Acquire)
 	v, _ := atomic_compare_exchange_strong_explicit(&b.counter, 0, 1, .Acquire, .Acquire)
 	return v == 0
 	return v == 0
 }
 }
 
 
-benaphore_unlock :: proc(b: ^Benaphore) {
+benaphore_unlock :: proc "contextless" (b: ^Benaphore) {
 	if atomic_sub_explicit(&b.counter, 1, .Release) > 0 {
 	if atomic_sub_explicit(&b.counter, 1, .Release) > 0 {
 		sema_post(&b.sema)
 		sema_post(&b.sema)
 	}
 	}
 }
 }
 
 
 @(deferred_in=benaphore_unlock)
 @(deferred_in=benaphore_unlock)
-benaphore_guard :: proc(m: ^Benaphore) -> bool {
+benaphore_guard :: proc "contextless" (m: ^Benaphore) -> bool {
 	benaphore_lock(m)
 	benaphore_lock(m)
 	return true
 	return true
 }
 }
@@ -221,7 +221,7 @@ Recursive_Benaphore :: struct {
 	sema:      Sema,
 	sema:      Sema,
 }
 }
 
 
-recursive_benaphore_lock :: proc(b: ^Recursive_Benaphore) {
+recursive_benaphore_lock :: proc "contextless" (b: ^Recursive_Benaphore) {
 	tid := current_thread_id()
 	tid := current_thread_id()
 	if atomic_add_explicit(&b.counter, 1, .Acquire) > 1 {
 	if atomic_add_explicit(&b.counter, 1, .Acquire) > 1 {
 		if tid != b.owner {
 		if tid != b.owner {
@@ -233,7 +233,7 @@ recursive_benaphore_lock :: proc(b: ^Recursive_Benaphore) {
 	b.recursion += 1
 	b.recursion += 1
 }
 }
 
 
-recursive_benaphore_try_lock :: proc(b: ^Recursive_Benaphore) -> bool {
+recursive_benaphore_try_lock :: proc "contextless" (b: ^Recursive_Benaphore) -> bool {
 	tid := current_thread_id()
 	tid := current_thread_id()
 	if b.owner == tid {
 	if b.owner == tid {
 		atomic_add_explicit(&b.counter, 1, .Acquire)
 		atomic_add_explicit(&b.counter, 1, .Acquire)
@@ -248,9 +248,9 @@ recursive_benaphore_try_lock :: proc(b: ^Recursive_Benaphore) -> bool {
 	return true
 	return true
 }
 }
 
 
-recursive_benaphore_unlock :: proc(b: ^Recursive_Benaphore) {
+recursive_benaphore_unlock :: proc "contextless" (b: ^Recursive_Benaphore) {
 	tid := current_thread_id()
 	tid := current_thread_id()
-	assert(tid == b.owner)
+	_assert(tid == b.owner, "tid != b.owner")
 	b.recursion -= 1
 	b.recursion -= 1
 	recursion := b.recursion
 	recursion := b.recursion
 	if recursion == 0 {
 	if recursion == 0 {
@@ -265,7 +265,7 @@ recursive_benaphore_unlock :: proc(b: ^Recursive_Benaphore) {
 }
 }
 
 
 @(deferred_in=recursive_benaphore_unlock)
 @(deferred_in=recursive_benaphore_unlock)
-recursive_benaphore_guard :: proc(m: ^Recursive_Benaphore) -> bool {
+recursive_benaphore_guard :: proc "contextless" (m: ^Recursive_Benaphore) -> bool {
 	recursive_benaphore_lock(m)
 	recursive_benaphore_lock(m)
 	return true
 	return true
 }
 }
@@ -314,7 +314,7 @@ Parker :: struct {
 // Blocks the current thread until the token is made available.
 // Blocks the current thread until the token is made available.
 //
 //
 // Assumes this is only called by the thread that owns the Parker.
 // Assumes this is only called by the thread that owns the Parker.
-park :: proc(p: ^Parker) {
+park :: proc "contextless" (p: ^Parker) {
 	EMPTY    :: 0
 	EMPTY    :: 0
 	NOTIFIED :: 1
 	NOTIFIED :: 1
 	PARKED   :: max(u32)
 	PARKED   :: max(u32)
@@ -333,7 +333,7 @@ park :: proc(p: ^Parker) {
 // for a limited duration.
 // for a limited duration.
 //
 //
 // Assumes this is only called by the thread that owns the Parker
 // Assumes this is only called by the thread that owns the Parker
-park_with_timeout :: proc(p: ^Parker, duration: time.Duration) {
+park_with_timeout :: proc "contextless" (p: ^Parker, duration: time.Duration) {
 	EMPTY    :: 0
 	EMPTY    :: 0
 	NOTIFIED :: 1
 	NOTIFIED :: 1
 	PARKED   :: max(u32)
 	PARKED   :: max(u32)
@@ -345,7 +345,7 @@ park_with_timeout :: proc(p: ^Parker, duration: time.Duration) {
 }
 }
 
 
 // Automatically makes thee token available if it was not already.
 // Automatically makes thee token available if it was not already.
-unpark :: proc(p: ^Parker)  {
+unpark :: proc "contextless" (p: ^Parker)  {
 	EMPTY    :: 0
 	EMPTY    :: 0
 	NOTIFIED :: 1
 	NOTIFIED :: 1
 	PARKED   :: max(Futex)
 	PARKED   :: max(Futex)

+ 7 - 7
core/sync/futex_darwin.odin

@@ -24,11 +24,11 @@ EINTR     :: -4
 EFAULT    :: -14
 EFAULT    :: -14
 ETIMEDOUT :: -60
 ETIMEDOUT :: -60
 
 
-_futex_wait :: proc(f: ^Futex, expected: u32) -> bool {
+_futex_wait :: proc "contextless" (f: ^Futex, expected: u32) -> bool {
 	return _futex_wait_with_timeout(f, expected, 0)
 	return _futex_wait_with_timeout(f, expected, 0)
 }
 }
 
 
-_futex_wait_with_timeout :: proc(f: ^Futex, expected: u32, duration: time.Duration) -> bool {
+_futex_wait_with_timeout :: proc "contextless" (f: ^Futex, expected: u32, duration: time.Duration) -> bool {
 	timeout_ns := u32(duration) * 1000
 	timeout_ns := u32(duration) * 1000
 	
 	
 	s := __ulock_wait(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO, f, u64(expected), timeout_ns)
 	s := __ulock_wait(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO, f, u64(expected), timeout_ns)
@@ -41,13 +41,13 @@ _futex_wait_with_timeout :: proc(f: ^Futex, expected: u32, duration: time.Durati
 	case ETIMEDOUT:
 	case ETIMEDOUT:
 		return false
 		return false
 	case:
 	case:
-		panic("futex_wait failure")
+		_panic("futex_wait failure")
 	}
 	}
 	return true
 	return true
 
 
 }
 }
 
 
-_futex_signal :: proc(f: ^Futex) {
+_futex_signal :: proc "contextless" (f: ^Futex) {
 	loop: for {
 	loop: for {
 		s := __ulock_wake(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO, f, 0)
 		s := __ulock_wake(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO, f, 0)
 		if s >= 0 {
 		if s >= 0 {
@@ -59,12 +59,12 @@ _futex_signal :: proc(f: ^Futex) {
 		case ENOENT:
 		case ENOENT:
 			return
 			return
 		case:
 		case:
-			panic("futex_wake_single failure")
+			_panic("futex_wake_single failure")
 		}
 		}
 	}
 	}
 }
 }
 
 
-_futex_broadcast :: proc(f: ^Futex) {
+_futex_broadcast :: proc "contextless" (f: ^Futex) {
 	loop: for {
 	loop: for {
 		s := __ulock_wake(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO | ULF_WAKE_ALL, f, 0)
 		s := __ulock_wake(UL_COMPARE_AND_WAIT | ULF_NO_ERRNO | ULF_WAKE_ALL, f, 0)
 		if s >= 0 {
 		if s >= 0 {
@@ -76,7 +76,7 @@ _futex_broadcast :: proc(f: ^Futex) {
 		case ENOENT:
 		case ENOENT:
 			return
 			return
 		case:
 		case:
-			panic("futex_wake_all failure")
+			_panic("futex_wake_all failure")
 		}
 		}
 	}
 	}
 }
 }

+ 8 - 8
core/sync/futex_freebsd.odin

@@ -17,7 +17,7 @@ foreign libc {
 	__error :: proc "c" () -> ^c.int ---
 	__error :: proc "c" () -> ^c.int ---
 }
 }
 
 
-_futex_wait :: proc(f: ^Futex, expected: u32) -> bool {
+_futex_wait :: proc "contextless" (f: ^Futex, expected: u32) -> bool {
 	timeout := [2]i64{14400, 0} // 4 hours
 	timeout := [2]i64{14400, 0} // 4 hours
 	for {
 	for {
 		res := _umtx_op(f, UMTX_OP_WAIT, c.ulong(expected), nil, &timeout)
 		res := _umtx_op(f, UMTX_OP_WAIT, c.ulong(expected), nil, &timeout)
@@ -30,12 +30,12 @@ _futex_wait :: proc(f: ^Futex, expected: u32) -> bool {
 			continue
 			continue
 		}
 		}
 
 
-		panic("_futex_wait failure")
+		_panic("_futex_wait failure")
 	}
 	}
 	unreachable()
 	unreachable()
 }
 }
 
 
-_futex_wait_with_timeout :: proc(f: ^Futex, expected: u32, duration: time.Duration) -> bool {
+_futex_wait_with_timeout :: proc "contextless" (f: ^Futex, expected: u32, duration: time.Duration) -> bool {
 	if duration <= 0 {
 	if duration <= 0 {
 		return false
 		return false
 	}
 	}
@@ -51,21 +51,21 @@ _futex_wait_with_timeout :: proc(f: ^Futex, expected: u32, duration: time.Durati
 		return false
 		return false
 	}
 	}
 
 
-	panic("_futex_wait_with_timeout failure")
+	_panic("_futex_wait_with_timeout failure")
 }
 }
 
 
-_futex_signal :: proc(f: ^Futex) {
+_futex_signal :: proc "contextless" (f: ^Futex) {
 	res := _umtx_op(f, UMTX_OP_WAKE, 1, nil, nil)
 	res := _umtx_op(f, UMTX_OP_WAKE, 1, nil, nil)
 
 
 	if res == -1 {
 	if res == -1 {
-		panic("_futex_signal failure")
+		_panic("_futex_signal failure")
 	}
 	}
 }
 }
 
 
-_futex_broadcast :: proc(f: ^Futex)  {
+_futex_broadcast :: proc "contextless" (f: ^Futex)  {
 	res := _umtx_op(f, UMTX_OP_WAKE, c.ulong(max(i32)), nil, nil)
 	res := _umtx_op(f, UMTX_OP_WAKE, c.ulong(max(i32)), nil, nil)
 
 
 	if res == -1 {
 	if res == -1 {
-		panic("_futex_broadcast failure")
+		_panic("_futex_broadcast failure")
 	}
 	}
 }
 }

+ 10 - 10
core/sync/futex_linux.odin

@@ -21,20 +21,20 @@ EFAULT    :: -14
 EINVAL    :: -22
 EINVAL    :: -22
 ETIMEDOUT :: -110
 ETIMEDOUT :: -110
 
 
-get_errno :: proc(r: int) -> int {
+get_errno :: proc "contextless" (r: int) -> int {
 	if -4096 < r && r < 0 {
 	if -4096 < r && r < 0 {
 		return r
 		return r
 	}
 	}
 	return 0
 	return 0
 }
 }
 
 
-internal_futex :: proc(f: ^Futex, op: c.int, val: u32, timeout: rawptr) -> int {
+internal_futex :: proc "contextless" (f: ^Futex, op: c.int, val: u32, timeout: rawptr) -> int {
 	code := int(intrinsics.syscall(unix.SYS_futex, uintptr(f), uintptr(op), uintptr(val), uintptr(timeout), 0, 0))
 	code := int(intrinsics.syscall(unix.SYS_futex, uintptr(f), uintptr(op), uintptr(val), uintptr(timeout), 0, 0))
 	return get_errno(code)
 	return get_errno(code)
 }
 }
 
 
 
 
-_futex_wait :: proc(f: ^Futex, expected: u32) -> bool {
+_futex_wait :: proc "contextless" (f: ^Futex, expected: u32) -> bool {
 	err := internal_futex(f, FUTEX_WAIT_PRIVATE | FUTEX_WAIT, expected, nil)
 	err := internal_futex(f, FUTEX_WAIT_PRIVATE | FUTEX_WAIT, expected, nil)
 	switch err {
 	switch err {
 	case ESUCCESS, EINTR, EAGAIN, EINVAL:
 	case ESUCCESS, EINTR, EAGAIN, EINVAL:
@@ -44,12 +44,12 @@ _futex_wait :: proc(f: ^Futex, expected: u32) -> bool {
 	case EFAULT: 
 	case EFAULT: 
 		fallthrough
 		fallthrough
 	case:
 	case:
-		panic("futex_wait failure")
+		_panic("futex_wait failure")
 	}
 	}
 	return true
 	return true
 }
 }
 
 
-_futex_wait_with_timeout :: proc(f: ^Futex, expected: u32, duration: time.Duration) -> bool {
+_futex_wait_with_timeout :: proc "contextless" (f: ^Futex, expected: u32, duration: time.Duration) -> bool {
 	if duration <= 0 {
 	if duration <= 0 {
 		return false
 		return false
 	}
 	}
@@ -71,27 +71,27 @@ _futex_wait_with_timeout :: proc(f: ^Futex, expected: u32, duration: time.Durati
 	case EFAULT: 
 	case EFAULT: 
 		fallthrough
 		fallthrough
 	case:
 	case:
-		panic("futex_wait_with_timeout failure")
+		_panic("futex_wait_with_timeout failure")
 	}
 	}
 	return true
 	return true
 }
 }
 
 
 
 
-_futex_signal :: proc(f: ^Futex) {
+_futex_signal :: proc "contextless" (f: ^Futex) {
 	err := internal_futex(f, FUTEX_WAKE_PRIVATE | FUTEX_WAKE, 1, nil)
 	err := internal_futex(f, FUTEX_WAKE_PRIVATE | FUTEX_WAKE, 1, nil)
 	switch err {
 	switch err {
 	case ESUCCESS, EINVAL, EFAULT:
 	case ESUCCESS, EINVAL, EFAULT:
 		// okay
 		// okay
 	case:
 	case:
-		panic("futex_wake_single failure")
+		_panic("futex_wake_single failure")
 	}
 	}
 }
 }
-_futex_broadcast :: proc(f: ^Futex)  {
+_futex_broadcast :: proc "contextless" (f: ^Futex)  {
 	err := internal_futex(f, FUTEX_WAKE_PRIVATE | FUTEX_WAKE, u32(max(i32)), nil)
 	err := internal_futex(f, FUTEX_WAKE_PRIVATE | FUTEX_WAKE, u32(max(i32)), nil)
 	switch err {
 	switch err {
 	case ESUCCESS, EINVAL, EFAULT:
 	case ESUCCESS, EINVAL, EFAULT:
 		// okay
 		// okay
 	case:
 	case:
-		panic("_futex_wake_all failure")
+		_panic("_futex_wake_all failure")
 	}
 	}
 }
 }

+ 8 - 8
core/sync/futex_openbsd.odin

@@ -21,7 +21,7 @@ foreign libc {
 	_unix_futex :: proc "c" (f: ^Futex, op: c.int, val: u32, timeout: rawptr) -> c.int ---
 	_unix_futex :: proc "c" (f: ^Futex, op: c.int, val: u32, timeout: rawptr) -> c.int ---
 }
 }
 
 
-_futex_wait :: proc(f: ^Futex, expected: u32) -> bool {
+_futex_wait :: proc "contextless" (f: ^Futex, expected: u32) -> bool {
 	res := _unix_futex(f, FUTEX_WAIT_PRIVATE, expected, nil)
 	res := _unix_futex(f, FUTEX_WAIT_PRIVATE, expected, nil)
 
 
 	if res != -1 {
 	if res != -1 {
@@ -32,10 +32,10 @@ _futex_wait :: proc(f: ^Futex, expected: u32) -> bool {
 		return false
 		return false
 	}
 	}
 
 
-	panic("futex_wait failure")
+	_panic("futex_wait failure")
 }
 }
 
 
-_futex_wait_with_timeout :: proc(f: ^Futex, expected: u32, duration: time.Duration) -> bool {
+_futex_wait_with_timeout :: proc "contextless" (f: ^Futex, expected: u32, duration: time.Duration) -> bool {
 	if duration <= 0 {
 	if duration <= 0 {
 		return false
 		return false
 	}
 	}
@@ -58,21 +58,21 @@ _futex_wait_with_timeout :: proc(f: ^Futex, expected: u32, duration: time.Durati
 		return false
 		return false
 	}
 	}
 
 
-	panic("futex_wait_with_timeout failure")
+	_panic("futex_wait_with_timeout failure")
 }
 }
 
 
-_futex_signal :: proc(f: ^Futex) {
+_futex_signal :: proc "contextless" (f: ^Futex) {
 	res := _unix_futex(f, FUTEX_WAKE_PRIVATE, 1, nil)
 	res := _unix_futex(f, FUTEX_WAKE_PRIVATE, 1, nil)
 
 
 	if res == -1 {
 	if res == -1 {
-		panic("futex_wake_single failure")
+		_panic("futex_wake_single failure")
 	}
 	}
 }
 }
 
 
-_futex_broadcast :: proc(f: ^Futex)  {
+_futex_broadcast :: proc "contextless" (f: ^Futex)  {
 	res := _unix_futex(f, FUTEX_WAKE_PRIVATE, u32(max(i32)), nil)
 	res := _unix_futex(f, FUTEX_WAKE_PRIVATE, u32(max(i32)), nil)
 
 
 	if res == -1 {
 	if res == -1 {
-		panic("_futex_wake_all failure")
+		_panic("_futex_wake_all failure")
 	}
 	}
 }
 }

+ 4 - 4
core/sync/futex_wasm.odin

@@ -5,18 +5,18 @@ package sync
 import "core:intrinsics"
 import "core:intrinsics"
 import "core:time"
 import "core:time"
 
 
-_futex_wait :: proc(f: ^Futex, expected: u32) -> bool {
+_futex_wait :: proc "contextless" (f: ^Futex, expected: u32) -> bool {
 	s := intrinsics.wasm_memory_atomic_wait32((^u32)(f), expected, -1)
 	s := intrinsics.wasm_memory_atomic_wait32((^u32)(f), expected, -1)
 	return s != 0
 	return s != 0
 }
 }
 
 
-_futex_wait_with_timeout :: proc(f: ^Futex, expected: u32, duration: time.Duration) -> bool {
+_futex_wait_with_timeout :: proc "contextless" (f: ^Futex, expected: u32, duration: time.Duration) -> bool {
 	s := intrinsics.wasm_memory_atomic_wait32((^u32)(f), expected, i64(duration))
 	s := intrinsics.wasm_memory_atomic_wait32((^u32)(f), expected, i64(duration))
 	return s != 0
 	return s != 0
 
 
 }
 }
 
 
-_futex_signal :: proc(f: ^Futex) {
+_futex_signal :: proc "contextless" (f: ^Futex) {
 	loop: for {
 	loop: for {
 		s := intrinsics.wasm_memory_atomic_notify32((^u32)(f), 1)
 		s := intrinsics.wasm_memory_atomic_notify32((^u32)(f), 1)
 		if s >= 1 {
 		if s >= 1 {
@@ -25,7 +25,7 @@ _futex_signal :: proc(f: ^Futex) {
 	}
 	}
 }
 }
 
 
-_futex_broadcast :: proc(f: ^Futex) {
+_futex_broadcast :: proc "contextless" (f: ^Futex) {
 	loop: for {
 	loop: for {
 		s := intrinsics.wasm_memory_atomic_notify32((^u32)(f), ~u32(0))
 		s := intrinsics.wasm_memory_atomic_notify32((^u32)(f), ~u32(0))
 		if s >= 0 {
 		if s >= 0 {

+ 4 - 4
core/sync/futex_windows.odin

@@ -39,22 +39,22 @@ CustomWaitOnAddress :: proc "stdcall" (Address: rawptr, CompareAddress: rawptr,
 }
 }
 
 
 
 
-_futex_wait :: proc(f: ^Futex, expect: u32) -> bool {
+_futex_wait :: proc "contextless" (f: ^Futex, expect: u32) -> bool {
 	expect := expect
 	expect := expect
 	return CustomWaitOnAddress(f, &expect, size_of(expect), nil)
 	return CustomWaitOnAddress(f, &expect, size_of(expect), nil)
 }
 }
 
 
-_futex_wait_with_timeout :: proc(f: ^Futex, expect: u32, duration: time.Duration) -> bool {
+_futex_wait_with_timeout :: proc "contextless" (f: ^Futex, expect: u32, duration: time.Duration) -> bool {
 	expect := expect
 	expect := expect
 	// NOTE(bill): for some bizarre reason, this has be a negative number
 	// NOTE(bill): for some bizarre reason, this has be a negative number
 	timeout := -i64(duration / 100)
 	timeout := -i64(duration / 100)
 	return CustomWaitOnAddress(f, &expect, size_of(expect), &timeout)
 	return CustomWaitOnAddress(f, &expect, size_of(expect), &timeout)
 }
 }
 
 
-_futex_signal :: proc(f: ^Futex) {
+_futex_signal :: proc "contextless" (f: ^Futex) {
 	WakeByAddressSingle(f)
 	WakeByAddressSingle(f)
 }
 }
 
 
-_futex_broadcast :: proc(f: ^Futex) {
+_futex_broadcast :: proc "contextless" (f: ^Futex) {
 	WakeByAddressAll(f)
 	WakeByAddressAll(f)
 }
 }

+ 44 - 28
core/sync/primitives.odin

@@ -1,5 +1,6 @@
 package sync
 package sync
 
 
+import "core:runtime"
 import "core:time"
 import "core:time"
 
 
 current_thread_id :: proc "contextless" () -> int {
 current_thread_id :: proc "contextless" () -> int {
@@ -15,17 +16,17 @@ Mutex :: struct {
 }
 }
 
 
 // mutex_lock locks m
 // mutex_lock locks m
-mutex_lock :: proc(m: ^Mutex) {
+mutex_lock :: proc "contextless" (m: ^Mutex) {
 	_mutex_lock(m)
 	_mutex_lock(m)
 }
 }
 
 
 // mutex_unlock unlocks m
 // mutex_unlock unlocks m
-mutex_unlock :: proc(m: ^Mutex) {
+mutex_unlock :: proc "contextless" (m: ^Mutex) {
 	_mutex_unlock(m)
 	_mutex_unlock(m)
 }
 }
 
 
 // mutex_try_lock tries to lock m, will return true on success, and false on failure
 // mutex_try_lock tries to lock m, will return true on success, and false on failure
-mutex_try_lock :: proc(m: ^Mutex) -> bool {
+mutex_try_lock :: proc "contextless" (m: ^Mutex) -> bool {
 	return _mutex_try_lock(m)
 	return _mutex_try_lock(m)
 }
 }
 
 
@@ -36,7 +37,7 @@ Example:
 	}
 	}
 */
 */
 @(deferred_in=mutex_unlock)
 @(deferred_in=mutex_unlock)
-mutex_guard :: proc(m: ^Mutex) -> bool {
+mutex_guard :: proc "contextless" (m: ^Mutex) -> bool {
 	mutex_lock(m)
 	mutex_lock(m)
 	return true
 	return true
 }
 }
@@ -52,32 +53,32 @@ RW_Mutex :: struct {
 
 
 // rw_mutex_lock locks rw for writing (with a single writer)
 // rw_mutex_lock locks rw for writing (with a single writer)
 // If the mutex is already locked for reading or writing, the mutex blocks until the mutex is available.
 // If the mutex is already locked for reading or writing, the mutex blocks until the mutex is available.
-rw_mutex_lock :: proc(rw: ^RW_Mutex) {
+rw_mutex_lock :: proc "contextless" (rw: ^RW_Mutex) {
 	_rw_mutex_lock(rw)
 	_rw_mutex_lock(rw)
 }
 }
 
 
 // rw_mutex_unlock unlocks rw for writing (with a single writer)
 // rw_mutex_unlock unlocks rw for writing (with a single writer)
-rw_mutex_unlock :: proc(rw: ^RW_Mutex) {
+rw_mutex_unlock :: proc "contextless" (rw: ^RW_Mutex) {
 	_rw_mutex_unlock(rw)
 	_rw_mutex_unlock(rw)
 }
 }
 
 
 // rw_mutex_try_lock tries to lock rw for writing (with a single writer)
 // rw_mutex_try_lock tries to lock rw for writing (with a single writer)
-rw_mutex_try_lock :: proc(rw: ^RW_Mutex) -> bool {
+rw_mutex_try_lock :: proc "contextless" (rw: ^RW_Mutex) -> bool {
 	return _rw_mutex_try_lock(rw)
 	return _rw_mutex_try_lock(rw)
 }
 }
 
 
 // rw_mutex_shared_lock locks rw for reading (with arbitrary number of readers)
 // rw_mutex_shared_lock locks rw for reading (with arbitrary number of readers)
-rw_mutex_shared_lock :: proc(rw: ^RW_Mutex) {
+rw_mutex_shared_lock :: proc "contextless" (rw: ^RW_Mutex) {
 	_rw_mutex_shared_lock(rw)
 	_rw_mutex_shared_lock(rw)
 }
 }
 
 
 // rw_mutex_shared_unlock unlocks rw for reading (with arbitrary number of readers)
 // rw_mutex_shared_unlock unlocks rw for reading (with arbitrary number of readers)
-rw_mutex_shared_unlock :: proc(rw: ^RW_Mutex) {
+rw_mutex_shared_unlock :: proc "contextless" (rw: ^RW_Mutex) {
 	_rw_mutex_shared_unlock(rw)
 	_rw_mutex_shared_unlock(rw)
 }
 }
 
 
 // rw_mutex_try_shared_lock tries to lock rw for reading (with arbitrary number of readers)
 // rw_mutex_try_shared_lock tries to lock rw for reading (with arbitrary number of readers)
-rw_mutex_try_shared_lock :: proc(rw: ^RW_Mutex) -> bool {
+rw_mutex_try_shared_lock :: proc "contextless" (rw: ^RW_Mutex) -> bool {
 	return _rw_mutex_try_shared_lock(rw)
 	return _rw_mutex_try_shared_lock(rw)
 }
 }
 /*
 /*
@@ -87,7 +88,7 @@ Example:
 	}
 	}
 */
 */
 @(deferred_in=rw_mutex_unlock)
 @(deferred_in=rw_mutex_unlock)
-rw_mutex_guard :: proc(m: ^RW_Mutex) -> bool {
+rw_mutex_guard :: proc "contextless" (m: ^RW_Mutex) -> bool {
 	rw_mutex_lock(m)
 	rw_mutex_lock(m)
 	return true
 	return true
 }
 }
@@ -99,7 +100,7 @@ Example:
 	}
 	}
 */
 */
 @(deferred_in=rw_mutex_shared_unlock)
 @(deferred_in=rw_mutex_shared_unlock)
-rw_mutex_shared_guard :: proc(m: ^RW_Mutex) -> bool {
+rw_mutex_shared_guard :: proc "contextless" (m: ^RW_Mutex) -> bool {
 	rw_mutex_shared_lock(m)
 	rw_mutex_shared_lock(m)
 	return true
 	return true
 }
 }
@@ -114,15 +115,15 @@ Recursive_Mutex :: struct {
 	impl: _Recursive_Mutex,
 	impl: _Recursive_Mutex,
 }
 }
 
 
-recursive_mutex_lock :: proc(m: ^Recursive_Mutex) {
+recursive_mutex_lock :: proc "contextless" (m: ^Recursive_Mutex) {
 	_recursive_mutex_lock(m)
 	_recursive_mutex_lock(m)
 }
 }
 
 
-recursive_mutex_unlock :: proc(m: ^Recursive_Mutex) {
+recursive_mutex_unlock :: proc "contextless" (m: ^Recursive_Mutex) {
 	_recursive_mutex_unlock(m)
 	_recursive_mutex_unlock(m)
 }
 }
 
 
-recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool {
+recursive_mutex_try_lock :: proc "contextless" (m: ^Recursive_Mutex) -> bool {
 	return _recursive_mutex_try_lock(m)
 	return _recursive_mutex_try_lock(m)
 }
 }
 
 
@@ -133,7 +134,7 @@ Example:
 	}
 	}
 */
 */
 @(deferred_in=recursive_mutex_unlock)
 @(deferred_in=recursive_mutex_unlock)
-recursive_mutex_guard :: proc(m: ^Recursive_Mutex) -> bool {
+recursive_mutex_guard :: proc "contextless" (m: ^Recursive_Mutex) -> bool {
 	recursive_mutex_lock(m)
 	recursive_mutex_lock(m)
 	return true
 	return true
 }
 }
@@ -147,22 +148,22 @@ Cond :: struct {
 	impl: _Cond,
 	impl: _Cond,
 }
 }
 
 
-cond_wait :: proc(c: ^Cond, m: ^Mutex) {
+cond_wait :: proc "contextless" (c: ^Cond, m: ^Mutex) {
 	_cond_wait(c, m)
 	_cond_wait(c, m)
 }
 }
 
 
-cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool {
+cond_wait_with_timeout :: proc "contextless" (c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool {
 	if duration <= 0 {
 	if duration <= 0 {
 		return false
 		return false
 	}
 	}
 	return _cond_wait_with_timeout(c, m, duration)
 	return _cond_wait_with_timeout(c, m, duration)
 }
 }
 
 
-cond_signal :: proc(c: ^Cond) {
+cond_signal :: proc "contextless" (c: ^Cond) {
 	_cond_signal(c)
 	_cond_signal(c)
 }
 }
 
 
-cond_broadcast :: proc(c: ^Cond) {
+cond_broadcast :: proc "contextless" (c: ^Cond) {
 	_cond_broadcast(c)
 	_cond_broadcast(c)
 }
 }
 
 
@@ -175,15 +176,15 @@ Sema :: struct {
 	impl: _Sema,
 	impl: _Sema,
 }
 }
 
 
-sema_post :: proc(s: ^Sema, count := 1) {
+sema_post :: proc "contextless" (s: ^Sema, count := 1) {
 	_sema_post(s, count)
 	_sema_post(s, count)
 }
 }
 
 
-sema_wait :: proc(s: ^Sema) {
+sema_wait :: proc "contextless" (s: ^Sema) {
 	_sema_wait(s)
 	_sema_wait(s)
 }
 }
 
 
-sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool {
+sema_wait_with_timeout :: proc "contextless" (s: ^Sema, duration: time.Duration) -> bool {
 	return _sema_wait_with_timeout(s, duration)
 	return _sema_wait_with_timeout(s, duration)
 }
 }
 
 
@@ -194,16 +195,16 @@ sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool {
 // An Futex must not be copied after first use
 // An Futex must not be copied after first use
 Futex :: distinct u32
 Futex :: distinct u32
 
 
-futex_wait :: proc(f: ^Futex, expected: u32) {
+futex_wait :: proc "contextless" (f: ^Futex, expected: u32) {
 	if u32(atomic_load_explicit(f, .Acquire)) != expected {
 	if u32(atomic_load_explicit(f, .Acquire)) != expected {
 		return
 		return
 	}
 	}
 	
 	
-	assert(_futex_wait(f, expected), "futex_wait failure")
+	_assert(_futex_wait(f, expected), "futex_wait failure")
 }
 }
 
 
 // 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 "contextless" (f: ^Futex, expected: u32, duration: time.Duration) -> bool {
 	if u32(atomic_load_explicit(f, .Acquire)) != expected {
 	if u32(atomic_load_explicit(f, .Acquire)) != expected {
 		return true
 		return true
 	}
 	}
@@ -214,10 +215,25 @@ futex_wait_with_timeout :: proc(f: ^Futex, expected: u32, duration: time.Duratio
 	return _futex_wait_with_timeout(f, expected, duration)
 	return _futex_wait_with_timeout(f, expected, duration)
 }
 }
 
 
-futex_signal :: proc(f: ^Futex) {
+futex_signal :: proc "contextless" (f: ^Futex) {
 	_futex_signal(f)
 	_futex_signal(f)
 }
 }
 
 
-futex_broadcast :: proc(f: ^Futex) {
+futex_broadcast :: proc "contextless" (f: ^Futex) {
 	_futex_broadcast(f)
 	_futex_broadcast(f)
 }
 }
+
+
+@(private)
+_assert :: proc "contextless" (cond: bool, msg: string) {
+	if !cond {
+		_panic(msg)
+	}
+}
+
+@(private)
+_panic :: proc "contextless" (msg: string) -> ! {
+	runtime.print_string(msg)
+	runtime.print_byte('\n')
+	runtime.trap()
+}

+ 26 - 26
core/sync/primitives_atomic.odin

@@ -18,9 +18,9 @@ Atomic_Mutex :: struct {
 }
 }
 
 
 // atomic_mutex_lock locks m
 // atomic_mutex_lock locks m
-atomic_mutex_lock :: proc(m: ^Atomic_Mutex) {
+atomic_mutex_lock :: proc "contextless" (m: ^Atomic_Mutex) {
 	@(cold)
 	@(cold)
-	lock_slow :: proc(m: ^Atomic_Mutex, curr_state: Atomic_Mutex_State) {
+	lock_slow :: proc "contextless" (m: ^Atomic_Mutex, curr_state: Atomic_Mutex_State) {
 		new_state := curr_state // Make a copy of it
 		new_state := curr_state // Make a copy of it
 
 
 		spin_lock: for spin in 0..<i32(100) {
 		spin_lock: for spin in 0..<i32(100) {
@@ -58,9 +58,9 @@ atomic_mutex_lock :: proc(m: ^Atomic_Mutex) {
 }
 }
 
 
 // atomic_mutex_unlock unlocks m
 // atomic_mutex_unlock unlocks m
-atomic_mutex_unlock :: proc(m: ^Atomic_Mutex) {
+atomic_mutex_unlock :: proc "contextless" (m: ^Atomic_Mutex) {
 	@(cold)
 	@(cold)
-	unlock_slow :: proc(m: ^Atomic_Mutex) {
+	unlock_slow :: proc "contextless" (m: ^Atomic_Mutex) {
 		futex_signal((^Futex)(&m.state))
 		futex_signal((^Futex)(&m.state))
 	}
 	}
 
 
@@ -76,7 +76,7 @@ atomic_mutex_unlock :: proc(m: ^Atomic_Mutex) {
 }
 }
 
 
 // atomic_mutex_try_lock tries to lock m, will return true on success, and false on failure
 // atomic_mutex_try_lock tries to lock m, will return true on success, and false on failure
-atomic_mutex_try_lock :: proc(m: ^Atomic_Mutex) -> bool {
+atomic_mutex_try_lock :: proc "contextless" (m: ^Atomic_Mutex) -> bool {
 	_, ok := atomic_compare_exchange_strong_explicit(&m.state, .Unlocked, .Locked, .Acquire, .Consume)
 	_, ok := atomic_compare_exchange_strong_explicit(&m.state, .Unlocked, .Locked, .Acquire, .Consume)
 	return ok
 	return ok
 }
 }
@@ -88,7 +88,7 @@ Example:
 	}
 	}
 */
 */
 @(deferred_in=atomic_mutex_unlock)
 @(deferred_in=atomic_mutex_unlock)
-atomic_mutex_guard :: proc(m: ^Atomic_Mutex) -> bool {
+atomic_mutex_guard :: proc "contextless" (m: ^Atomic_Mutex) -> bool {
 	atomic_mutex_lock(m)
 	atomic_mutex_lock(m)
 	return true
 	return true
 }
 }
@@ -117,7 +117,7 @@ Atomic_RW_Mutex :: struct {
 
 
 // atomic_rw_mutex_lock locks rw for writing (with a single writer)
 // atomic_rw_mutex_lock locks rw for writing (with a single writer)
 // If the mutex is already locked for reading or writing, the mutex blocks until the mutex is available.
 // If the mutex is already locked for reading or writing, the mutex blocks until the mutex is available.
-atomic_rw_mutex_lock :: proc(rw: ^Atomic_RW_Mutex) {
+atomic_rw_mutex_lock :: proc "contextless" (rw: ^Atomic_RW_Mutex) {
 	_ = atomic_add(&rw.state, Atomic_RW_Mutex_State_Writer)
 	_ = atomic_add(&rw.state, Atomic_RW_Mutex_State_Writer)
 	atomic_mutex_lock(&rw.mutex)
 	atomic_mutex_lock(&rw.mutex)
 
 
@@ -128,13 +128,13 @@ atomic_rw_mutex_lock :: proc(rw: ^Atomic_RW_Mutex) {
 }
 }
 
 
 // atomic_rw_mutex_unlock unlocks rw for writing (with a single writer)
 // atomic_rw_mutex_unlock unlocks rw for writing (with a single writer)
-atomic_rw_mutex_unlock :: proc(rw: ^Atomic_RW_Mutex) {
+atomic_rw_mutex_unlock :: proc "contextless" (rw: ^Atomic_RW_Mutex) {
 	_ = atomic_and(&rw.state, ~Atomic_RW_Mutex_State_Is_Writing)
 	_ = atomic_and(&rw.state, ~Atomic_RW_Mutex_State_Is_Writing)
 	atomic_mutex_unlock(&rw.mutex)
 	atomic_mutex_unlock(&rw.mutex)
 }
 }
 
 
 // atomic_rw_mutex_try_lock tries to lock rw for writing (with a single writer)
 // atomic_rw_mutex_try_lock tries to lock rw for writing (with a single writer)
-atomic_rw_mutex_try_lock :: proc(rw: ^Atomic_RW_Mutex) -> bool {
+atomic_rw_mutex_try_lock :: proc "contextless" (rw: ^Atomic_RW_Mutex) -> bool {
 	if atomic_mutex_try_lock(&rw.mutex) {
 	if atomic_mutex_try_lock(&rw.mutex) {
 		state := atomic_load(&rw.state)
 		state := atomic_load(&rw.state)
 		if state & Atomic_RW_Mutex_State_Reader_Mask == 0 {
 		if state & Atomic_RW_Mutex_State_Reader_Mask == 0 {
@@ -148,7 +148,7 @@ atomic_rw_mutex_try_lock :: proc(rw: ^Atomic_RW_Mutex) -> bool {
 }
 }
 
 
 // atomic_rw_mutex_shared_lock locks rw for reading (with arbitrary number of readers)
 // atomic_rw_mutex_shared_lock locks rw for reading (with arbitrary number of readers)
-atomic_rw_mutex_shared_lock :: proc(rw: ^Atomic_RW_Mutex) {
+atomic_rw_mutex_shared_lock :: proc "contextless" (rw: ^Atomic_RW_Mutex) {
 	state := atomic_load(&rw.state)
 	state := atomic_load(&rw.state)
 	for state & (Atomic_RW_Mutex_State_Is_Writing|Atomic_RW_Mutex_State_Writer_Mask) == 0 {
 	for state & (Atomic_RW_Mutex_State_Is_Writing|Atomic_RW_Mutex_State_Writer_Mask) == 0 {
 		ok: bool
 		ok: bool
@@ -164,7 +164,7 @@ atomic_rw_mutex_shared_lock :: proc(rw: ^Atomic_RW_Mutex) {
 }
 }
 
 
 // atomic_rw_mutex_shared_unlock unlocks rw for reading (with arbitrary number of readers)
 // atomic_rw_mutex_shared_unlock unlocks rw for reading (with arbitrary number of readers)
-atomic_rw_mutex_shared_unlock :: proc(rw: ^Atomic_RW_Mutex) {
+atomic_rw_mutex_shared_unlock :: proc "contextless" (rw: ^Atomic_RW_Mutex) {
 	state := atomic_sub(&rw.state, Atomic_RW_Mutex_State_Reader)
 	state := atomic_sub(&rw.state, Atomic_RW_Mutex_State_Reader)
 
 
 	if (state & Atomic_RW_Mutex_State_Reader_Mask == Atomic_RW_Mutex_State_Reader) &&
 	if (state & Atomic_RW_Mutex_State_Reader_Mask == Atomic_RW_Mutex_State_Reader) &&
@@ -174,7 +174,7 @@ atomic_rw_mutex_shared_unlock :: proc(rw: ^Atomic_RW_Mutex) {
 }
 }
 
 
 // atomic_rw_mutex_try_shared_lock tries to lock rw for reading (with arbitrary number of readers)
 // atomic_rw_mutex_try_shared_lock tries to lock rw for reading (with arbitrary number of readers)
-atomic_rw_mutex_try_shared_lock :: proc(rw: ^Atomic_RW_Mutex) -> bool {
+atomic_rw_mutex_try_shared_lock :: proc "contextless" (rw: ^Atomic_RW_Mutex) -> bool {
 	state := atomic_load(&rw.state)
 	state := atomic_load(&rw.state)
 	if state & (Atomic_RW_Mutex_State_Is_Writing|Atomic_RW_Mutex_State_Writer_Mask) == 0 {
 	if state & (Atomic_RW_Mutex_State_Is_Writing|Atomic_RW_Mutex_State_Writer_Mask) == 0 {
 		_, ok := atomic_compare_exchange_strong(&rw.state, state, state + Atomic_RW_Mutex_State_Reader)
 		_, ok := atomic_compare_exchange_strong(&rw.state, state, state + Atomic_RW_Mutex_State_Reader)
@@ -198,7 +198,7 @@ Example:
 	}
 	}
 */
 */
 @(deferred_in=atomic_rw_mutex_unlock)
 @(deferred_in=atomic_rw_mutex_unlock)
-atomic_rw_mutex_guard :: proc(m: ^Atomic_RW_Mutex) -> bool {
+atomic_rw_mutex_guard :: proc "contextless" (m: ^Atomic_RW_Mutex) -> bool {
 	atomic_rw_mutex_lock(m)
 	atomic_rw_mutex_lock(m)
 	return true
 	return true
 }
 }
@@ -210,7 +210,7 @@ Example:
 	}
 	}
 */
 */
 @(deferred_in=atomic_rw_mutex_shared_unlock)
 @(deferred_in=atomic_rw_mutex_shared_unlock)
-atomic_rw_mutex_shared_guard :: proc(m: ^Atomic_RW_Mutex) -> bool {
+atomic_rw_mutex_shared_guard :: proc "contextless" (m: ^Atomic_RW_Mutex) -> bool {
 	atomic_rw_mutex_shared_lock(m)
 	atomic_rw_mutex_shared_lock(m)
 	return true
 	return true
 }
 }
@@ -228,7 +228,7 @@ Atomic_Recursive_Mutex :: struct {
 	mutex: Mutex,
 	mutex: Mutex,
 }
 }
 
 
-atomic_recursive_mutex_lock :: proc(m: ^Atomic_Recursive_Mutex) {
+atomic_recursive_mutex_lock :: proc "contextless" (m: ^Atomic_Recursive_Mutex) {
 	tid := current_thread_id()
 	tid := current_thread_id()
 	if tid != m.owner {
 	if tid != m.owner {
 		mutex_lock(&m.mutex)
 		mutex_lock(&m.mutex)
@@ -238,9 +238,9 @@ atomic_recursive_mutex_lock :: proc(m: ^Atomic_Recursive_Mutex) {
 	m.recursion += 1
 	m.recursion += 1
 }
 }
 
 
-atomic_recursive_mutex_unlock :: proc(m: ^Atomic_Recursive_Mutex) {
+atomic_recursive_mutex_unlock :: proc "contextless" (m: ^Atomic_Recursive_Mutex) {
 	tid := current_thread_id()
 	tid := current_thread_id()
-	assert(tid == m.owner)
+	_assert(tid == m.owner, "tid != m.owner")
 	m.recursion -= 1
 	m.recursion -= 1
 	recursion := m.recursion
 	recursion := m.recursion
 	if recursion == 0 {
 	if recursion == 0 {
@@ -253,7 +253,7 @@ atomic_recursive_mutex_unlock :: proc(m: ^Atomic_Recursive_Mutex) {
 
 
 }
 }
 
 
-atomic_recursive_mutex_try_lock :: proc(m: ^Atomic_Recursive_Mutex) -> bool {
+atomic_recursive_mutex_try_lock :: proc "contextless" (m: ^Atomic_Recursive_Mutex) -> bool {
 	tid := current_thread_id()
 	tid := current_thread_id()
 	if m.owner == tid {
 	if m.owner == tid {
 		return mutex_try_lock(&m.mutex)
 		return mutex_try_lock(&m.mutex)
@@ -274,7 +274,7 @@ Example:
 	}
 	}
 */
 */
 @(deferred_in=atomic_recursive_mutex_unlock)
 @(deferred_in=atomic_recursive_mutex_unlock)
-atomic_recursive_mutex_guard :: proc(m: ^Atomic_Recursive_Mutex) -> bool {
+atomic_recursive_mutex_guard :: proc "contextless" (m: ^Atomic_Recursive_Mutex) -> bool {
 	atomic_recursive_mutex_lock(m)
 	atomic_recursive_mutex_lock(m)
 	return true
 	return true
 }
 }
@@ -289,7 +289,7 @@ Atomic_Cond :: struct {
 	state: Futex,
 	state: Futex,
 }
 }
 
 
-atomic_cond_wait :: proc(c: ^Atomic_Cond, m: ^Atomic_Mutex) {
+atomic_cond_wait :: proc "contextless" (c: ^Atomic_Cond, m: ^Atomic_Mutex) {
 	state := u32(atomic_load_explicit(&c.state, .Relaxed))
 	state := u32(atomic_load_explicit(&c.state, .Relaxed))
 	unlock(m)
 	unlock(m)
 	futex_wait(&c.state, state)
 	futex_wait(&c.state, state)
@@ -297,7 +297,7 @@ atomic_cond_wait :: proc(c: ^Atomic_Cond, m: ^Atomic_Mutex) {
 
 
 }
 }
 
 
-atomic_cond_wait_with_timeout :: proc(c: ^Atomic_Cond, m: ^Atomic_Mutex, duration: time.Duration) -> (ok: bool) {
+atomic_cond_wait_with_timeout :: proc "contextless" (c: ^Atomic_Cond, m: ^Atomic_Mutex, duration: time.Duration) -> (ok: bool) {
 	state := u32(atomic_load_explicit(&c.state, .Relaxed))
 	state := u32(atomic_load_explicit(&c.state, .Relaxed))
 	unlock(m)
 	unlock(m)
 	ok = futex_wait_with_timeout(&c.state, state, duration)
 	ok = futex_wait_with_timeout(&c.state, state, duration)
@@ -306,12 +306,12 @@ atomic_cond_wait_with_timeout :: proc(c: ^Atomic_Cond, m: ^Atomic_Mutex, duratio
 }
 }
 
 
 
 
-atomic_cond_signal :: proc(c: ^Atomic_Cond) {
+atomic_cond_signal :: proc "contextless" (c: ^Atomic_Cond) {
 	atomic_add_explicit(&c.state, 1, .Release)
 	atomic_add_explicit(&c.state, 1, .Release)
 	futex_signal(&c.state)
 	futex_signal(&c.state)
 }
 }
 
 
-atomic_cond_broadcast :: proc(c: ^Atomic_Cond) {
+atomic_cond_broadcast :: proc "contextless" (c: ^Atomic_Cond) {
 	atomic_add_explicit(&c.state, 1, .Release)
 	atomic_add_explicit(&c.state, 1, .Release)
 	futex_broadcast(&c.state)
 	futex_broadcast(&c.state)
 }
 }
@@ -324,7 +324,7 @@ Atomic_Sema :: struct {
 	count: Futex,
 	count: Futex,
 }
 }
 
 
-atomic_sema_post :: proc(s: ^Atomic_Sema, count := 1) {
+atomic_sema_post :: proc "contextless" (s: ^Atomic_Sema, count := 1) {
 	atomic_add_explicit(&s.count, Futex(count), .Release)
 	atomic_add_explicit(&s.count, Futex(count), .Release)
 	if count == 1 {
 	if count == 1 {
 		futex_signal(&s.count)
 		futex_signal(&s.count)
@@ -333,7 +333,7 @@ atomic_sema_post :: proc(s: ^Atomic_Sema, count := 1) {
 	}
 	}
 }
 }
 
 
-atomic_sema_wait :: proc(s: ^Atomic_Sema) {
+atomic_sema_wait :: proc "contextless" (s: ^Atomic_Sema) {
 	for {
 	for {
 		original_count := atomic_load_explicit(&s.count, .Relaxed)
 		original_count := atomic_load_explicit(&s.count, .Relaxed)
 		for original_count == 0 {
 		for original_count == 0 {
@@ -346,7 +346,7 @@ atomic_sema_wait :: proc(s: ^Atomic_Sema) {
 	}
 	}
 }
 }
 
 
-atomic_sema_wait_with_timeout :: proc(s: ^Atomic_Sema, duration: time.Duration) -> bool {
+atomic_sema_wait_with_timeout :: proc "contextless" (s: ^Atomic_Sema, duration: time.Duration) -> bool {
 	if duration <= 0 {
 	if duration <= 0 {
 		return false
 		return false
 	}
 	}

+ 19 - 19
core/sync/primitives_internal.odin

@@ -7,15 +7,15 @@ _Sema :: struct {
 	atomic: Atomic_Sema,
 	atomic: Atomic_Sema,
 }
 }
 
 
-_sema_post :: proc(s: ^Sema, count := 1) {
+_sema_post :: proc "contextless" (s: ^Sema, count := 1) {
 	atomic_sema_post(&s.impl.atomic, count)
 	atomic_sema_post(&s.impl.atomic, count)
 }
 }
 
 
-_sema_wait :: proc(s: ^Sema) {
+_sema_wait :: proc "contextless" (s: ^Sema) {
 	atomic_sema_wait(&s.impl.atomic)
 	atomic_sema_wait(&s.impl.atomic)
 }
 }
 
 
-_sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool {
+_sema_wait_with_timeout :: proc "contextless" (s: ^Sema, duration: time.Duration) -> bool {
 	return atomic_sema_wait_with_timeout(&s.impl.atomic, duration)
 	return atomic_sema_wait_with_timeout(&s.impl.atomic, duration)
 }
 }
 
 
@@ -25,7 +25,7 @@ _Recursive_Mutex :: struct {
 	recursion: i32,
 	recursion: i32,
 }
 }
 
 
-_recursive_mutex_lock :: proc(m: ^Recursive_Mutex) {
+_recursive_mutex_lock :: proc "contextless" (m: ^Recursive_Mutex) {
 	tid := Futex(current_thread_id())
 	tid := Futex(current_thread_id())
 	for {
 	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)
@@ -40,7 +40,7 @@ _recursive_mutex_lock :: proc(m: ^Recursive_Mutex) {
 	}
 	}
 }
 }
 
 
-_recursive_mutex_unlock :: proc(m: ^Recursive_Mutex) {
+_recursive_mutex_unlock :: proc "contextless" (m: ^Recursive_Mutex) {
 	m.impl.recursion -= 1
 	m.impl.recursion -= 1
 	if m.impl.recursion != 0 {
 	if m.impl.recursion != 0 {
 		return
 		return
@@ -52,7 +52,7 @@ _recursive_mutex_unlock :: proc(m: ^Recursive_Mutex) {
 
 
 }
 }
 
 
-_recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool {
+_recursive_mutex_try_lock :: proc "contextless" (m: ^Recursive_Mutex) -> bool {
 	tid := Futex(current_thread_id())
 	tid := Futex(current_thread_id())
 	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 {
@@ -70,15 +70,15 @@ when ODIN_OS != .Windows {
 		mutex: Atomic_Mutex,
 		mutex: Atomic_Mutex,
 	}
 	}
 
 
-	_mutex_lock :: proc(m: ^Mutex) {
+	_mutex_lock :: proc "contextless" (m: ^Mutex) {
 		atomic_mutex_lock(&m.impl.mutex)
 		atomic_mutex_lock(&m.impl.mutex)
 	}
 	}
 
 
-	_mutex_unlock :: proc(m: ^Mutex) {
+	_mutex_unlock :: proc "contextless" (m: ^Mutex) {
 		atomic_mutex_unlock(&m.impl.mutex)
 		atomic_mutex_unlock(&m.impl.mutex)
 	}
 	}
 
 
-	_mutex_try_lock :: proc(m: ^Mutex) -> bool {
+	_mutex_try_lock :: proc "contextless" (m: ^Mutex) -> bool {
 		return atomic_mutex_try_lock(&m.impl.mutex)
 		return atomic_mutex_try_lock(&m.impl.mutex)
 	}
 	}
 
 
@@ -86,19 +86,19 @@ when ODIN_OS != .Windows {
 		cond: Atomic_Cond,
 		cond: Atomic_Cond,
 	}
 	}
 
 
-	_cond_wait :: proc(c: ^Cond, m: ^Mutex) {
+	_cond_wait :: proc "contextless" (c: ^Cond, m: ^Mutex) {
 		atomic_cond_wait(&c.impl.cond, &m.impl.mutex)
 		atomic_cond_wait(&c.impl.cond, &m.impl.mutex)
 	}
 	}
 
 
-	_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool {
+	_cond_wait_with_timeout :: proc "contextless" (c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool {
 		return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration)
 		return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration)
 	}
 	}
 
 
-	_cond_signal :: proc(c: ^Cond) {
+	_cond_signal :: proc "contextless" (c: ^Cond) {
 		atomic_cond_signal(&c.impl.cond)
 		atomic_cond_signal(&c.impl.cond)
 	}
 	}
 
 
-	_cond_broadcast :: proc(c: ^Cond) {
+	_cond_broadcast :: proc "contextless" (c: ^Cond) {
 		atomic_cond_broadcast(&c.impl.cond)
 		atomic_cond_broadcast(&c.impl.cond)
 	}
 	}
 
 
@@ -107,27 +107,27 @@ when ODIN_OS != .Windows {
 		mutex: Atomic_RW_Mutex,
 		mutex: Atomic_RW_Mutex,
 	}
 	}
 
 
-	_rw_mutex_lock :: proc(rw: ^RW_Mutex) {
+	_rw_mutex_lock :: proc "contextless" (rw: ^RW_Mutex) {
 		atomic_rw_mutex_lock(&rw.impl.mutex)
 		atomic_rw_mutex_lock(&rw.impl.mutex)
 	}
 	}
 
 
-	_rw_mutex_unlock :: proc(rw: ^RW_Mutex) {
+	_rw_mutex_unlock :: proc "contextless" (rw: ^RW_Mutex) {
 		atomic_rw_mutex_unlock(&rw.impl.mutex)
 		atomic_rw_mutex_unlock(&rw.impl.mutex)
 	}
 	}
 
 
-	_rw_mutex_try_lock :: proc(rw: ^RW_Mutex) -> bool {
+	_rw_mutex_try_lock :: proc "contextless" (rw: ^RW_Mutex) -> bool {
 		return atomic_rw_mutex_try_lock(&rw.impl.mutex)
 		return atomic_rw_mutex_try_lock(&rw.impl.mutex)
 	}
 	}
 
 
-	_rw_mutex_shared_lock :: proc(rw: ^RW_Mutex) {
+	_rw_mutex_shared_lock :: proc "contextless" (rw: ^RW_Mutex) {
 		atomic_rw_mutex_shared_lock(&rw.impl.mutex)
 		atomic_rw_mutex_shared_lock(&rw.impl.mutex)
 	}
 	}
 
 
-	_rw_mutex_shared_unlock :: proc(rw: ^RW_Mutex) {
+	_rw_mutex_shared_unlock :: proc "contextless" (rw: ^RW_Mutex) {
 		atomic_rw_mutex_shared_unlock(&rw.impl.mutex)
 		atomic_rw_mutex_shared_unlock(&rw.impl.mutex)
 	}
 	}
 
 
-	_rw_mutex_try_shared_lock :: proc(rw: ^RW_Mutex) -> bool {
+	_rw_mutex_try_shared_lock :: proc "contextless" (rw: ^RW_Mutex) -> bool {
 		return atomic_rw_mutex_try_shared_lock(&rw.impl.mutex)
 		return atomic_rw_mutex_try_shared_lock(&rw.impl.mutex)
 	}
 	}
 }
 }

+ 13 - 13
core/sync/primitives_windows.odin

@@ -13,15 +13,15 @@ _Mutex :: struct {
 	srwlock: win32.SRWLOCK,
 	srwlock: win32.SRWLOCK,
 }
 }
 
 
-_mutex_lock :: proc(m: ^Mutex) {
+_mutex_lock :: proc "contextless" (m: ^Mutex) {
 	win32.AcquireSRWLockExclusive(&m.impl.srwlock)
 	win32.AcquireSRWLockExclusive(&m.impl.srwlock)
 }
 }
 
 
-_mutex_unlock :: proc(m: ^Mutex) {
+_mutex_unlock :: proc "contextless" (m: ^Mutex) {
 	win32.ReleaseSRWLockExclusive(&m.impl.srwlock)
 	win32.ReleaseSRWLockExclusive(&m.impl.srwlock)
 }
 }
 
 
-_mutex_try_lock :: proc(m: ^Mutex) -> bool {
+_mutex_try_lock :: proc "contextless" (m: ^Mutex) -> bool {
 	return bool(win32.TryAcquireSRWLockExclusive(&m.impl.srwlock))
 	return bool(win32.TryAcquireSRWLockExclusive(&m.impl.srwlock))
 }
 }
 
 
@@ -29,27 +29,27 @@ _RW_Mutex :: struct {
 	srwlock: win32.SRWLOCK,
 	srwlock: win32.SRWLOCK,
 }
 }
 
 
-_rw_mutex_lock :: proc(rw: ^RW_Mutex) {
+_rw_mutex_lock :: proc "contextless" (rw: ^RW_Mutex) {
 	win32.AcquireSRWLockExclusive(&rw.impl.srwlock)
 	win32.AcquireSRWLockExclusive(&rw.impl.srwlock)
 }
 }
 
 
-_rw_mutex_unlock :: proc(rw: ^RW_Mutex) {
+_rw_mutex_unlock :: proc "contextless" (rw: ^RW_Mutex) {
 	win32.ReleaseSRWLockExclusive(&rw.impl.srwlock)
 	win32.ReleaseSRWLockExclusive(&rw.impl.srwlock)
 }
 }
 
 
-_rw_mutex_try_lock :: proc(rw: ^RW_Mutex) -> bool {
+_rw_mutex_try_lock :: proc "contextless" (rw: ^RW_Mutex) -> bool {
 	return bool(win32.TryAcquireSRWLockExclusive(&rw.impl.srwlock))
 	return bool(win32.TryAcquireSRWLockExclusive(&rw.impl.srwlock))
 }
 }
 
 
-_rw_mutex_shared_lock :: proc(rw: ^RW_Mutex) {
+_rw_mutex_shared_lock :: proc "contextless" (rw: ^RW_Mutex) {
 	win32.AcquireSRWLockShared(&rw.impl.srwlock)
 	win32.AcquireSRWLockShared(&rw.impl.srwlock)
 }
 }
 
 
-_rw_mutex_shared_unlock :: proc(rw: ^RW_Mutex) {
+_rw_mutex_shared_unlock :: proc "contextless" (rw: ^RW_Mutex) {
 	win32.ReleaseSRWLockShared(&rw.impl.srwlock)
 	win32.ReleaseSRWLockShared(&rw.impl.srwlock)
 }
 }
 
 
-_rw_mutex_try_shared_lock :: proc(rw: ^RW_Mutex) -> bool {
+_rw_mutex_try_shared_lock :: proc "contextless" (rw: ^RW_Mutex) -> bool {
 	return bool(win32.TryAcquireSRWLockShared(&rw.impl.srwlock))
 	return bool(win32.TryAcquireSRWLockShared(&rw.impl.srwlock))
 }
 }
 
 
@@ -58,22 +58,22 @@ _Cond :: struct {
 	cond: win32.CONDITION_VARIABLE,
 	cond: win32.CONDITION_VARIABLE,
 }
 }
 
 
-_cond_wait :: proc(c: ^Cond, m: ^Mutex) {
+_cond_wait :: proc "contextless" (c: ^Cond, m: ^Mutex) {
 	_ = win32.SleepConditionVariableSRW(&c.impl.cond, &m.impl.srwlock, win32.INFINITE, 0)
 	_ = win32.SleepConditionVariableSRW(&c.impl.cond, &m.impl.srwlock, win32.INFINITE, 0)
 }
 }
 
 
-_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool {
+_cond_wait_with_timeout :: proc "contextless" (c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool {
 	duration := u32(duration / time.Millisecond)
 	duration := u32(duration / time.Millisecond)
 	ok := win32.SleepConditionVariableSRW(&c.impl.cond, &m.impl.srwlock, duration, 0)
 	ok := win32.SleepConditionVariableSRW(&c.impl.cond, &m.impl.srwlock, duration, 0)
 	return bool(ok)
 	return bool(ok)
 }
 }
 
 
 
 
-_cond_signal :: proc(c: ^Cond) {
+_cond_signal :: proc "contextless" (c: ^Cond) {
 	win32.WakeConditionVariable(&c.impl.cond)
 	win32.WakeConditionVariable(&c.impl.cond)
 }
 }
 
 
-_cond_broadcast :: proc(c: ^Cond) {
+_cond_broadcast :: proc "contextless" (c: ^Cond) {
 	win32.WakeAllConditionVariable(&c.impl.cond)
 	win32.WakeAllConditionVariable(&c.impl.cond)
 }
 }