This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc 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: libstdc++ wants clock_gettime without libpthread


That is a worthy goal and unfortunately it does not have a very simple
solution.

librt unavoidably uses pthread calls because the aio, mq, and timer
interfaces include the (dynamic) possibility of SIGEV_THREAD, which
obviously has to use pthread_create (and could legitimately be used in a
program that didn't make any direct pthread calls itself).

There are several things we could potentially do, but none is without some
kind of complication.

1. Just move clock_* calls into libc.  

   Pro: That solves the problem for libstdc++ with almost no special effort
	at all on the libstdc++ side.  If building libstdc++ just uses -lc
	-Wl,--as-needed -lrt then it will be compatible with old
	installations where you need to get it from librt, and with new
	ones where you can get it from libc and won't generate a DT_NEEDED
	on librt.so.N (without requiring configure-time checks to influence
	the linking details).

   Con: 
   a. It bloats libc.so.N with code, and its permanent ABI with symbols,
      that most applications do not need.
   b. For all configurations that exist today, we'll still need to have
      clock_* symbols in librt.so because of existing binaries' symbol
      version bindings.  With IFUNC we could do this in a way where
      librt.so would not actually duplicate the code and would just resolve
      those symbols using libc.so's definitions.  (But there are still some
      machines where the tools don't support IFUNC at all.)

2. Split librt.so.N into multiple DSOs and make librt.so be a linker script
   using GROUP(AS_NEEDED(librt-clock.so.N librt.so.N)).

   Pro: 
   a. No change whatsoever to libstdc++ and just a recompile would result
      in optimal DSO dependencies just by building against a new -lrt.
   b. Every other applications newly linked with -lrt would get just the
      dependencies it actually needs.

   Con:
   a. Applications or DSOs that use both clock_* and other interfaces from
      -lrt would now have an additional DT_NEEDED entry, with its attendant
      additional overhead in startup time, symbol searches, and the like in
      the dynamic linker, and some additional address space and memory
      overhead from rounding-to-page error in the sizes of the two DSOs and
      dynamic linker data structures.
   b. We'd still need to have clock_* symbols in librt.so.N because of
      existing binaries' DT_NEEDED entries and symbol version bindings.
      With IFUNC tricks it could avoid any actual code duplication, but
      at the cost of librt.so.N having a DT_NEEDED on librt-clock.so.N
      and thus all the aforementioned overhead even for applications that
      use only some other -lrt interfaces and not clock_* interfaces.

3. Figure out some arcane thing with DT_FILTER or something.

   Pro: Potentially avoids the two-DSOs overheads when both aren't really
   needed.

   Con:
   a. Still has the two-DSOs overhead when both are actually used.
   b. Uses dynamic linker features that nobody has really used before
      and are not well-tested.
   c. It might not even be a fit for the semantics of such features such
      that it's not actually possible (with today's dynamic linker).

4. Make librt not depend statically on libpthread, but load it dynamically
   as needed.

   Pro: Avoids libpthread overheads (both generic DSO-loading overheads and
	the overheads of enabling locking and so forth) in applications
	that don't actually need libpthread--even ones using timer_* et al
	interfaces that can't statically be determined not to need it.

   Con:
   a. We're not really sure how well we support loading libpthread
      dynamically, or if it is worth making sure it works.
   b. Even if glibc itself supports it perfectly, it would cause things
      like libstdc++/libgcc's __gthr_active_p to treat the "dynamically
      multi-threaded" case as being single-threaded.  That almost certainly
      breaks the semantics of some legitimate code using SIGEV_THREAD and
      the like (for example C++ code called from a SIGEV_THREAD notifier
      function that interacts in some way with C++ code on the main thread).
      It would certainly be some work in libstdc++ et al to make such cases
      work as they ought to, and it's entirely possible that it's not
      really feasible to make them work at all.

Every approach requires some amount of work in glibc, some perhaps a lot of
work, and some require significant work in libstdc++ and elsewhere.  Even
if infinite labor were instantaneously available, there is no approach that
doesn't have some downside.


Thanks,
Roland


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