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) {
|
if(result < 0) {
|
||||||
return _RT_ERROR_GENERIC;
|
return _RT_ERROR_GENERIC;
|
||||||
}
|
}
|
||||||
|
if(n_woken != NULL) {
|
||||||
*n_woken = (u32)result;
|
*n_woken = (u32)result;
|
||||||
|
}
|
||||||
return _RT_STATUS_OK;
|
return _RT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,6 +179,8 @@ static _RT_Status _rt_sync_wake_all(u32 *addr, u32 *n_woken) {
|
||||||
if(result < 0) {
|
if(result < 0) {
|
||||||
return _RT_ERROR_GENERIC;
|
return _RT_ERROR_GENERIC;
|
||||||
}
|
}
|
||||||
|
if(n_woken != NULL) {
|
||||||
*n_woken = (u32)result;
|
*n_woken = (u32)result;
|
||||||
|
}
|
||||||
return _RT_STATUS_OK;
|
return _RT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,36 @@
|
||||||
|
|
||||||
#define _CIA_MUTEX_TAG_UNLOCKED 0x00000000
|
#define _CIA_MUTEX_FREE 0
|
||||||
#define _CIA_MUTEX_TAG_LOCKED 0x00000001
|
#define _CIA_MUTEX_LOCK 1
|
||||||
|
#define _CIA_MUTEX_CONT 2
|
||||||
|
|
||||||
void cia_mutex_init(Cia_Mutex *mutex) {
|
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) {
|
void cia_mutex_lock(Cia_Mutex *mutex) {
|
||||||
do {
|
u64 prev_tag;
|
||||||
_rt_sync_wait(&mutex->tag, _CIA_MUTEX_TAG_LOCKED, _RT_SYNC_WAIT_INFINITE);
|
for(;;) {
|
||||||
} while(mutex->tag == _CIA_MUTEX_TAG_LOCKED);
|
prev_tag = __sync_val_compare_and_swap(&mutex->tag, _CIA_MUTEX_FREE, _CIA_MUTEX_LOCK);
|
||||||
mutex->tag = _CIA_MUTEX_TAG_LOCKED;
|
// 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) {
|
void cia_mutex_unlock(Cia_Mutex *mutex) {
|
||||||
mutex->tag = _CIA_MUTEX_TAG_UNLOCKED;
|
// TODO: add error when we unlock a free mutex
|
||||||
u32 woken = 0;
|
// TODO: support recursive muteces
|
||||||
_rt_sync_wake_one(&mutex->tag, &woken);
|
mutex->tag = _CIA_MUTEX_FREE;
|
||||||
|
_rt_sync_wake_one(&mutex->tag, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue