public inbox for glibc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "dhatch at ilm dot com" <sourceware-bugzilla@sourceware.org>
To: glibc-bugs@sourceware.org
Subject: [Bug dynamic-link/15310] _dl_sort_fini is O(n^3) causing slow exit when many dsos
Date: Thu, 28 Mar 2013 00:31:00 -0000	[thread overview]
Message-ID: <bug-15310-131-D5nN3rhVfh@http.sourceware.org/bugzilla/> (raw)
In-Reply-To: <bug-15310-131@http.sourceware.org/bugzilla/>

http://sourceware.org/bugzilla/show_bug.cgi?id=15310

--- Comment #9 from Don Hatch <dhatch at ilm dot com> 2013-03-28 00:31:40 UTC ---
(In reply to comment #4)
> On Wed, Mar 27, 2013 at 07:47:46AM +0000, dhatch at ilm dot com wrote:
> > http://sourceware.org/bugzilla/show_bug.cgi?id=15310
> > 
> > This is just a topsort, which can be done simply in O(n) time
> > with no fancy data structures.
> > 
> I do not have domain knowledge to understand what is necessary to
> consider.
> 
> However I could write topsort if I knew dependencies. From code I think
> following pseudocode should work upto possibility that some arrows need
> be reversed.
> 
> add_edge(g,x,y) // add edge from x to y
> topsort(g)      // returns topologic ordering of g
> 
> graph *g; 
> for(k=0;k<nmaps;k++)
>   {
>       /* Add dependencies of the object.  */
>       struct link_map **runp = maps[k]->l_initfini;
>       if (runp != NULL)
>         while (*runp != NULL) 
>           add_edge(g,maps[k],*runp);
> 
>           /* Add relocation dependencies.  */
>       if (__builtin_expect (maps[k]->l_reldeps != NULL, 0))
>         {
>           unsigned int m = maps[k]->l_reldeps->act;
>           struct link_map **relmaps = &maps[k]->l_reldeps->list[0];
>           for (j=0;j<m;j++)
>             add_edge(g,relmaps[k],*runp) 
>         }
>   }
> 
>     memcpy(maps,topsort(g));

That looks essentially right,
although there are a couple of nuances in the existing code.
    - under the comment "Do not handle ld.so in secondary namespace"
      (whatever that means), it ignores a dependency "B depends on A"
      if A!=A->l_real  (but doesn't check whether B!=B->l_real).
      I don't really know what this means, or whether this assymmetry
      is intentional...
      QUESTION: can I just omit all edges involving such items
      altogether, not caring where these items come out
      in the output order?
    - it also ignores "B depends on A" if A->l_idx == -1 (i.e.
IDX_STILL_USED)--
      this one I believe I understand--
      it definitely doesn't matter where such items
      come out in the final sort order.
    - static dependendies should override dynamic ones if there's a conflict.
      I'll do two passes in order to get this right, and more well-behaved
      than the existing code--
      see bug 15311 for details.

I hadn't thought about creating the graph structure explicitly as you
suggest...
arguably that would result in cleaner topsort code, but
I was just going to work directly with the data structure that's
already there instead.
Note that an explicit auxiliary graph representation would have size O(N+E)
(number of nodes plus number of edges)
whereas the size of needed auxiliary structures is currently only O(N)
(making it feasible to allocate them as local variables on the runtime stack)
and I wasn't planning on changing that.

The topsort algorithm will be essentially Tarjan's SCC algorithm:
http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
(actually two passes of it).  This is a bit more involved than
a simple reverse postorder, but keeping SCCs contiguous is desireable
(for one thing, the existing code does it-- furthermore,
it provides some nice well-behavedness between the two passes
that I wouldn't be able to prove otherwise).
Tarjan's algorithm is preferable to Kosaraju's since it doesn't require
explicitly creating the reverse graph.

One other issue/question-- I was assuming a recursive implementation
would be out of the question (due to increased runtime stack requirement);
but I'm finding that an iterative implementation of Tarjan's SCC algorithm
is... well, really unpleasant.
I can do it, but it's no fun, and it won't be any fun
to review or maintain it either.  A recursive implementation
would be MUCH cleaner, simpler, more readable and maintainable.
Any thoughts/feelings on whether it's okay to make it recursive?

-- 
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


  parent reply	other threads:[~2013-03-28  0:31 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-27  7:47 [Bug dynamic-link/15310] New: " dhatch at ilm dot com
2013-03-27  8:12 ` [Bug dynamic-link/15310] " dhatch at ilm dot com
2013-03-27  8:45 ` dhatch at ilm dot com
2013-03-27 12:57 ` carlos at redhat dot com
2013-03-27 14:19 ` ppluzhnikov at google dot com
2013-03-27 20:33 ` dhatch at ilm dot com
2013-03-27 20:50 ` neleai at seznam dot cz
2013-03-27 20:50 ` [Bug dynamic-link/15310] New: " Ondřej Bílka
2013-03-27 21:00 ` [Bug dynamic-link/15310] " carlos at redhat dot com
2013-03-27 21:07 ` carlos at redhat dot com
2013-03-27 21:13 ` law at redhat dot com
2013-03-27 23:44 ` dhatch at ilm dot com
2013-03-28  0:31 ` dhatch at ilm dot com [this message]
2013-03-28  7:42   ` Ondřej Bílka
2013-03-28  7:42 ` neleai at seznam dot cz
2013-03-28 10:00 ` dhatch at ilm dot com
2013-03-28 10:19 ` dhatch at ilm dot com
2013-03-28 17:09 ` law at redhat dot com
2013-03-28 17:31 ` dhatch at ilm dot com
2013-04-02  9:54 ` dhatch at ilm dot com
2013-04-02 11:31   ` Ondřej Bílka
2013-04-02 11:31 ` neleai at seznam dot cz
2013-04-02 13:07 ` dhatch at ilm dot com
2013-04-02 23:37 ` dhatch at ilm dot com
2013-04-03  7:57   ` Ondřej Bílka
2013-04-03  7:57 ` neleai at seznam dot cz
2013-04-06 21:07 ` carlos at redhat dot com
2014-06-13 13:51 ` fweimer at redhat dot com
2014-06-13 18:37 ` fweimer at redhat dot com
2021-10-27 14:58 ` adhemerval.zanella at linaro dot org
2021-10-27 14:59 ` adhemerval.zanella at linaro dot org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-15310-131-D5nN3rhVfh@http.sourceware.org/bugzilla/ \
    --to=sourceware-bugzilla@sourceware.org \
    --cc=glibc-bugs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).