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).