[PATCH] Re: [mudflap] remove a couple of race conditions
Ulrich Weigand
uweigand@de.ibm.com
Mon Aug 15 19:49:00 GMT 2005
Richard Henderson wrote:
> On Sun, Aug 14, 2005 at 01:26:14AM +0200, Ulrich Weigand wrote:
> > * mf-runtime.c (__mf_state_1): Initialize to reentrant.
> > (__mf_init): Set thread state active.
> > * mf-hooks3.c (__mf_pthread_spawner): Always set thread
> > state active.
> > (pthread_create wrapper): Always use thread spawner.
> >
> > * testsuite/libmudflap.cth/pass37-frag.c: Increase timeout.
> > * testsuite/libmudflap.cth/pass39-frag.c: Likewise.
>
> Not ok, even though I see that you committed it yesterday.
Yes, after (off-list) approval by fche ...
> This fails utterly with linuxthreads and no tls. Please
> configure with --disable-tls to see the problems.
Sorry for neglecting to test that case.
The problem is the 'main_seen_p' hack that __mf_get_state uses to
attempt to recognize the main thread. The assumption was that
the first thread encountered without a registered thread info
structure must be the main thread.
However, now that there is a __mf_set_state call in __mf_init,
the main thread always has a thread info structure. The first
time the main_seen_p hack hits now happens to be the linuxthreads
manager thread, so this thread is marked active -- which is
exactly what we don't want. This causes exactly the same
symptoms I was seeing before my patch in the linuxthreads+tls
scenario ...
This appears to be easily fixable by just removing the main_seen_p
hack from the non-TLS logic. Both main and user threads are then
correctly recognized same as in the TLS case, and the linuxthreads
manager thread is identified as reentrant.
Tested on s390-ibm-linux with --disable-tls, no regressions.
OK for mainline?
Bye,
Ulrich
ChangeLog:
* mf-hooks3.c (main_seen_p): Remove.
(__mf_get_state): Remove attempt to recognize the main thread.
Index: libmudflap/mf-hooks3.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/mf-hooks3.c,v
retrieving revision 1.9
diff -c -p -r1.9 mf-hooks3.c
*** libmudflap/mf-hooks3.c 14 Aug 2005 19:38:34 -0000 1.9
--- libmudflap/mf-hooks3.c 15 Aug 2005 18:38:19 -0000
*************** struct mf_thread_data
*** 104,114 ****
static struct mf_thread_data mf_thread_data[LIBMUDFLAPTH_THREADS_MAX];
static pthread_mutex_t mf_thread_data_lock = PTHREAD_MUTEX_INITIALIZER;
- /* Try to identify the main thread when filling in mf_thread_data. We
- should always be called at least once from the main thread before
- any new threads are spawned. */
- static int main_seen_p;
-
#define PTHREAD_HASH(p) ((unsigned long) (p) % LIBMUDFLAPTH_THREADS_MAX)
static struct mf_thread_data *
--- 104,109 ----
*************** __mf_get_state (void)
*** 176,186 ****
if (data)
return data->state;
! /* The main thread needs to default to active state, so that the global
! constructors are processed in the active state. Child threads should
! be considered to be in the reentrant state, so that we don't wind up
! doing Screwy Things inside the thread library; it'll get reset to
! active state in __mf_pthread_spawner before user code is invoked.
The trickiest bit here is that the LinuxThreads pthread_manager thread
should *always* be considered to be reentrant, so that none of our
--- 171,179 ----
if (data)
return data->state;
! /* If we've never seen this thread before, consider it to be in the
! reentrant state. The state gets reset to active for the main thread
! in __mf_init, and for child threads in __mf_pthread_spawner.
The trickiest bit here is that the LinuxThreads pthread_manager thread
should *always* be considered to be reentrant, so that none of our
*************** __mf_get_state (void)
*** 189,203 ****
stuff isn't initialized, leading to SEGV very quickly. Even calling
pthread_self is a bit suspect, but it happens to work. */
! if (main_seen_p)
! return reentrant;
! else
! {
! main_seen_p = 1;
! data = __mf_find_threadinfo (1);
! data->state = active;
! return active;
! }
}
void
--- 182,188 ----
stuff isn't initialized, leading to SEGV very quickly. Even calling
pthread_self is a bit suspect, but it happens to work. */
! return reentrant;
}
void
--
Dr. Ulrich Weigand
Linux on zSeries Development
Ulrich.Weigand@de.ibm.com
More information about the Gcc-patches
mailing list