aboutsummaryrefslogtreecommitdiff
path: root/gdb/unittests
diff options
context:
space:
mode:
authorSimon Marchi <simon.marchi@polymtl.ca>2021-06-15 14:49:32 -0400
committerSimon Marchi <simon.marchi@polymtl.ca>2021-07-12 20:46:52 -0400
commit8b6a69b2f37fd1370aa823320f9dc3fd482e1e78 (patch)
treeaadd270b49270314c5c60f4e25ae1dd6ce74c9a4 /gdb/unittests
parent08bdefb58b78621f50b30f64170e2cdc31c1b2cf (diff)
downloadgdb-8b6a69b2f37fd1370aa823320f9dc3fd482e1e78.zip
gdb-8b6a69b2f37fd1370aa823320f9dc3fd482e1e78.tar.gz
gdb-8b6a69b2f37fd1370aa823320f9dc3fd482e1e78.tar.bz2
gdb: use intrusive list for step-over chain
The threads that need a step-over are currently linked using an hand-written intrusive doubly-linked list, so that seems a very good candidate for intrusive_list, convert it. For this, we have a use case of appending a list to another one (in start_step_over). Based on the std::list and Boost APIs, add a splice method. However, only support splicing the other list at the end of the `this` list, since that's all we need. Add explicit default assignment operators to reference_to_pointer_iterator, which are otherwise implicitly deleted. This is needed because to define thread_step_over_list_safe_iterator, we wrap reference_to_pointer_iterator inside a basic_safe_iterator, and basic_safe_iterator needs to be able to copy-assign the wrapped iterator. The move-assignment operator is therefore not needed, only the copy-assignment operator is. But for completeness, add both. Change-Id: I31b2ff67c7b78251314646b31887ef1dfebe510c
Diffstat (limited to 'gdb/unittests')
-rw-r--r--gdb/unittests/intrusive_list-selftests.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/gdb/unittests/intrusive_list-selftests.c b/gdb/unittests/intrusive_list-selftests.c
index 5497a01..8b2b2d1 100644
--- a/gdb/unittests/intrusive_list-selftests.c
+++ b/gdb/unittests/intrusive_list-selftests.c
@@ -504,6 +504,89 @@ struct intrusive_list_test
}
static void
+ test_splice ()
+ {
+ {
+ /* Two non-empty lists. */
+ item_type a ("a"), b ("b"), c ("c"), d ("d"), e ("e");
+ ListType list1;
+ ListType list2;
+ std::vector<const item_type *> expected;
+
+ list1.push_back (a);
+ list1.push_back (b);
+ list1.push_back (c);
+
+ list2.push_back (d);
+ list2.push_back (e);
+
+ list1.splice (std::move (list2));
+
+ expected = {&a, &b, &c, &d, &e};
+ verify_items (list1, expected);
+
+ expected = {};
+ verify_items (list2, expected);
+ }
+
+ {
+ /* Receiving list empty. */
+ item_type a ("a"), b ("b"), c ("c");
+ ListType list1;
+ ListType list2;
+ std::vector<const item_type *> expected;
+
+ list2.push_back (a);
+ list2.push_back (b);
+ list2.push_back (c);
+
+ list1.splice (std::move (list2));
+
+ expected = {&a, &b, &c};
+ verify_items (list1, expected);
+
+ expected = {};
+ verify_items (list2, expected);
+ }
+
+ {
+ /* Giving list empty. */
+ item_type a ("a"), b ("b"), c ("c");
+ ListType list1;
+ ListType list2;
+ std::vector<const item_type *> expected;
+
+ list1.push_back (a);
+ list1.push_back (b);
+ list1.push_back (c);
+
+ list1.splice (std::move (list2));
+
+ expected = {&a, &b, &c};
+ verify_items (list1, expected);
+
+ expected = {};
+ verify_items (list2, expected);
+ }
+
+ {
+ /* Both lists empty. */
+ item_type a ("a"), b ("b"), c ("c");
+ ListType list1;
+ ListType list2;
+ std::vector<const item_type *> expected;
+
+ list1.splice (std::move (list2));
+
+ expected = {};
+ verify_items (list1, expected);
+
+ expected = {};
+ verify_items (list2, expected);
+ }
+ }
+
+ static void
test_pop_front ()
{
item_type a ("a"), b ("b"), c ("c");
@@ -682,6 +765,7 @@ test_intrusive_list ()
tests.test_push_front ();
tests.test_push_back ();
tests.test_insert ();
+ tests.test_splice ();
tests.test_pop_front ();
tests.test_pop_back ();
tests.test_erase ();