mirror of https://github.com/xemu-project/xemu.git
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;
|
n_threads = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef TEST_LIST_TYPE
|
||||||
|
#define TEST_LIST_TYPE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
struct list_element {
|
struct list_element {
|
||||||
|
#if TEST_LIST_TYPE == 1
|
||||||
QLIST_ENTRY(list_element) entry;
|
QLIST_ENTRY(list_element) entry;
|
||||||
|
#else
|
||||||
|
#error Invalid TEST_LIST_TYPE
|
||||||
|
#endif
|
||||||
struct rcu_head rcu;
|
struct rcu_head rcu;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -96,8 +103,19 @@ static void reclaim_list_el(struct rcu_head *prcu)
|
||||||
n_reclaims++;
|
n_reclaims++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TEST_LIST_TYPE == 1
|
||||||
static QLIST_HEAD(q_list_head, list_element) Q_list_head;
|
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)
|
static void *rcu_q_reader(void *arg)
|
||||||
{
|
{
|
||||||
long long n_reads_local = 0;
|
long long n_reads_local = 0;
|
||||||
|
@ -113,7 +131,7 @@ static void *rcu_q_reader(void *arg)
|
||||||
|
|
||||||
while (atomic_read(&goflag) == GOFLAG_RUN) {
|
while (atomic_read(&goflag) == GOFLAG_RUN) {
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
QLIST_FOREACH_RCU(el, &Q_list_head, entry) {
|
TEST_LIST_FOREACH_RCU(el, &Q_list_head, entry) {
|
||||||
n_reads_local++;
|
n_reads_local++;
|
||||||
if (atomic_read(&goflag) == GOFLAG_STOP) {
|
if (atomic_read(&goflag) == GOFLAG_STOP) {
|
||||||
break;
|
break;
|
||||||
|
@ -150,10 +168,10 @@ static void *rcu_q_updater(void *arg)
|
||||||
target_el = select_random_el(RCU_Q_LEN);
|
target_el = select_random_el(RCU_Q_LEN);
|
||||||
j = 0;
|
j = 0;
|
||||||
/* FOREACH_RCU could work here but let's use both macros */
|
/* 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++;
|
j++;
|
||||||
if (target_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 */
|
/* may be more than one updater in the future */
|
||||||
call_rcu1(&prev_el->rcu, reclaim_list_el);
|
call_rcu1(&prev_el->rcu, reclaim_list_el);
|
||||||
n_removed_local++;
|
n_removed_local++;
|
||||||
|
@ -165,12 +183,12 @@ static void *rcu_q_updater(void *arg)
|
||||||
}
|
}
|
||||||
target_el = select_random_el(RCU_Q_LEN);
|
target_el = select_random_el(RCU_Q_LEN);
|
||||||
j = 0;
|
j = 0;
|
||||||
QLIST_FOREACH_RCU(el, &Q_list_head, entry) {
|
TEST_LIST_FOREACH_RCU(el, &Q_list_head, entry) {
|
||||||
j++;
|
j++;
|
||||||
if (target_el == 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;
|
n_nodes += n_nodes_local;
|
||||||
QLIST_INSERT_BEFORE_RCU(el, prev_el, entry);
|
TEST_LIST_INSERT_AFTER_RCU(el, new_el, entry);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,7 +213,7 @@ static void rcu_qtest_init(void)
|
||||||
srand(time(0));
|
srand(time(0));
|
||||||
for (i = 0; i < RCU_Q_LEN; i++) {
|
for (i = 0; i < RCU_Q_LEN; i++) {
|
||||||
new_el = g_new(struct list_element, 1);
|
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);
|
qemu_mutex_lock(&counts_mutex);
|
||||||
n_nodes += RCU_Q_LEN;
|
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);
|
create_thread(rcu_q_updater);
|
||||||
rcu_qtest_run(duration, nreaders);
|
rcu_qtest_run(duration, nreaders);
|
||||||
|
|
||||||
QLIST_FOREACH_SAFE_RCU(prev_el, &Q_list_head, entry, el) {
|
TEST_LIST_FOREACH_SAFE_RCU(prev_el, &Q_list_head, entry, el) {
|
||||||
QLIST_REMOVE_RCU(prev_el, entry);
|
TEST_LIST_REMOVE_RCU(prev_el, entry);
|
||||||
call_rcu1(&prev_el->rcu, reclaim_list_el);
|
call_rcu1(&prev_el->rcu, reclaim_list_el);
|
||||||
n_removed_local++;
|
n_removed_local++;
|
||||||
}
|
}
|
||||||
|
@ -290,9 +308,9 @@ int main(int argc, char *argv[])
|
||||||
} else {
|
} else {
|
||||||
gtest_seconds = 20;
|
gtest_seconds = 20;
|
||||||
}
|
}
|
||||||
g_test_add_func("/rcu/qlist/single-threaded", gtest_rcuq_one);
|
g_test_add_func("/rcu/"TEST_NAME"/single-threaded", gtest_rcuq_one);
|
||||||
g_test_add_func("/rcu/qlist/short-few", gtest_rcuq_few);
|
g_test_add_func("/rcu/"TEST_NAME"/short-few", gtest_rcuq_few);
|
||||||
g_test_add_func("/rcu/qlist/long-many", gtest_rcuq_many);
|
g_test_add_func("/rcu/"TEST_NAME"/long-many", gtest_rcuq_many);
|
||||||
g_test_in_charge = 1;
|
g_test_in_charge = 1;
|
||||||
return g_test_run();
|
return g_test_run();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue