* remove_user_mutex_entry(): The next entry wasn't removed from its own list. * user_mutex_unlock_locked(): Set or clear the locked flag depending on whether we wake up a waiter. * _user_mutex_switch_lock(): The syscall cannot be restartable.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36319 a95241bf-73f2-0310-859d-f6bbb57e9c96
Diff
src/system/kernel/locks/user_mutex.cpp | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
@@ -87,7 +87,7 @@
sUserMutexTable.Remove(entry);
firstEntry = entry->otherEntries.Head();
firstEntry = entry->otherEntries.RemoveHead();
if (firstEntry != NULL) {
firstEntry->otherEntries.MoveFrom(&entry->otherEntries);
sUserMutexTable.Insert(firstEntry);
@@ -151,12 +151,17 @@
user_mutex_unlock_locked(vint32* mutex, addr_t physicalAddress, uint32 flags)
{
if (UserMutexEntry* entry = sUserMutexTable.Lookup(physicalAddress)) {
int32 oldValue = atomic_or(mutex, B_USER_MUTEX_LOCKED);
entry->locked = true;
entry->condition.NotifyOne();
if ((flags & B_USER_MUTEX_UNBLOCK_ALL) != 0
&& (*mutex & B_USER_MUTEX_DISABLED) != 0) {
|| (oldValue & B_USER_MUTEX_DISABLED) != 0) {
for (UserMutexEntryList::Iterator it
= entry->otherEntries.GetIterator();
@@ -165,6 +170,9 @@
otherEntry->condition.NotifyOne();
}
}
} else {
atomic_and(mutex, ~(int32)B_USER_MUTEX_LOCKED);
}
}
@@ -292,11 +300,7 @@
|| !IS_USER_ADDRESS(toMutex) || (addr_t)toMutex % 4 != 0) {
return B_BAD_ADDRESS;
}
syscall_restart_handle_timeout_pre(flags, timeout);
status_t error = user_mutex_switch_lock(fromMutex, toMutex, name,
return user_mutex_switch_lock(fromMutex, toMutex, name,
flags | B_CAN_INTERRUPT, timeout);
return syscall_restart_handle_timeout_post(error, timeout);
}