Boost logo

Boost :

From: Michael Glassford (glassfordm_at_[hidden])
Date: 2004-06-04 15:52:57


"Johan Nilsson" <johan.nilsson_at_[hidden]> wrote in message
news:c9pn3h$q4a$1_at_sea.gmane.org...
>
> "Michael Glassford" <glassfordm_at_[hidden]> wrote in message
> news:c9nemm$gt8$1_at_sea.gmane.org...
> > "Johan Nilsson" <johan.nilsson_at_[hidden]> wrote in message
> > news:c9mk92$815$1_at_sea.gmane.org...
> > >
> > > "Michael Glassford" <glassfordm_at_[hidden]> wrote in message
> > > news:c9kodd$krt$1_at_sea.gmane.org...
> > > > "Johan Nilsson" <johan.nilsson_at_[hidden]> wrote in
message
> > > > news:c9k069$9jf$1_at_sea.gmane.org...
> >
> > [snip]
> >
> >
> > > An alternative could be to have Boost.Threads automatically
create a
> > > background thread to periodically collect unowned
thread-specific
> > data.
> >
> > This could also be used in addition to lazy cleanup instead of as
an
> > alternative, and seems to have the same problems.
> >
>
> Implementing the solution another poster mentioned (have a
background thread
> wait either on thread termination or an event signalling a new
thread
> request TSS data) would be better.

Except that Malcolm, who mentioned that approach, abandoned it as
unworkable--or was that only the optimization? But without the
optimization you'd have to create a "watchdog" thread for each thread
being watched, which doesn't sound like a good idea, either.

I agree that it's worth looking into, though, to see if the problems
he had can be dealt with.

> Or why not implement a catch (...) around the call to the threads
user's
> provided thread entry and free data when it returns - but that would
> preclude users to create threads directly and still use
> thread_specific_ptr's.

Yes, and that's pretty important.

> Hmmm ... or is that impossible in the current
> implementation as well?

No, it's quite possible to use a thread_specific_ptr in a thread not
created by Boost.Threads.

> > > Now if boost threads could have priority assigned to them to
make
> > > this a (corresponding to) THREAD_PRIORITY_IDLE thread - is that
in
> > the
> > > works?
> >
> > The (unfinished) changes on the thread_dev branch do implement
thread
> > priorities. They won't make it into the next Boost release, but I
hope
> > they will be in the one after that.
> >
>
> Not a problem in this case; you could just use (the boost equivalent
of):
>
> // pseudo pseudo-code
> #if defined (WIN32)
> ::SetThreadPriority(...);
> #else
> #error <appropriate error message>
> #endif

True. I was reading "is that in the works" as asking about
availability of setting thread priorities in general, and answering it
as such.

> [snip]
>
> > > Highly theoretical:
> > >
> > > 1. Thread A is created with id:1
> > > 2. Thread A" creates thread_specific_ptr (first time),
implicitly
> > > allocating TLS slot.
> > > 3. Thread A exits
> > > 4. Thread B is created, getting the recycled id of the first
thread
> > (id:1)
> > > 5. Thread B creates thread_specific_ptr; this is the first time
so
> > the
> > > implementation now also tries to perform a 'lazy' cleanup of any
> > unowned
> > > data. There are still data allocated by Thread A, but this is
mapped
> > through
> > > the thread's id and so can't be detected as ready for
collection.
> >
> > I follow as far as this.
> >
> > > Thread B can still create it's own data,
> >
> > How does thread B know that it needs to create its own data--i.e.,
> > what prevents it from thinking that thread A's data is its own and
> > using it?
>
> By pure magic I suppose ... ;-)
>
> Seriously, I haven't checked the thread_specific_ptr implementation.
> Previously I've always been under the impression that if calling
> TlsGetValue(<tls index>) return NULL and GetLastError() == NO_ERROR,
the
> calling threads slot is uninitialized => create whatever and store
pointer.

I need to look at the code again and think about this. I think I may
have missed something before.

> The thread id as mapped by the suggestion above is only used for
deleting
> "unowned data". References to the data is stored globally, protected
by a
> synchronization object and mapped per thread-id. This "meta"-data is
not
> used for _accessing_ the data.
>
> >
> > Here's a specific case I have in mind: the implementation of the
> > thread class on the thread_dev branch. In this implementation, the
> > thread class has become a handle class that holds a
reference-counted
> > pointer to a thread_data class. When a thread class is created, it
> > gets access to the thread_data class for the thread using a global
> > static thread_specific_ptr. In the scenario you outline above,
when a
> > thread object created on Thread B tries to access its thread data
> > through this thread_specific_ptr, it will get the thread data for
> > thread A, which is a Bad Thing.
>
> If it accesses the data through it's own id <-> data map, yes. Not
if it
> leaves that to the operating systems's service internally
(TlsGetValue). I
> might be missing something though.

As I said above, I need to look at the code again.

> [snip]
>
> > >
> > > Yes, but that's still forcing the user to use a "special" dll
just
> > for that
> > > purpose.
> >
> > Not necessarily. If the user's code is in a dll, its own dllmain
could
> > be used; or the dllmain of the "pseudo dll" that is created on the
fly
> > could be used.
>
> Sorry, I meant you're forcing the user to _use a dll_ for that
purpose (i.e.
> not necessarily a "special" one).

OK.

Mike


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk