⛏️ index : haiku.git

author Ingo Weinhold <ingo_weinhold@gmx.de> 2010-04-15 21:21:32.0 +00:00:00
committer Ingo Weinhold <ingo_weinhold@gmx.de> 2010-04-15 21:21:32.0 +00:00:00
commit
0dffa8d48e796f01ddc86e2ff2f6665807f822dc [patch]
tree
40afccd685b5c53bcfe59dcc1c0b1709218be278
parent
186058c5170b2a73ad0bdab55f609ed13373c3f2
download
0dffa8d48e796f01ddc86e2ff2f6665807f822dc.tar.gz

* 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(-)

diff --git a/src/system/kernel/locks/user_mutex.cpp b/src/system/kernel/locks/user_mutex.cpp
index be1c3e3..d842bfc 100644
--- a/src/system/kernel/locks/user_mutex.cpp
+++ b/src/system/kernel/locks/user_mutex.cpp
@@ -87,7 +87,7 @@
	// if any, add the next entry to the table.
	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)) {
		// Someone is waiting -- set the locked flag. It might still be set,
		// but when using userland atomic operations, the caller will usually
		// have cleared it already.
		int32 oldValue = atomic_or(mutex, B_USER_MUTEX_LOCKED);

		// unblock the first thread
		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) {
			// unblock all the other waiting threads as well
			for (UserMutexEntryList::Iterator it
					= entry->otherEntries.GetIterator();
@@ -165,6 +170,9 @@
				otherEntry->condition.NotifyOne();
			}
		}
	} else {
		// no one is waiting -- clear locked flag
		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);
}