Optimizing synchronization objects

Daniel Santos daniel.santos at pobox.com
Mon Sep 14 03:02:57 CDT 2015


On 09/14/2015 02:18 AM, Alexandre Julliard wrote:
> Daniel Santos <daniel.santos at pobox.com> writes:
>
>> As you can see this can get more complicated. If the server discovers
>> that an server object isn't signaled it will have to notify the client
>> to rollback the locks and wait for server objects to be ready.
>>
>> So which of these solution is most appealing to you?
> None of them, really.
>
> Using shared memory means you'll need one page per object, because you
> can't allow a process to corrupt the state of unrelated objects. This
> doesn't scale.

I have considered this as well, and my idea was to have a shared page 
(or set of pages if needed) for each unique combination of processes 
that are sharing objects. Then these pages will only contain objects 
that are shared by all of those processes. The synchronization object in 
private memory is then "moved" (or just redirects) to the new object in 
shared memory and any threads waiting on the old one are signaled and a 
flag in the old object informs them of the move, so they can start over 
on the new object. Actually, the original object doesn't go away, it 
just becomes a proxy. This can happen again if the sharing scheme 
changes to involve another process, except that the now-intermediary 
object can actually be "deleted" once there are no more references to it 
(not really a call to free() of course).
> SysV synchronization objects are broken in various ways and should be
> avoided.

That's good to know!
>
> I think the most promising approach would be to add a process-local
> cache for objects that don't need inter-process synchronization. As soon
> as the object needs complex work that involves the server or another
> process (DuplicateHandle, WaitForMultipleObjects, named objects, etc.)
> it graduates to a full server object, and from then on goes through the
> normal path. This should cover the most performance-critical cases.
>

That is actually a wonderful idea! The struct ntdll_object & associated 
rbtree and list added to om.c in the patch set is exactly for this 
process-level cache. Rather the object is inter-process or not can just 
be data in that cache object. This would seem to add the most for the 
least complexity and exposure to security and corruption issues. This 
approach should fix most performance issues and still be very simple! :) 
Thanks!

I was going to have to ask about the message queues needing to have 
their signaled() functions called during a select call (which was a 
complication I hadn't mentioned) but this avoids that issues now.

Daniel






More information about the wine-devel mailing list