[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