mirror of https://github.com/flysand7/ciabatta.git
Fix memory ordering on mutex acquire
This commit is contained in:
parent
dc2ec9eb13
commit
362460ac9c
|
@ -30,7 +30,7 @@ struct _LD_Thread_Block {
|
||||||
/* +0x10 */ _Atomic(u32) thread_behaviour; /* One of the CIA_THREAD_BEHAVIOR_* constants */
|
/* +0x10 */ _Atomic(u32) thread_behaviour; /* One of the CIA_THREAD_BEHAVIOR_* constants */
|
||||||
/* +0x14 */ _Atomic(i32) thread_finished;
|
/* +0x14 */ _Atomic(i32) thread_finished;
|
||||||
/* +0x18 */ u32 pad0;
|
/* +0x18 */ u32 pad0;
|
||||||
/* +0x1c */ i32 exit_code;
|
/* +0x1c */ _Atomic(i32) exit_code;
|
||||||
/* +0x20 */ u64 pad1;
|
/* +0x20 */ u64 pad1;
|
||||||
/* +0x28 */ u64 stack_canary;
|
/* +0x28 */ u64 stack_canary;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 main thread set this thread to be joined, we signal it that we're done here
|
||||||
if(thread_behaviour == _LD_THREAD_BEHAVIOUR_JOIN) {
|
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);
|
atomic_store_explicit(&tcb->thread_finished, 1, memory_order_release);
|
||||||
syscall(SYS_futex, &tcb->thread_finished, FUTEX_WAKE, 0, NULL, 0, 0);
|
syscall(SYS_futex, &tcb->thread_finished, FUTEX_WAKE, 0, NULL, 0, 0);
|
||||||
sys_exit(exit_code);
|
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);
|
syscall(SYS_futex, &tcb->thread_finished, FUTEX_WAIT, 0, NULL, 0, 0);
|
||||||
}
|
}
|
||||||
// Set the exit code
|
// 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;
|
return _RT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,20 +10,21 @@ void cia_mutex_init(Cia_Mutex *mutex) {
|
||||||
void cia_mutex_lock(Cia_Mutex *mutex) {
|
void cia_mutex_lock(Cia_Mutex *mutex) {
|
||||||
u32 p_tag;
|
u32 p_tag;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
//p_tag = __sync_val_compare_and_swap(&mutex->tag, _CIA_MUTEX_FREE, _CIA_MUTEX_LOCK);
|
|
||||||
p_tag = _CIA_MUTEX_FREE;
|
p_tag = _CIA_MUTEX_FREE;
|
||||||
atomic_compare_exchange_strong_explicit(
|
atomic_compare_exchange_strong_explicit(
|
||||||
&mutex->tag
|
&mutex->tag
|
||||||
, &p_tag
|
, &p_tag
|
||||||
, _CIA_MUTEX_LOCK
|
, _CIA_MUTEX_LOCK
|
||||||
, memory_order_relaxed
|
, memory_order_acquire
|
||||||
, memory_order_relaxed
|
, memory_order_relaxed
|
||||||
);
|
);
|
||||||
// We got the mutex, lets bail
|
// We got the mutex, lets bail
|
||||||
if(p_tag == _CIA_MUTEX_FREE) {
|
if(p_tag == _CIA_MUTEX_FREE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if 0
|
#if 1
|
||||||
|
_rt_sync_wait(&mutex->tag, _CIA_MUTEX_LOCK, _RT_SYNC_WAIT_INFINITE);
|
||||||
|
#else
|
||||||
// We should wait if:
|
// We should wait if:
|
||||||
// (1) the mutex is contested
|
// (1) the mutex is contested
|
||||||
// (2)
|
// (2)
|
||||||
|
@ -34,8 +35,6 @@ void cia_mutex_lock(Cia_Mutex *mutex) {
|
||||||
if(should_wait) {
|
if(should_wait) {
|
||||||
_rt_sync_wait(&mutex->tag, _CIA_MUTEX_CONT, _RT_SYNC_WAIT_INFINITE);
|
_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
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,6 +42,6 @@ void cia_mutex_lock(Cia_Mutex *mutex) {
|
||||||
void cia_mutex_unlock(Cia_Mutex *mutex) {
|
void cia_mutex_unlock(Cia_Mutex *mutex) {
|
||||||
// TODO: add error when we unlock a free mutex
|
// TODO: add error when we unlock a free mutex
|
||||||
// TODO: support recursive muteces
|
// 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);
|
_rt_sync_wake_one(&mutex->tag, NULL);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue