mirror of https://github.com/flysand7/ciabatta.git
Fix mutex
This commit is contained in:
parent
35a760e54e
commit
7929779df6
|
@ -168,7 +168,9 @@ static _RT_Status _rt_sync_wake_one(u32 *addr, u32 *n_woken) {
|
|||
if(result < 0) {
|
||||
return _RT_ERROR_GENERIC;
|
||||
}
|
||||
if(n_woken != NULL) {
|
||||
*n_woken = (u32)result;
|
||||
}
|
||||
return _RT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
@ -177,6 +179,8 @@ static _RT_Status _rt_sync_wake_all(u32 *addr, u32 *n_woken) {
|
|||
if(result < 0) {
|
||||
return _RT_ERROR_GENERIC;
|
||||
}
|
||||
if(n_woken != NULL) {
|
||||
*n_woken = (u32)result;
|
||||
}
|
||||
return _RT_STATUS_OK;
|
||||
}
|
||||
|
|
|
@ -1,21 +1,36 @@
|
|||
|
||||
#define _CIA_MUTEX_TAG_UNLOCKED 0x00000000
|
||||
#define _CIA_MUTEX_TAG_LOCKED 0x00000001
|
||||
#define _CIA_MUTEX_FREE 0
|
||||
#define _CIA_MUTEX_LOCK 1
|
||||
#define _CIA_MUTEX_CONT 2
|
||||
|
||||
void cia_mutex_init(Cia_Mutex *mutex) {
|
||||
mutex->tag = _CIA_MUTEX_TAG_UNLOCKED;
|
||||
mutex->tag = _CIA_MUTEX_FREE;
|
||||
}
|
||||
|
||||
void cia_mutex_lock(Cia_Mutex *mutex) {
|
||||
do {
|
||||
_rt_sync_wait(&mutex->tag, _CIA_MUTEX_TAG_LOCKED, _RT_SYNC_WAIT_INFINITE);
|
||||
} while(mutex->tag == _CIA_MUTEX_TAG_LOCKED);
|
||||
mutex->tag = _CIA_MUTEX_TAG_LOCKED;
|
||||
u64 prev_tag;
|
||||
for(;;) {
|
||||
prev_tag = __sync_val_compare_and_swap(&mutex->tag, _CIA_MUTEX_FREE, _CIA_MUTEX_LOCK);
|
||||
// We got the mutex, lets bail
|
||||
if(prev_tag == _CIA_MUTEX_FREE) {
|
||||
break;
|
||||
}
|
||||
// We should wait if:
|
||||
// (1) the mutex is contested
|
||||
// (2) this thread locking the mutex makes it contested
|
||||
bool should_wait = 0;
|
||||
should_wait |= (prev_tag == _CIA_MUTEX_CONT);
|
||||
should_wait |= (__sync_val_compare_and_swap(&mutex->tag, _CIA_MUTEX_LOCK, _CIA_MUTEX_CONT) != _CIA_MUTEX_FREE);
|
||||
// We wait while its contested
|
||||
if(should_wait) {
|
||||
_rt_sync_wait(&mutex->tag, _CIA_MUTEX_CONT, _RT_SYNC_WAIT_INFINITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cia_mutex_unlock(Cia_Mutex *mutex) {
|
||||
mutex->tag = _CIA_MUTEX_TAG_UNLOCKED;
|
||||
u32 woken = 0;
|
||||
_rt_sync_wake_one(&mutex->tag, &woken);
|
||||
// TODO: add error when we unlock a free mutex
|
||||
// TODO: support recursive muteces
|
||||
mutex->tag = _CIA_MUTEX_FREE;
|
||||
_rt_sync_wake_one(&mutex->tag, NULL);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue