Re: RFA [threads]: Thread cache

Daniel Jacobowitz
2003-01-14T00:27:45Z

On Mon, Jan 13, 2003 at 04:04:20PM -0800, Michael Snyder wrote:
> Daniel Jacobowitz wrote:
> >
> > On Sat, Jan 11, 2003 at 01:13:55PM +0100, Mark Kettenis wrote:
> > > Daniel Jacobowitz <drow@mvista.com> writes:
> > >
> > > > I've figured out how to fix print-threads.exp (see my ramblings on gdb@
> > > > yesterday for a bad description of the problem; better coming soon).
> > > > However, to do it, I discovered that it was actually _required_ that we
> > > > cache certain information from libthread_db, instead of merely beneficial.
> > > >
> > > > So I implemented the cache. This patch is the entire cache mechanism,
> > > > except for updating the comment at the top of the file saying we need one.
> > > > Before I get to the patch itself, some numbers:
> > >
> > > This looks good! Please check it in, regardless of the things I say
> > > further on in this message.
> > >
> > > > Now, on to the patch itself. I replace all calls to td_ta_map_id2thr_p
> > > > and most calls to td_thr_get_info_p [Hmm, I don't see any reason not to
> > > > convert the others too; I will do that in a separate patch if this one is
> > > > approved, and see how much more it takes off the runtime] with calls to
> > > > wrapper functions which cache the data in the struct private_thread_info.
> > > > The cache is invalidated at every resume(); there's some information that we
> > > > could keep if we are guaranteed a 1-to-1 threads implementation with no
> > > > migration, like LinuxThreads or NPTL, but I'm being conservative for now.
> > >
> > > Note that the thread_db.h interface provides TD_SWITCHTO and
> > > TD_SWITCHFROM events. I'd be perfectly happy if you'd cache info
> > > about the LWP a particular user-level thread is bound to if you'd
> > > invalidate this info upon receiving those events (which should never
> > > happen in a 1-to-1 threads implementation.
> > >
> > > That said, would re-enabling TD_DEATH events somehow make things more
> > > robust for you? TD_DEATH was broken in glibc 2.1.3, but anybody who's
> > > doing any serious threads development should be using a more recent
> > > glibc.
> >
> > I don't think that TD_DEATH would solve the problem. Let me check when
> > they're actually delivered... no, TD_DEATH is reported immediately
> > before the terminated flag is set, i.e. the thread becomes a "zombie".
> > The problem is that we need to continue debugging the thread until it's
> > actually _gone_. Hmm, enabling TD_DEATH might be useful in that it
> > would simplify the ad-hoc-ness of the zombie handling; it could prevent
> > having to iterate over all LWPs, which would be nice. I'll thik about
> > it.
>
> If we think that the TD_DEATH event is coming at the wrong time,
> we can certainly ask the glibc maintainers to change it.
> GDB is the only consumer so far...

We could probably use TD_REAP for some of this also.

> > Now, relying on SWITCHTO/SWITCHFROM has some potential. The difficulty
> > is that using them would slow down debugging of a M-to-N implementation
> > substantially, I wager. But we could at least do something like "assume
> > 1-to-1 for caching purposes until we get a SWITCHTO/SWITCHFROM". Hmm,
> > I need to think about that too.
>
> Insider info -- glibc is extremely unlikely to ever switch
> to an m-by-n model. I've talked with Uli Drepper, and although
> he once planned on doing that, he now believes that there is no
> possible gain to be had from it, and that it's an essentially
> faulty approach.

Yep. However, as much as I may personally avoid it, NGPT has some
current backing; it works with our current thread-db code, more or
less. (I'm going on hearsay here; I haven't tested it so I don't know
how good the support is.) Do we want it to keep working?

> > Is there formal documentation for the libthread_db interface somewhere?
> > Glibc certainly doesn't have any.
>
> Log into a solaris box and do "man libthread_db".

Ah, that's something at least.

> > For instance, I'd like to know if I
> > can safely cache the thread handles across resumes;
>
> Even if that happened to be safe now, it would be an
> extremely bad assumption that it would continue to be
> safe.
>
> > if I could, this
> > would be much much much much easier to do efficiently. We could get
> > the thread handle and LWP when the thread is created, and then hold the
> > thread handle, and optionally hold the LWP. I am pretty sure this is
> > safe given glibc, but I don't know in general.
>
> I think in general not.

Hmm. The Solaris documentation suggests that this is valid; I have no
way to check whether it actually is, and there is no explicit
description of the lifetime of a thread handle, but it doesn't describe
them as being of limited life. It's a handle to "the thread object"
itself.

Do you think that we could arrange for this assumption to continue
holding? I think it will in the glibc implementation, for a while at
least, because just the thread agent and pthread_descr are used as the
thread handle; the pthread_descr can't change in the lifetime of a
thread.

>
> Michael
>
> PS: Do ask me questions like this -- I've had extensive talks with
> Uli about libthread_db. He and I basically implemented it together
> (him on the glibc side, me on the gdb side).

Aha, perfect!