Speeding up wineserver synchronization objects with shared memory

Robert O'Callahan roc+ at cs.cmu.edu
Thu Feb 22 17:47:41 CST 2001


I was just reading WWN and saw this discussion. Here's 
a wacky idea that might or might not work.

The basic idea is to grant ownership of each mutex to 
one Win32 process at a time. Let any thread grab the 
mutex quickly if it belongs to the process that owns 
the mutex. If its process does not own the mutex, then 
it must communicate with the wineserver and the 
wineserver must communicate with the owning process to 
transfer ownership of the mutex from the current owner 
to the requesting thread.

Here's how to implement it. For each Win32 process, for 
each mutex that's been mapped into it using 
DuplicateHandle or whatever, allocate a standard 
shared-memory-based critical section, along with a 
weOwnIt flag that indicates whether we own the mutex or 
not. Processes that don't own the mutex leave their 
critical sections locked. Then implement the operations 
as follows:

AcquireMutex {
retry:
   TryToEnterCriticalSection(); // nonblocking
   if (failed) {
     if (!weOwnIt) {
       wineserver->GiveUsOwnership(); // blocking
       goto retry;
     } else {
       EnterCriticalSection(); // blocking
     }
   }
}

ReleaseMutex {
   LeaveCriticalSection();
}

Then on some other thread in the same address space 
that serves wineserver requests:

WineserverGrantsUsOwnership {
   weOwnIt = true;
   LeaveCriticalSection();
}

WineserverWantsToTakeAwayOwnership {
   EnterCriticalSection();
   weOwnIt = false;
   wineserver->WeHaveGivenUpOwnership();
}

Because the ownership test in AcquireMutex can race, 
the server needs to ignore GiveUsOwnership requests for 
processes that already own the mutex.

It seems like this will be efficient (a lot more 
efficient than a kernel call actually) unless the mutex 
is pingponging between processes, in which case you'll 
be eating lots of context switches anyway.

In terms of safety, a correctly functioning process 
will never complete AcquireMutex unless the wineserver 
has granted it the mutex. A misbehaving process can 
hold the mutex indefinitely or incorrectly think it has 
the mutex, but of course that's true under any scheme. 
When the wineserver terminates a process, it can 
reassign mutex ownership. (So if a process is asked to 
give up the mutex but doesn't, the wineserver can time 
out, kill the process and grant the mutex to someone else).

Rob





More information about the wine-devel mailing list