diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ada-tasks.c | 4 | ||||
-rw-r--r-- | gdb/inferior-iter.h | 25 | ||||
-rw-r--r-- | gdb/inferior.c | 63 | ||||
-rw-r--r-- | gdb/inferior.h | 9 | ||||
-rw-r--r-- | gdb/infrun.c | 30 | ||||
-rw-r--r-- | gdb/progspace.c | 3 | ||||
-rw-r--r-- | gdb/regcache.c | 1 | ||||
-rw-r--r-- | gdb/scoped-mock-context.h | 10 | ||||
-rw-r--r-- | gdb/thread-iter.c | 68 | ||||
-rw-r--r-- | gdb/thread.c | 6 |
10 files changed, 103 insertions, 116 deletions
diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c index a9c6b5e..80a7221 100644 --- a/gdb/ada-tasks.c +++ b/gdb/ada-tasks.c @@ -1444,8 +1444,6 @@ ada_tasks_normal_stop_observer (struct bpstats *unused_args, int unused_args2) static void ada_tasks_new_objfile_observer (struct objfile *objfile) { - struct inferior *inf; - /* Invalidate the relevant data in our program-space data. */ if (objfile == NULL) @@ -1468,7 +1466,7 @@ ada_tasks_new_objfile_observer (struct objfile *objfile) If all objfiles are being cleared (OBJFILE is NULL), then clear the caches for all inferiors. */ - for (inf = inferior_list; inf != NULL; inf = inf->next) + for (inferior *inf : all_inferiors ()) if (objfile == NULL || inf->pspace == objfile->pspace) ada_tasks_invalidate_inferior_data (inf); } diff --git a/gdb/inferior-iter.h b/gdb/inferior-iter.h index f999150..1701465 100644 --- a/gdb/inferior-iter.h +++ b/gdb/inferior-iter.h @@ -36,18 +36,21 @@ public: typedef int difference_type; /* Create an iterator pointing at HEAD. */ - all_inferiors_iterator (process_stratum_target *proc_target, inferior *head) - : m_proc_target (proc_target) + all_inferiors_iterator (process_stratum_target *proc_target, + const intrusive_list<inferior> &list) + : m_proc_target (proc_target), m_inf_iter (list.begin ()) { + intrusive_list<inferior>::iterator end; + /* Advance M_INF to the first inferior's position. */ - for (m_inf = head; m_inf != NULL; m_inf = m_inf->next) + for (; m_inf_iter != end; ++m_inf_iter) if (m_inf_matches ()) return; } /* Create a one-past-end iterator. */ all_inferiors_iterator () - : m_proc_target (nullptr), m_inf (nullptr) + : m_proc_target (nullptr) {} all_inferiors_iterator &operator++ () @@ -57,37 +60,39 @@ public: } inferior *operator* () const - { return m_inf; } + { return &*m_inf_iter; } bool operator!= (const all_inferiors_iterator &other) const - { return m_inf != other.m_inf; } + { return m_inf_iter != other.m_inf_iter; } private: /* Advance to next inferior, skipping filtered inferiors. */ void advance () { + intrusive_list<inferior>::iterator end; + /* The loop below is written in the natural way as-if we'd always start at the beginning of the inferior list. This fast-forwards the algorithm to the actual current position. */ goto start; - while (m_inf != NULL) + while (m_inf_iter != end) { if (m_inf_matches ()) return; start: - m_inf = m_inf->next; + ++m_inf_iter; } } bool m_inf_matches () { return (m_proc_target == nullptr - || m_proc_target == m_inf->process_target ()); + || m_proc_target == m_inf_iter->process_target ()); } process_stratum_target *m_proc_target; - inferior *m_inf; + intrusive_list<inferior>::iterator m_inf_iter; }; /* A range adapter that makes it possible to iterate over all diff --git a/gdb/inferior.c b/gdb/inferior.c index 3accf97..9681aaf 100644 --- a/gdb/inferior.c +++ b/gdb/inferior.c @@ -41,7 +41,7 @@ DEFINE_REGISTRY (inferior, REGISTRY_ACCESS_FIELD) -struct inferior *inferior_list = NULL; +intrusive_list<inferior> inferior_list; static int highest_inferior_num; /* See inferior.h. */ @@ -126,16 +126,7 @@ add_inferior_silent (int pid) { inferior *inf = new inferior (pid); - if (inferior_list == NULL) - inferior_list = inf; - else - { - inferior *last; - - for (last = inferior_list; last->next != NULL; last = last->next) - ; - last->next = inf; - } + inferior_list.push_back (*inf); gdb::observers::inferior_added.notify (inf); @@ -177,25 +168,12 @@ inferior::clear_thread_list (bool silent) } void -delete_inferior (struct inferior *todel) +delete_inferior (struct inferior *inf) { - struct inferior *inf, *infprev; - - infprev = NULL; - - for (inf = inferior_list; inf; infprev = inf, inf = inf->next) - if (inf == todel) - break; - - if (!inf) - return; - inf->clear_thread_list (true); - if (infprev) - infprev->next = inf->next; - else - inferior_list = inf->next; + auto it = inferior_list.iterator_to (*inf); + inferior_list.erase (it); gdb::observers::inferior_removed.notify (inf); @@ -210,17 +188,8 @@ delete_inferior (struct inferior *todel) exit of its threads. */ static void -exit_inferior_1 (struct inferior *inftoex, int silent) +exit_inferior_1 (struct inferior *inf, int silent) { - struct inferior *inf; - - for (inf = inferior_list; inf; inf = inf->next) - if (inf == inftoex) - break; - - if (!inf) - return; - inf->clear_thread_list (silent); gdb::observers::inferior_exit.notify (inf); @@ -388,22 +357,14 @@ have_live_inferiors (void) void prune_inferiors (void) { - inferior *ss; - - ss = inferior_list; - while (ss) + for (inferior *inf : all_inferiors_safe ()) { - if (!ss->deletable () - || !ss->removable - || ss->pid != 0) - { - ss = ss->next; - continue; - } + if (!inf->deletable () + || !inf->removable + || inf->pid != 0) + continue; - inferior *ss_next = ss->next; - delete_inferior (ss); - ss = ss_next; + delete_inferior (inf); } } diff --git a/gdb/inferior.h b/gdb/inferior.h index 2ae9f9a..830dec3 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -55,6 +55,7 @@ struct thread_info; #include "gdbsupport/refcounted-object.h" #include "gdbsupport/forward-scope-exit.h" #include "gdbsupport/gdb_unique_ptr.h" +#include "gdbsupport/intrusive_list.h" #include "gdbsupport/common-inferior.h" #include "gdbthread.h" @@ -339,7 +340,8 @@ extern void switch_to_inferior_no_thread (inferior *inf); listed exactly once in the inferior list, so placing an inferior in the inferior list is an implicit, not counted strong reference. */ -class inferior : public refcounted_object +class inferior : public refcounted_object, + public intrusive_list_node<inferior> { public: explicit inferior (int pid); @@ -387,9 +389,6 @@ public: bool has_execution () { return target_has_execution (this); } - /* Pointer to next inferior in singly-linked list of inferiors. */ - struct inferior *next = NULL; - /* This inferior's thread list, sorted by creation order. */ intrusive_list<thread_info> thread_list; @@ -653,7 +652,7 @@ private: /* Traverse all inferiors. */ -extern struct inferior *inferior_list; +extern intrusive_list<inferior> inferior_list; /* Pull in the internals of the inferiors ranges and iterators. Must be done after struct inferior is defined. */ diff --git a/gdb/infrun.c b/gdb/infrun.c index 8cfd58b..300d627 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -3730,18 +3730,28 @@ do_target_wait (execution_control_state *ecs, target_wait_flags options) reported the stop to the user, polling for events. */ scoped_restore_current_thread restore_thread; - int inf_num = selected->num; - for (inferior *inf = selected; inf != NULL; inf = inf->next) - if (inferior_matches (inf)) - if (do_wait (inf)) + intrusive_list_iterator<inferior> start + = inferior_list.iterator_to (*selected); + + for (intrusive_list_iterator<inferior> it = start; + it != inferior_list.end (); + ++it) + { + inferior *inf = &*it; + + if (inferior_matches (inf) && do_wait (inf)) return true; + } - for (inferior *inf = inferior_list; - inf != NULL && inf->num < inf_num; - inf = inf->next) - if (inferior_matches (inf)) - if (do_wait (inf)) + for (intrusive_list_iterator<inferior> it = inferior_list.begin (); + it != start; + ++it) + { + inferior *inf = &*it; + + if (inferior_matches (inf) && do_wait (inf)) return true; + } ecs->ws.kind = TARGET_WAITKIND_IGNORE; return false; @@ -9452,7 +9462,6 @@ infrun_thread_ptid_changed () scoped_mock_context<test_target_ops> target1 (arch); scoped_mock_context<test_target_ops> target2 (arch); - target2.mock_inferior.next = &target1.mock_inferior; ptid_t old_ptid (111, 222); ptid_t new_ptid (111, 333); @@ -9477,7 +9486,6 @@ infrun_thread_ptid_changed () scoped_mock_context<test_target_ops> target1 (arch); scoped_mock_context<test_target_ops> target2 (arch); - target2.mock_inferior.next = &target1.mock_inferior; ptid_t old_ptid (111, 222); ptid_t new_ptid (111, 333); diff --git a/gdb/progspace.c b/gdb/progspace.c index e3cc692..7080bf8 100644 --- a/gdb/progspace.c +++ b/gdb/progspace.c @@ -404,7 +404,6 @@ void update_address_spaces (void) { int shared_aspace = gdbarch_has_shared_address_space (target_gdbarch ()); - struct inferior *inf; init_address_spaces (); @@ -423,7 +422,7 @@ update_address_spaces (void) pspace->aspace = new_address_space (); } - for (inf = inferior_list; inf; inf = inf->next) + for (inferior *inf : all_inferiors ()) if (gdbarch_has_global_solist (target_gdbarch ())) inf->aspace = maybe_new_address_space (); else diff --git a/gdb/regcache.c b/gdb/regcache.c index fde0c61..21fa25d 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -2038,7 +2038,6 @@ regcache_thread_ptid_changed () /* Prepare two targets with one thread each, with the same ptid. */ scoped_mock_context<test_target_ops> target1 (arch); scoped_mock_context<test_target_ops> target2 (arch); - target2.mock_inferior.next = &target1.mock_inferior; ptid_t old_ptid (111, 222); ptid_t new_ptid (111, 333); diff --git a/gdb/scoped-mock-context.h b/gdb/scoped-mock-context.h index 37ffe51..ba3b81e 100644 --- a/gdb/scoped-mock-context.h +++ b/gdb/scoped-mock-context.h @@ -44,13 +44,12 @@ struct scoped_mock_context scoped_restore_current_pspace_and_thread restore_pspace_thread; - /* Add the mock inferior to the inferior list so that look ups by - target+ptid can find it. */ - scoped_restore_tmpl<inferior *> restore_inferior_list - {&inferior_list, &mock_inferior}; - explicit scoped_mock_context (gdbarch *gdbarch) { + /* Add the mock inferior to the inferior list so that look ups by + target+ptid can find it. */ + inferior_list.push_back (mock_inferior); + mock_inferior.thread_list.push_back (mock_thread); mock_inferior.gdbarch = gdbarch; mock_inferior.aspace = mock_pspace.aspace; @@ -70,6 +69,7 @@ struct scoped_mock_context ~scoped_mock_context () { + inferior_list.erase (inferior_list.iterator_to (mock_inferior)); pop_all_targets_at_and_above (process_stratum); } }; diff --git a/gdb/thread-iter.c b/gdb/thread-iter.c index a1cdd02..31b7a36 100644 --- a/gdb/thread-iter.c +++ b/gdb/thread-iter.c @@ -26,15 +26,18 @@ all_threads_iterator::all_threads_iterator (begin_t) { /* Advance M_INF/M_THR to the first thread's position. */ - for (m_inf = inferior_list; m_inf != NULL; m_inf = m_inf->next) + + for (inferior &inf : inferior_list) { - auto thr_iter = m_inf->thread_list.begin (); - if (thr_iter != m_inf->thread_list.end ()) + auto thr_iter = inf.thread_list.begin (); + if (thr_iter != inf.thread_list.end ()) { + m_inf = &inf; m_thr = &*thr_iter; return; } } + m_inf = nullptr; m_thr = nullptr; } @@ -43,6 +46,7 @@ all_threads_iterator::all_threads_iterator (begin_t) void all_threads_iterator::advance () { + intrusive_list<inferior>::iterator inf_iter (m_inf); intrusive_list<thread_info>::iterator thr_iter (m_thr); /* The loop below is written in the natural way as-if we'd always @@ -50,8 +54,9 @@ all_threads_iterator::advance () the algorithm to the actual current position. */ goto start; - for (; m_inf != NULL; m_inf = m_inf->next) + for (; inf_iter != inferior_list.end (); ++inf_iter) { + m_inf = &*inf_iter; thr_iter = m_inf->thread_list.begin (); while (thr_iter != m_inf->thread_list.end ()) { @@ -86,16 +91,21 @@ all_matching_threads_iterator::all_matching_threads_iterator gdb_assert ((filter_target == nullptr && filter_ptid == minus_one_ptid) || filter_target->stratum () == process_stratum); - for (m_inf = inferior_list; m_inf != NULL; m_inf = m_inf->next) - if (m_inf_matches ()) - for (auto thr_iter = m_inf->thread_list.begin (); - thr_iter != m_inf->thread_list.end (); - ++thr_iter) - if (thr_iter->ptid.matches (m_filter_ptid)) + for (inferior &inf : inferior_list) + { + m_inf = &inf; + if (m_inf_matches ()) + for (auto thr_iter = m_inf->thread_list.begin (); + thr_iter != m_inf->thread_list.end (); + ++thr_iter) { - m_thr = &*thr_iter; - return; + if (thr_iter->ptid.matches (m_filter_ptid)) + { + m_thr = &*thr_iter; + return; + } } + } m_thr = nullptr; } @@ -105,6 +115,7 @@ all_matching_threads_iterator::all_matching_threads_iterator void all_matching_threads_iterator::advance () { + intrusive_list<inferior>::iterator inf_iter (m_inf); intrusive_list<thread_info>::iterator thr_iter (m_thr); /* The loop below is written in the natural way as-if we'd always @@ -112,21 +123,24 @@ all_matching_threads_iterator::advance () the algorithm to the actual current position. */ goto start; - for (; m_inf != NULL; m_inf = m_inf->next) - if (m_inf_matches ()) - { - thr_iter = m_inf->thread_list.begin (); - while (thr_iter != m_inf->thread_list.end ()) - { - if (thr_iter->ptid.matches (m_filter_ptid)) - { - m_thr = &*thr_iter; - return; - } - start: - ++thr_iter; - } - } + for (; inf_iter != inferior_list.end (); ++inf_iter) + { + m_inf = &*inf_iter; + if (m_inf_matches ()) + { + thr_iter = m_inf->thread_list.begin (); + while (thr_iter != m_inf->thread_list.end ()) + { + if (thr_iter->ptid.matches (m_filter_ptid)) + { + m_thr = &*thr_iter; + return; + } + start: + ++thr_iter; + } + } + } m_thr = nullptr; } diff --git a/gdb/thread.c b/gdb/thread.c index 89f51c0..506e93c 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -1395,7 +1395,11 @@ show_thread_that_caused_stop (void) int show_inferior_qualified_tids (void) { - return (inferior_list->next != NULL || inferior_list->num != 1); + auto inf = inferior_list.begin (); + if (inf->num != 1) + return true; + ++inf; + return inf != inferior_list.end (); } /* See gdbthread.h. */ |