Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Yao Qi <qiyaoltc@gmail.com>
To: gdb-patches@sourceware.org
Subject: [PATCH 2/3] Get pending events in random
Date: Mon, 26 Sep 2016 02:25:00 -0000	[thread overview]
Message-ID: <1474856716-5913-3-git-send-email-yao.qi@linaro.org> (raw)
In-Reply-To: <1474856716-5913-1-git-send-email-yao.qi@linaro.org>

Nowadays, we select events to be reported to GDB in random, however
that is not enough when many GDBserver internal events (not reported
to GDB) are generated.

GDBserver pulls all events out of kernel via waitpid, and leave them
pending.  When goes through threads which have pending events,
GDBserver uses find_inferior to find the first thread which has
pending event, and consumes it.  Note that find_inferior always
iterate threads in a fixed order.  If multiple threads keep hitting
GDBserver breakpoints, range stepping with single-step breakpoint for
example, threads in the head of the thread list are more likely to be
processed and threads in the tail are starved.  This causes some timeout
fails in gdb.threads/non-stop-fair-events.exp when range stepping is
enabled on arm-linux.

This patch fixes this issue by randomly selecting pending events.  It
adds a new function find_inferior_in_random, which iterates threads
which have pending events randomly.

gdb/gdbserver:

2016-09-25  Yao Qi  <yao.qi@linaro.org>

	* inferiors.c (find_inferior_in_random): New function.
	* inferiors.h (find_inferior_in_random): Declare.
	* linux-low.c (linux_wait_for_event_filtered): Call
	find_inferior_in_random instead of find_inferior.
---
 gdb/gdbserver/inferiors.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 gdb/gdbserver/inferiors.h |  5 +++++
 gdb/gdbserver/linux-low.c |  6 ++++--
 3 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c
index 7888f3c..574a7ba 100644
--- a/gdb/gdbserver/inferiors.c
+++ b/gdb/gdbserver/inferiors.c
@@ -248,6 +248,51 @@ find_inferior (struct inferior_list *list,
   return NULL;
 }
 
+/* Find the random inferior_list_entry E in LIST for which FUNC (E, ARG)
+   returns non-zero.  If no entry is found then return NULL.  */
+
+struct inferior_list_entry *
+find_inferior_in_random (struct inferior_list *list,
+			 int (*func) (struct inferior_list_entry *, void *),
+			 void *arg)
+{
+  struct inferior_list_entry *inf = list->head;
+  int count = 0;
+  int random_selector;
+
+  /* First count how many interesting entries we have.  */
+  while (inf != NULL)
+    {
+      struct inferior_list_entry *next;
+
+      next = inf->next;
+      if ((*func) (inf, arg))
+	count++;
+      inf = next;
+    }
+
+  if (count == 0)
+    return NULL;
+
+  /* Now randomly pick an entry out of those.  */
+  random_selector = (int)
+    ((count * (double) rand ()) / (RAND_MAX + 1.0));
+
+  inf = list->head;
+  while (inf != NULL)
+    {
+      struct inferior_list_entry *next;
+
+      next = inf->next;
+      if ((*func) (inf, arg) && (random_selector-- == 0))
+	return inf;
+      inf = next;
+    }
+
+  gdb_assert_not_reached ("failed to find an inferior in random.");
+  return NULL;
+}
+
 struct inferior_list_entry *
 find_inferior_id (struct inferior_list *list, ptid_t id)
 {
diff --git a/gdb/gdbserver/inferiors.h b/gdb/gdbserver/inferiors.h
index 65ab1c6..6ea7a99 100644
--- a/gdb/gdbserver/inferiors.h
+++ b/gdb/gdbserver/inferiors.h
@@ -154,6 +154,11 @@ struct inferior_list_entry *find_inferior
       void *arg);
 struct inferior_list_entry *find_inferior_id (struct inferior_list *list,
 					      ptid_t id);
+struct inferior_list_entry *
+  find_inferior_in_random (struct inferior_list *,
+			   int (*func) (struct inferior_list_entry *,
+					void *),
+			   void *arg);
 
 void *inferior_target_data (struct thread_info *);
 void set_inferior_target_data (struct thread_info *, void *);
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index fd3cd5a..25dd60c 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -2695,7 +2695,8 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
   if (ptid_equal (filter_ptid, minus_one_ptid) || ptid_is_pid (filter_ptid))
     {
       event_thread = (struct thread_info *)
-	find_inferior (&all_threads, status_pending_p_callback, &filter_ptid);
+	find_inferior_in_random (&all_threads, status_pending_p_callback,
+				 &filter_ptid);
       if (event_thread != NULL)
 	event_child = get_thread_lwp (event_thread);
       if (debug_threads && event_thread)
@@ -2806,7 +2807,8 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
       /* ... and find an LWP with a status to report to the core, if
 	 any.  */
       event_thread = (struct thread_info *)
-	find_inferior (&all_threads, status_pending_p_callback, &filter_ptid);
+	find_inferior_in_random (&all_threads, status_pending_p_callback,
+				 &filter_ptid);
       if (event_thread != NULL)
 	{
 	  event_child = get_thread_lwp (event_thread);
-- 
1.9.1


  parent reply	other threads:[~2016-09-26  2:25 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-26  2:25 [PATCH 0/3] Support range stepping on software single-step target Yao Qi
2016-09-26  2:25 ` [PATCH 3/3] Enable range stepping if software single step is supported Yao Qi
2016-09-26  2:25 ` Yao Qi [this message]
2016-09-26  2:47 ` [PATCH 1/3] Remove single-step breakpoint for GDBserver internal event Yao Qi
2016-10-26 17:45   ` Pedro Alves
2016-10-26 20:14     ` Yao Qi
2016-10-27 13:16       ` Pedro Alves
2016-10-27 14:14         ` Yao Qi
2016-10-27 14:14           ` Pedro Alves
2016-10-10  8:43 ` [PATCH 0/3] Support range stepping on software single-step target Yao Qi
2016-10-26 15:39   ` Yao Qi
2016-10-26 17:34     ` Antoine Tremblay
2016-10-27 15:07       ` Yao Qi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1474856716-5913-3-git-send-email-yao.qi@linaro.org \
    --to=qiyaoltc@gmail.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox