|
From: Konstantin S. <kon...@gm...> - 2010-03-09 13:20:53
|
On Tue, Mar 9, 2010 at 2:08 PM, Bart Van Assche <bva...@ac...> wrote: > On Wed, Jan 27, 2010 at 1:33 PM, Konstantin Serebryany > <kon...@gm...> wrote: >> >> On Wed, Jan 27, 2010 at 3:41 PM, Julian Seward <js...@ac...> wrote: >>> >>> Konstantin, >>> >>> I'm trying to annotate a user-implemented barrier, using >>> >>> http://code.google.com/p/google-perftools/source/browse/trunk/src/base/dynamic_annotations.h >>> specifically ANNOTATE_HAPPENS_BEFORE and ANNOTATE_HAPPENS_AFTER >>> >>> like this >>> >>> void barrier_wait ( barrier* b ) >>> { >>> ANNOTATE_HAPPENS_BEFORE(b); >>> // the barrier implementation >>> ANNOTATE_HAPPENS_AFTER(b); >>> } >> >> this is exactly how I handle barrier. > > (replying to an e-mail of about one month ago) > > The above algorithm for annotating barriers is wrong. Yes, it may miss races. This is why we agreed to use ANNOTATE_BARRIER_* to implement barrier. > This can be > illustrated easily via the test program drd/tests/pth_barrier in the > Valgrind tree: DRD and Helgrind always report 32 races for this > program when started with the arguments "2 32 1" (two threads, 32 > iterations, silent output) while TSan reports zero races with silent > output and 17 races with verbose output (arguments "2 32 0"). The > results reported by DRD and Helgrind are correct, the results reported > by TSan not. tsan's implementation of ANNOTATE_BARRIER_* was incorrect though, I just fixed it (hopefully) Thanks for the report! Now tsan always reports one race (in non-verbose mode): ==17079== WARNING: Possible data race during write of size 4 at 0x4218060: {{{ ==17079== T2 (locks held: {}): ==17079== #0 threadfunc /home/kcc/valgrind/trunk/drd/tests/pth_barrier.c:57 ==17079== #1 ThreadSanitizerStartThread /home/kcc/drt/trunk/tsan/ts_valgrind_intercepts.c:553 ==17079== Concurrent write(s) happened at (OR AFTER) these points: ==17079== T1 (locks held: {}): ==17079== #0 threadfunc /home/kcc/valgrind/trunk/drd/tests/pth_barrier.c:57 ==17079== #1 ThreadSanitizerStartThread /home/kcc/drt/trunk/tsan/ts_valgrind_intercepts.c:553 ==17079== Location 0x4218060 is 0 bytes inside a block starting at 0x4218060 of size 8 allocated by T0 from heap: ==17079== #0 malloc /home/kcc/drt/t runk/tsan/ts_valgrind_intercepts.c:380 ==17079== #1 barriers_and_races /home/kcc/valgrind/trunk/drd/tests/pth_barrier.c:72 ==17079== #2 main /home/kcc/valgrind/trunk/drd/tests/pth_barrier.c:107 ==17079== }}} It does not report 32 races because it reports each stack only once. If you run the test in verbose mode you may get some more race reports like this: ==17079== WARNING: Possible data race during write of size 1 at 0x401A029: {{{ ==17079== T2 (locks held: {}): ==17079== #0 _IO_file_xsputn@@GLIBC_2.2.5 /usr/grte/v1/lib64/libc-2.3.6.so ==17079== #1 vfprintf /usr/grte/v1/lib64/libc-2.3.6.so ... This is because the test calls printf() from several threads w/o synchronization. ThreadSanitizer deliberately does not suppress these warnings by default because some users may consider it as a real problem (if you call printf from several threads w/o synchronization your output may be garbled). You can suppress or ignore these reports using the regular suppression mechanism or using tsan's ignore files. Thanks again! --kcc > > $ ../tsan/drt/tsan.sh drd/tests/pth_barrier 2 32 1 > Extracting ThreadSanitizer to /tmp/valgrind.LbA93c > ==1676== ThreadSanitizer, a data race detector > ==1676== Copyright (C) 2008-2009, and GNU GPL'd, by Google Inc. > ==1676== Using Valgrind-3.6.0.SVN and LibVEX; rerun with -h for copyright info > ==1676== Command: drd/tests/pth_barrier 2 32 1 > ==1676== > ==1676== ThreadSanitizerValgrind r1819: pure-happens-before=yes > fast-mode=no ignore-in-dtor=no > ==1676== INFO: Allocating 939,524,096 (112 * 8,388,608) bytes for Segments. > ==1676== > ==1676== ThreadSanitizer summary: reported 0 warning(s) (0 race(s)) > > Sorry that I didn't have a closer look at the above algorithm earlier. > > Bart. > |