Fix memory ordering on mutex acquire

This commit is contained in:
flysand7 2023-09-10 18:12:17 +11:00
parent dc2ec9eb13
commit 362460ac9c
3 changed files with 8 additions and 9 deletions

View File

@ -30,7 +30,7 @@ struct _LD_Thread_Block {
/* +0x10 */ _Atomic(u32) thread_behaviour; /* One of the CIA_THREAD_BEHAVIOR_* constants */
/* +0x14 */ _Atomic(i32) thread_finished;
/* +0x18 */ u32 pad0;
/* +0x1c */ i32 exit_code;
/* +0x1c */ _Atomic(i32) exit_code;
/* +0x20 */ u64 pad1;
/* +0x28 */ u64 stack_canary;
};

View File

@ -65,7 +65,7 @@ void _rt_thread_finish(int exit_code) {
}
// If main thread set this thread to be joined, we signal it that we're done here
if(thread_behaviour == _LD_THREAD_BEHAVIOUR_JOIN) {
tcb->exit_code = exit_code;
atomic_store_explicit(&tcb->exit_code, exit_code, memory_order_relaxed);
atomic_store_explicit(&tcb->thread_finished, 1, memory_order_release);
syscall(SYS_futex, &tcb->thread_finished, FUTEX_WAKE, 0, NULL, 0, 0);
sys_exit(exit_code);
@ -86,7 +86,7 @@ static _RT_Status _rt_thread_join(_RT_Thread *thread, int *out_exit_code) {
syscall(SYS_futex, &tcb->thread_finished, FUTEX_WAIT, 0, NULL, 0, 0);
}
// Set the exit code
*out_exit_code = tcb->exit_code;
*out_exit_code = atomic_load_explicit(&tcb->exit_code, memory_order_acquire);
return _RT_STATUS_OK;
}

View File

@ -10,20 +10,21 @@ void cia_mutex_init(Cia_Mutex *mutex) {
void cia_mutex_lock(Cia_Mutex *mutex) {
u32 p_tag;
for(;;) {
//p_tag = __sync_val_compare_and_swap(&mutex->tag, _CIA_MUTEX_FREE, _CIA_MUTEX_LOCK);
p_tag = _CIA_MUTEX_FREE;
atomic_compare_exchange_strong_explicit(
&mutex->tag
, &p_tag
, _CIA_MUTEX_LOCK
, memory_order_relaxed
, memory_order_acquire
, memory_order_relaxed
);
// We got the mutex, lets bail
if(p_tag == _CIA_MUTEX_FREE) {
break;
}
#if 0
#if 1
_rt_sync_wait(&mutex->tag, _CIA_MUTEX_LOCK, _RT_SYNC_WAIT_INFINITE);
#else
// We should wait if:
// (1) the mutex is contested
// (2)
@ -34,8 +35,6 @@ void cia_mutex_lock(Cia_Mutex *mutex) {
if(should_wait) {
_rt_sync_wait(&mutex->tag, _CIA_MUTEX_CONT, _RT_SYNC_WAIT_INFINITE);
}
#else
_rt_sync_wait(&mutex->tag, _CIA_MUTEX_LOCK, _RT_SYNC_WAIT_INFINITE);
#endif
}
}
@ -43,6 +42,6 @@ void cia_mutex_lock(Cia_Mutex *mutex) {
void cia_mutex_unlock(Cia_Mutex *mutex) {
// TODO: add error when we unlock a free mutex
// TODO: support recursive muteces
atomic_store_explicit(&mutex->tag, _CIA_MUTEX_FREE, memory_order_relaxed);
atomic_store_explicit(&mutex->tag, _CIA_MUTEX_FREE, memory_order_release);
_rt_sync_wake_one(&mutex->tag, NULL);
}