gdb: defer commit resume until all available events are consumed concurrent-displaced-stepping-batching
authorSimon Marchi <simon.marchi@efficios.com>
Mon, 6 Jul 2020 19:53:28 +0000 (15:53 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Wed, 8 Jul 2020 18:43:16 +0000 (14:43 -0400)
This patch makes GDB defer commit resume when handling a sequence of
target events.

In fetch_inferior_event, a scoped_restore object is instantiated (if
it's not already) to set the defer_commit_resume flag.  Any resumption
that is the result of handling that event will therefore not be
committed.

If there are other events immediatly consumable, they'll all be handled
while the "defer commit resume flag" is set.  Once do_target_wait returns
false, we know that we have consumed all immediatly available events,
then the "defer commit resume" flag is reset and a commit resume is
issued.

After having handled an event in fetch_inferior_event, we call
mark_infrun_async_event_handler to make sure that fetch_inferior_event
gets called at least once more, to get that final call where
do_target_wait returns no event.

Change-Id: I18112ba19a1ff4986530c660f530d847bb4a1f1d

gdb/infrun.c

index ad7ff7f1a89dd01b01586e27573bd1557c5628b9..a702940a7207eb7c07f75f59a4e921e807d3bc5a 100644 (file)
@@ -3889,9 +3889,19 @@ fetch_inferior_event ()
       = make_scoped_restore (&execution_direction,
                             target_execution_direction ());
 
+    /* Hold the resume commands until we are done consuming all immediately
+       available target events.  */
+    static gdb::optional<scoped_restore_tmpl<int>> restore_defer_commit_resume;
+    if (!restore_defer_commit_resume.has_value ())
+      restore_defer_commit_resume.emplace (make_scoped_defer_target_commit_resume ());
+
     if (!do_target_wait (minus_one_ptid, ecs, TARGET_WNOHANG))
       {
        infrun_log_debug ("do_target_wait returned false");
+
+       /* No more events to process, let the resume commands free.  */
+       restore_defer_commit_resume.reset ();
+       commit_resume_all_targets();
        return;
       }
 
@@ -3991,6 +4001,8 @@ fetch_inferior_event ()
     /* No error, don't finish the thread states yet.  */
     finish_state.release ();
 
+    mark_infrun_async_event_handler ();
+
     /* This scope is used to ensure that readline callbacks are
        reinstalled here.  */
   }
This page took 0.027763 seconds and 4 git commands to generate.