mirror of
https://github.com/switchbrew/libnx.git
synced 2025-07-06 11:22:15 +02:00
implemented mutex error checking
This commit is contained in:
parent
e9cc565e92
commit
4c2102f06d
@ -26,8 +26,9 @@ static inline void mutexInit(Mutex* m)
|
|||||||
/**
|
/**
|
||||||
* @brief Locks a mutex.
|
* @brief Locks a mutex.
|
||||||
* @param m Mutex object.
|
* @param m Mutex object.
|
||||||
|
* @return 0 if the mutex is already owned by this thread, and 1 if it was sucessfully acquired.
|
||||||
*/
|
*/
|
||||||
void mutexLock(Mutex* m);
|
bool mutexLock(Mutex* m);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Attempts to lock a mutex without waiting.
|
* @brief Attempts to lock a mutex without waiting.
|
||||||
@ -39,8 +40,9 @@ bool mutexTryLock(Mutex* m);
|
|||||||
/**
|
/**
|
||||||
* @brief Unlocks a mutex.
|
* @brief Unlocks a mutex.
|
||||||
* @param m Mutex object.
|
* @param m Mutex object.
|
||||||
|
* @return 1 if the mutex was released, and 0 if the mutex does not belong to this thread.
|
||||||
*/
|
*/
|
||||||
void mutexUnlock(Mutex* m);
|
bool mutexUnlock(Mutex* m);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes a recursive mutex.
|
* @brief Initializes a recursive mutex.
|
||||||
|
@ -9,20 +9,21 @@ static u32 _GetTag(void) {
|
|||||||
return getThreadVars()->handle;
|
return getThreadVars()->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mutexLock(Mutex* m) {
|
bool mutexLock(Mutex* m) {
|
||||||
u32 self = _GetTag();
|
u32 self = _GetTag();
|
||||||
|
|
||||||
|
bool first = false;
|
||||||
while (1) {
|
while (1) {
|
||||||
u32 cur = __sync_val_compare_and_swap((u32*)m, 0, self);
|
u32 cur = __sync_val_compare_and_swap((u32*)m, 0, self);
|
||||||
|
|
||||||
if (cur == 0) {
|
if (cur == 0) {
|
||||||
// We won the race!
|
// We won the race!
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cur &~ HAS_LISTENERS) == self) {
|
if ((cur &~ HAS_LISTENERS) == self) {
|
||||||
// Kernel assigned it to us!
|
// Kernel assigned it to us!
|
||||||
return;
|
return !first;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur & HAS_LISTENERS) {
|
if (cur & HAS_LISTENERS) {
|
||||||
@ -38,6 +39,8 @@ void mutexLock(Mutex* m) {
|
|||||||
svcArbitrateLock(cur, (u32*)m, self);
|
svcArbitrateLock(cur, (u32*)m, self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
first = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,11 +61,20 @@ bool mutexTryLock(Mutex* m) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mutexUnlock(Mutex* m) {
|
bool mutexUnlock(Mutex* m) {
|
||||||
u32 old = __sync_val_compare_and_swap((u32*)m, _GetTag(), 0);
|
u32 self = _GetTag();
|
||||||
|
u32 old = __sync_val_compare_and_swap((u32*)m, self, 0);
|
||||||
|
|
||||||
if (old & HAS_LISTENERS) {
|
if ((old &~ HAS_LISTENERS) == self) {
|
||||||
svcArbitrateUnlock((u32*)m);
|
if (old & HAS_LISTENERS) {
|
||||||
|
svcArbitrateUnlock((u32*)m);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// The mutex doesn't belong to us
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user