This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Improvements to fork handling (2/5)


On 21/05/2011 9:44 PM, Christopher Faylor wrote:
On Wed, May 11, 2011 at 02:31:37PM -0400, Ryan Johnson wrote:
Hi all,

This patch has the parent sort its dll list topologically by
dependencies. Previously, attempts to load a DLL_LOAD dll risked pulling
in dependencies automatically, and the latter would then not benefit
>from the code which "encourages" them to land in the right places. The
dependency tracking is achieved using a simple class which allows to
introspect a mapped dll image and pull out the dependencies it lists.
The code currently rebuilds the dependency list at every fork rather
than attempt to update it properly as modules are loaded and unloaded.
Note that the topsort optimization affects only cygwin dlls, so any
windows dlls which are pulled in dynamically (directly or indirectly)
will still impose the usual risk of address space clobbers.
This seems CPU and memory intensive during a time for which we already
know is very slow.  Is the benefit really worth it?  How much more robust
does it make forking?
Topological sorting is O(n), so there's no asymptotic change in performance. Looking up dependencies inside a dll is *very* cheap (2-3 pointer dereferences per dep), and all of this only happens for dynamically-loaded dlls. Given the number of calls to Virtual{Alloc,Query,Free} and LoadDynamicLibraryEx which we make, I would be surprised if the topsort even registered. That said, it is extra work and will slow down fork.

I have not been able to test how much it helps, but it should help with the test case Jon Turney reported with python a while back [1]. In fact, it was that example which made me aware of the potential need for a topsort in the first place.

In theory, this should completely eliminate the case where us loading one DLL pulls in dependencies automatically (= uncontrolled and at Windows' whim). The problem would manifest as a DLL which "loads" in the same wrong place repeatedly when given the choice, and for which we would be unable to VirtualAlloc the offending spot (because the dll in question has non-zero refcount even after we unload it, due to the dll(s) that depend on it. The currently checked-in code would not detect this case, because inability to VirtualAlloc just causes ReserveAt and ReserveUpto to skip that spot silently.

[1] http://cygwin.com/ml/cygwin/2011-04/msg00054.html

Ryan


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]