test-rcu-list: abstract the list implementation
So that we can test other implementations. Signed-off-by: Emilio G. Cota <cota@braap.org> Message-Id: <20180819091335.22863-8-cota@braap.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
23311b8182
commit
685cc7c0ec
@ -82,9 +82,16 @@ static void wait_all_threads(void)
|
||||
n_threads = 0;
|
||||
}
|
||||
|
||||
#ifndef TEST_LIST_TYPE
|
||||
#define TEST_LIST_TYPE 1
|
||||
#endif
|
||||
|
||||
struct list_element {
|
||||
#if TEST_LIST_TYPE == 1
|
||||
QLIST_ENTRY(list_element) entry;
|
||||
#else
|
||||
#error Invalid TEST_LIST_TYPE
|
||||
#endif
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
|
||||
@ -96,8 +103,19 @@ static void reclaim_list_el(struct rcu_head *prcu)
|
||||
n_reclaims++;
|
||||
}
|
||||
|
||||
#if TEST_LIST_TYPE == 1
|
||||
static QLIST_HEAD(q_list_head, list_element) Q_list_head;
|
||||
|
||||
#define TEST_NAME "qlist"
|
||||
#define TEST_LIST_REMOVE_RCU QLIST_REMOVE_RCU
|
||||
#define TEST_LIST_INSERT_AFTER_RCU QLIST_INSERT_AFTER_RCU
|
||||
#define TEST_LIST_INSERT_HEAD_RCU QLIST_INSERT_HEAD_RCU
|
||||
#define TEST_LIST_FOREACH_RCU QLIST_FOREACH_RCU
|
||||
#define TEST_LIST_FOREACH_SAFE_RCU QLIST_FOREACH_SAFE_RCU
|
||||
#else
|
||||
#error Invalid TEST_LIST_TYPE
|
||||
#endif
|
||||
|
||||
static void *rcu_q_reader(void *arg)
|
||||
{
|
||||
long long n_reads_local = 0;
|
||||
@ -113,7 +131,7 @@ static void *rcu_q_reader(void *arg)
|
||||
|
||||
while (atomic_read(&goflag) == GOFLAG_RUN) {
|
||||
rcu_read_lock();
|
||||
QLIST_FOREACH_RCU(el, &Q_list_head, entry) {
|
||||
TEST_LIST_FOREACH_RCU(el, &Q_list_head, entry) {
|
||||
n_reads_local++;
|
||||
if (atomic_read(&goflag) == GOFLAG_STOP) {
|
||||
break;
|
||||
@ -150,10 +168,10 @@ static void *rcu_q_updater(void *arg)
|
||||
target_el = select_random_el(RCU_Q_LEN);
|
||||
j = 0;
|
||||
/* FOREACH_RCU could work here but let's use both macros */
|
||||
QLIST_FOREACH_SAFE_RCU(prev_el, &Q_list_head, entry, el) {
|
||||
TEST_LIST_FOREACH_SAFE_RCU(prev_el, &Q_list_head, entry, el) {
|
||||
j++;
|
||||
if (target_el == j) {
|
||||
QLIST_REMOVE_RCU(prev_el, entry);
|
||||
TEST_LIST_REMOVE_RCU(prev_el, entry);
|
||||
/* may be more than one updater in the future */
|
||||
call_rcu1(&prev_el->rcu, reclaim_list_el);
|
||||
n_removed_local++;
|
||||
@ -165,12 +183,12 @@ static void *rcu_q_updater(void *arg)
|
||||
}
|
||||
target_el = select_random_el(RCU_Q_LEN);
|
||||
j = 0;
|
||||
QLIST_FOREACH_RCU(el, &Q_list_head, entry) {
|
||||
TEST_LIST_FOREACH_RCU(el, &Q_list_head, entry) {
|
||||
j++;
|
||||
if (target_el == j) {
|
||||
prev_el = g_new(struct list_element, 1);
|
||||
struct list_element *new_el = g_new(struct list_element, 1);
|
||||
n_nodes += n_nodes_local;
|
||||
QLIST_INSERT_BEFORE_RCU(el, prev_el, entry);
|
||||
TEST_LIST_INSERT_AFTER_RCU(el, new_el, entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -195,7 +213,7 @@ static void rcu_qtest_init(void)
|
||||
srand(time(0));
|
||||
for (i = 0; i < RCU_Q_LEN; i++) {
|
||||
new_el = g_new(struct list_element, 1);
|
||||
QLIST_INSERT_HEAD_RCU(&Q_list_head, new_el, entry);
|
||||
TEST_LIST_INSERT_HEAD_RCU(&Q_list_head, new_el, entry);
|
||||
}
|
||||
qemu_mutex_lock(&counts_mutex);
|
||||
n_nodes += RCU_Q_LEN;
|
||||
@ -230,8 +248,8 @@ static void rcu_qtest(const char *test, int duration, int nreaders)
|
||||
create_thread(rcu_q_updater);
|
||||
rcu_qtest_run(duration, nreaders);
|
||||
|
||||
QLIST_FOREACH_SAFE_RCU(prev_el, &Q_list_head, entry, el) {
|
||||
QLIST_REMOVE_RCU(prev_el, entry);
|
||||
TEST_LIST_FOREACH_SAFE_RCU(prev_el, &Q_list_head, entry, el) {
|
||||
TEST_LIST_REMOVE_RCU(prev_el, entry);
|
||||
call_rcu1(&prev_el->rcu, reclaim_list_el);
|
||||
n_removed_local++;
|
||||
}
|
||||
@ -290,9 +308,9 @@ int main(int argc, char *argv[])
|
||||
} else {
|
||||
gtest_seconds = 20;
|
||||
}
|
||||
g_test_add_func("/rcu/qlist/single-threaded", gtest_rcuq_one);
|
||||
g_test_add_func("/rcu/qlist/short-few", gtest_rcuq_few);
|
||||
g_test_add_func("/rcu/qlist/long-many", gtest_rcuq_many);
|
||||
g_test_add_func("/rcu/"TEST_NAME"/single-threaded", gtest_rcuq_one);
|
||||
g_test_add_func("/rcu/"TEST_NAME"/short-few", gtest_rcuq_few);
|
||||
g_test_add_func("/rcu/"TEST_NAME"/long-many", gtest_rcuq_many);
|
||||
g_test_in_charge = 1;
|
||||
return g_test_run();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user