diff --git a/include/cia-ld/tcb.h b/include/cia-ld/tcb.h index 5eed95d..ac9d926 100644 --- a/include/cia-ld/tcb.h +++ b/include/cia-ld/tcb.h @@ -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; }; diff --git a/os/linux/tinyrt-threads.c b/os/linux/tinyrt-threads.c index d16f83f..21bc468 100644 --- a/os/linux/tinyrt-threads.c +++ b/os/linux/tinyrt-threads.c @@ -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; } diff --git a/src/cia-sync/mutex.c b/src/cia-sync/mutex.c index a065a57..2e4a646 100644 --- a/src/cia-sync/mutex.c +++ b/src/cia-sync/mutex.c @@ -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); }