#include "test/birdtest.h" #include "test/bt-utils.h" #include "lib/locking.h" #include #include #define FOO_PUBLIC \ const char *name; \ _Atomic uint counter; \ DOMAIN(proto) lock; \ struct foo_private { struct { FOO_PUBLIC; }; struct foo_private **locked_at; uint private_counter; }; typedef union foo { struct { FOO_PUBLIC; }; struct foo_private priv; } foo; LOBJ_UNLOCK_CLEANUP(foo, proto); #define FOO_LOCK(_foo, _fpp) LOBJ_LOCK(_foo, _fpp, foo, proto) #define FOO_LOCKED(_foo, _fpp) LOBJ_LOCKED(_foo, _fpp, foo, proto) #define FOO_IS_LOCKED(_foo) LOBJ_IS_LOCKED(_foo, proto) static uint inc_public(foo *f) { return atomic_fetch_add_explicit(&f->counter, 1, memory_order_relaxed) + 1; } static uint inc_private(foo *f) { FOO_LOCKED(f, fp) return ++fp->private_counter; bug("Returning always"); } #define BLOCKCOUNT 4096 #define THREADS 16 #define REPEATS 128 static void * thread_run(void *_foo) { foo *f = _foo; for (int i=0; irws[i]); rws_read_lock(&d->rws[i+1]); ASSERT_DIE(d->data[i] >= 0); ASSERT_DIE(d->data[i+1] >= 0); if (d->data[i] > d->data[i+1]) sorted = 0; rws_read_unlock(&d->rws[i+1]); rws_read_unlock(&d->rws[i]); } for (int i=0; (irws[i]); rws_write_lock(&d->rws[i+1]); int first = d->data[i]; int second = d->data[i+1]; ASSERT_DIE(first >= 0); ASSERT_DIE(second >= 0); d->data[i] = d->data[i+1] = -1; if (first > second) { d->data[i] = second; d->data[i+1] = first; } else { d->data[i] = first; d->data[i+1] = second; } rws_write_unlock(&d->rws[i+1]); rws_write_unlock(&d->rws[i]); } } return NULL; } static int t_rwspin(void) { struct rws_test_data d; /* Setup an array to sort */ for (int i=0; i