http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561



--- Comment #20 from Dmitry Vyukov <dvyukov at google dot com> 2012-12-29 
10:13:00 UTC ---

(In reply to comment #19)

> On Wed, Dec 26, 2012 at 12:23 AM, Joost.VandeVondele at mat dot

> ethz.ch <gcc-bugzi...@gcc.gnu.org> wrote:

> >

> > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561

> >

> > --- Comment #16 from Joost VandeVondele <Joost.VandeVondele at mat dot 
> > ethz.ch> 2012-12-25 20:23:07 UTC ---

> > many things appear to work fine, but seemingly parallel do loops with a 
> > dynamic

> > schedule generate warnings in libgomp. I also seem to observe that they are 
> > not

> > strictly deterministic, sometimes these warnings happen, sometimes not.

> >

> > Testcase:

> >

> > !$OMP PARALLEL PRIVATE(j)

> >

> > j=OMP_GET_THREAD_NUM()

> >

> > ! no warnings without the dynamic schedule

> > !$OMP DO SCHEDULE(DYNAMIC,2)

> > DO i=1,10

> > ENDDO

> >

> > !$OMP END PARALLEL

> > END

> >

> > Result:

> >

> > vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src> ./a.out

> > vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src> ./a.out

> > vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src> ./a.out

> > vjo...@nanosim-s01.ethz.ch:/data/vjoost/clean/cp2k/cp2k/src> ./a.out

> > ==================

> > WARNING: ThreadSanitizer: data race (pid=35190)

> >   Read of size 8 at 0x7d3000027290 by main thread:

> >     #0 gomp_iter_dynamic_next

> > /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/iter.c:190

> > (libgomp.so.1+0x000000006678)

> >     #1 GOMP_loop_dynamic_start

> > /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/loop.c:128

> > (libgomp.so.1+0x000000007a03)

> >     #2 MAIN__._omp_fn.0 test.f90:0 (exe+0x000000000d7d)

> >     #3 MAIN__ test.f90:0 (exe+0x000000000ccb)

> >     #4 main ??:0 (exe+0x000000000d1a)

> >

> >   Previous write of size 8 at 0x7d3000027290 by thread 1:

> >     #0 gomp_loop_init

> > /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/loop.c:41

> > (libgomp.so.1+0x000000007a96)

> >     #1 MAIN__._omp_fn.0 test.f90:0 (exe+0x000000000d7d)

> >     #2 gomp_thread_start

> > /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/team.c:116

> > (libgomp.so.1+0x00000000d012)

> >

> >   Location is heap block of size 1568 at 0x7d3000027100 allocated by main

> > thread:

> >     #0 malloc ??:0 (libtsan.so.0+0x00000001896e)

> >     #1 gomp_malloc

> > /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/alloc.c:36

> > (libgomp.so.1+0x00000000417a)

> >     #2 gomp_new_team

> > /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/team.c:145

> > (libgomp.so.1+0x00000000d27a)

> >     #3 GOMP_parallel_start

> > /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/parallel.c:108

> > (libgomp.so.1+0x00000000afc7)

> >     #4 MAIN__ test.f90:0 (exe+0x000000000cc1)

> >     #5 main ??:0 (exe+0x000000000d1a)

> >

> >   Thread 1 (tid=35191, running) created at:

> >     #0 pthread_create ??:0 (libtsan.so.0+0x00000001a868)

> >     #1 gomp_team_start

> > /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/team.c:440

> > (libgomp.so.1+0x00000000d908)

> >     #2 GOMP_parallel_start

> > /data/vjoost/gnu/gcc_trunk/obj/x86_64-unknown-linux-gnu/libgomp/../../../gcc/libgomp/parallel.c:108

> > (libgomp.so.1+0x00000000afd7)

> >     #3 MAIN__ test.f90:0 (exe+0x000000000cc1)

> >     #4 main ??:0 (exe+0x000000000d1a)

> 

> 

> Looks like unsafe publication of gomp_work_share data.

> 

> Can you show disassembly of

> >     #2 MAIN__._omp_fn.0 test.f90:0 (exe+0x000000000d7d)

> ?

> How does it choose between calling gomp_loop_init() and

> GOMP_loop_dynamic_start()?

> 

> Humm... do omp generated functions (like MAIN__._omp_fn.0) pass

> through tsan pass? Perhaps it contains some atomic op that tsan does

> not see.





Congratulations! We've found racy unsafe publication in libgomp with

ThreadSanitizer:



gomp_loop_dynamic_start() uses the following functions to synchronize with each

other.  As you can see gomp_ptrlock_get() contains fast-and-dead unsafe

fast-path.



libgomp/config/posix/ptrlock.h



static inline void *gomp_ptrlock_get (gomp_ptrlock_t *ptrlock)

{

  if (ptrlock->ptr != NULL)

    return ptrlock->ptr;



  gomp_mutex_lock (&ptrlock->lock);

  if (ptrlock->ptr != NULL)

    {

      gomp_mutex_unlock (&ptrlock->lock);

      return ptrlock->ptr;

    }



  return NULL;

}



static inline void gomp_ptrlock_set (gomp_ptrlock_t *ptrlock, void *ptr)

{

  ptrlock->ptr = ptr;

  gomp_mutex_unlock (&ptrlock->lock);

}

Reply via email to