Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib, tests: fix some b0rked tests, then fix TSAN warnings #16258

Merged
merged 5 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/frrcu.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ extern void rcu_enqueue(struct rcu_head *head, const struct rcu_action *action);
#define rcu_call(func, ptr, field) \
do { \
typeof(ptr) _ptr = (ptr); \
void (*fptype)(typeof(ptr)); \
void (*_fptype)(typeof(ptr)); \
struct rcu_head *_rcu_head = &_ptr->field; \
static const struct rcu_action _rcu_action = { \
.type = RCUA_CALL, \
Expand Down
33 changes: 33 additions & 0 deletions lib/seqlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,39 @@
* OS specific synchronization wrappers *
****************************************/

#ifndef __has_feature /* not available on old GCC */
#define __has_feature(x) 0
#endif

#if (defined(__SANITIZE_THREAD__) || __has_feature(thread_sanitizer))
/* TSAN really does not understand what is going on with the low-level
* futex/umtx calls. This leads to a whole bunch of warnings, a lot of which
* also have _extremely_ misleading text - since TSAN does not understand that
* there is in fact a synchronization primitive involved, it can end up pulling
* in completely unrelated things.
*
* What does work is the "unsupported platform" seqlock implementation based
* on a pthread mutex + condvar, since TSAN of course suppports these.
*
* It may be possible to also fix this with TSAN annotations (__tsan_acquire
* and __tsan_release), but using those (correctly) is not easy either, and
* for now just get things rolling.
*/

#ifdef HAVE_SYNC_LINUX_FUTEX
#undef HAVE_SYNC_LINUX_FUTEX
#endif

#ifdef HAVE_SYNC_OPENBSD_FUTEX
#undef HAVE_SYNC_OPENBSD_FUTEX
#endif

#ifdef HAVE_SYNC_UMTX_OP
#undef HAVE_SYNC_UMTX_OP
#endif

#endif /* TSAN */

/*
* Linux: sys_futex()
*/
Expand Down
18 changes: 9 additions & 9 deletions tests/lib/test_atomlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ static struct asort_head shead;
static struct testthread {
pthread_t pt;
struct seqlock sqlo;
size_t counter, nullops;
_Atomic size_t counter, nullops;
} thr[NTHREADS];

struct testrun {
Expand Down Expand Up @@ -97,10 +97,10 @@ static void trfunc_##name(unsigned int offset) \
{ \
size_t i = 0, n = 0;

#define endtestrun \
thr[offset].counter = i; \
thr[offset].nullops = n; \
}
#define endtestrun \
atomic_store_explicit(&thr[offset].counter, i, memory_order_seq_cst); \
atomic_store_explicit(&thr[offset].nullops, n, memory_order_seq_cst); \
}

deftestrun(add, "add vs. add", 0, false)
for (; i < NITEM / NTHREADS; i++)
Expand Down Expand Up @@ -288,10 +288,10 @@ static void run_tr(struct testrun *tr)
sv = seqlock_bump(&sqlo) - SEQLOCK_INCR;
for (size_t i = 0; i < NTHREADS; i++) {
seqlock_wait(&thr[i].sqlo, seqlock_cur(&sqlo));
s += thr[i].counter;
n += thr[i].nullops;
thr[i].counter = 0;
thr[i].nullops = 0;
s += atomic_load_explicit(&thr[i].counter, memory_order_seq_cst);
n += atomic_load_explicit(&thr[i].nullops, memory_order_seq_cst);
atomic_store_explicit(&thr[i].counter, 0, memory_order_seq_cst);
atomic_store_explicit(&thr[i].nullops, 0, memory_order_seq_cst);
}

delta = monotime_since(&tv, NULL);
Expand Down
5 changes: 3 additions & 2 deletions tests/lib/test_seqlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,11 @@ int main(int argc, char **argv)
assert(seqlock_held(&sqlo));

assert(seqlock_cur(&sqlo) == 1);
assert(seqlock_bump(&sqlo) == 1);
assert(seqlock_cur(&sqlo) == 5);
assert(seqlock_bump(&sqlo) == 5);
assert(seqlock_cur(&sqlo) == 5);
assert(seqlock_bump(&sqlo) == 9);
assert(seqlock_bump(&sqlo) == 13);
assert(seqlock_bump(&sqlo) == 17);
assert(seqlock_cur(&sqlo) == 17);

assert(seqlock_held(&sqlo));
Expand All @@ -111,4 +111,5 @@ int main(int argc, char **argv)
writestr("main @release\n");
seqlock_release(&sqlo);
sleep(1);
pthread_join(thr1, NULL);
}
Loading