mutex: Add TryLock() variants.

This commit is contained in:
Jules Blok 2018-02-27 15:34:09 +01:00 committed by plutoo
parent a622ae5593
commit e966f21800
2 changed files with 43 additions and 0 deletions

View File

@ -29,6 +29,13 @@ static inline void mutexInit(Mutex* m)
*/
void mutexLock(Mutex* m);
/**
* @brief Attempts to lock a mutex without waiting.
* @param m Mutex object.
* @return 1 if the mutex has been acquired successfully, and 0 on contention.
*/
u32 mutexTryLock(Mutex* m);
/**
* @brief Unlocks a mutex.
* @param m Mutex object.
@ -53,6 +60,13 @@ static inline void rmutexInit(RMutex* m)
*/
void rmutexLock(RMutex* m);
/**
* @brief Attempts to lock a recursive mutex without waiting.
* @param m Recursive mutex object.
* @return 1 if the mutex has been acquired successfully, and 0 on contention.
*/
u32 rmutexTryLock(RMutex* m);
/**
* @brief Unlocks a recursive mutex.
* @param m Recursive mutex object.

View File

@ -41,6 +41,23 @@ void mutexLock(Mutex* m) {
}
}
u32 mutexTryLock(Mutex* m) {
u32 self = _GetTag();
u32 cur = __sync_val_compare_and_swap((u32*)m, 0, self);
if (cur == 0) {
// We won the race!
return 1;
}
if ((cur &~ HAS_LISTENERS) == self) {
// Kernel assigned it to us!
return 1;
}
return 0;
}
void mutexUnlock(Mutex* m) {
u32 old = __sync_lock_test_and_set((u32*)m, 0);
@ -58,6 +75,18 @@ void rmutexLock(RMutex* m) {
m->counter++;
}
u32 rmutexTryLock(RMutex* m) {
if (m->thread_tag != _GetTag()) {
if (!mutexTryLock(&m->lock)) {
return 0;
}
m->thread_tag = _GetTag();
}
m->counter++;
return 1;
}
void rmutexUnlock(RMutex* m) {
if (--m->counter == 0) {
m->thread_tag = 0;