Refactored tests in clang to use barrier_init/wait: http://llvm.org/viewvc/llvm-project?view=revision&revision=226659
There are still few sleep call, like when we need to wait for a thread to exit (there is really no point to insert barrier_wait); or when we need to wait for a thread to _block_ inside of pthread_cond_wait; or when a thread needs to process signals. But all remaining uses of sleep are commented. On Wed, Jan 21, 2015 at 11:58 AM, Dmitry Vyukov <dvyu...@google.com> wrote: > On Tue, Jan 20, 2015 at 10:09 AM, Bernd Edlinger > <bernd.edlin...@hotmail.de> wrote: >> >> Hi, >> >> On Mon, 19 Jan 2015 18:49:21, Konstantin Serebryany wrote: >>> >>> [text-only] >>> >>> On Mon, Jan 19, 2015 at 7:42 AM, Mike Stump <mikest...@comcast.net> wrote: >>>> On Jan 19, 2015, at 12:43 AM, Dmitry Vyukov <dvyu...@google.com> wrote: >>>>> I can't really make my mind on this. I would mildly prefer sleep's (if >>>>> they work reliably!). >>>> >>>> Let me state it more forcefully. >>> You don't have to convince us here. >>> I'd love to get rid of sleep calls in the tsan test suite -- they are >>> a minor but a constant annoyance. >>> But I also want to keep the tests *very simple*, i.e. >>> 1. Single file w/o any non-system includes, no linking of extra >>> libraries/objects >>> 2. Not too much extra code. (ideally, 1 line for init, 1 line for >>> "signal", 1 line for "wait") >>> 3. Strictly posix or c++11 (unless we are testing something specific) >>> >>> Your idea with barrier_wait/dlsym sounds interesting, but I can't see >>> the code in this mail thread. >>> What do I miss? >>> >> >> We discussed two alternatives to sleep: >> >> 1. step function, optionally with sched_yield to make it somewhat less busy >> waiting: >> __attribute__((no_sanitize_thread)) >> void step (int i) >> { >> while (__atomic_load_n (&serial, __ATOMIC_ACQUIRE) != i - 1) >> sched_yield(); >> __atomic_store_n (&serial, i, __ATOMIC_RELEASE); >> } >> 2. tsan-invisible barriers: >> >> cat tsan_barrier.h >> /* TSAN-invisible barriers. Link with -ldl. */ >> #include <pthread.h> >> #include <dlfcn.h> >> >> static __typeof(pthread_barrier_wait) *barrier_wait; >> >> static >> void barrier_init (pthread_barrier_t *barrier, unsigned count) >> { >> void *h = dlopen ("libpthread.so.0", RTLD_LAZY); >> barrier_wait = (__typeof (pthread_barrier_wait) *) >> dlsym (h, "pthread_barrier_wait"); >> pthread_barrier_init (barrier, NULL, count); >> } >> >> >> We preferred the second alternative, because it does not do busy waiting. >> We include this header file in every positive test case and link with -ldl. > > > The step approach looks better to me at first sight. > > Busy waiting looks like a weak argument in this context. It's > absolutely non performance-critical and a yield or usleep(10) will > solve it more than sufficiently. > > I will check how complex to make its implementation invisible to tsan > (I suspect that clang does not ignore atomic operations when > no_sanitize_thread attribute is given) and whether it actually makes > more complex tests simpler to write (as compared to the barrier > approach).