Loading tests/test-rcu-list.c +30 −12 Original line number Diff line number Diff line Loading @@ -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; }; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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++; Loading @@ -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; } } Loading @@ -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; Loading Loading @@ -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++; } Loading Loading @@ -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 Loading
tests/test-rcu-list.c +30 −12 Original line number Diff line number Diff line Loading @@ -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; }; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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++; Loading @@ -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; } } Loading @@ -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; Loading Loading @@ -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++; } Loading Loading @@ -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