From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 115038 invoked by alias); 26 Sep 2016 02:25:33 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 114925 invoked by uid 89); 26 Sep 2016 02:25:32 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.5 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,RCVD_IN_SORBS_SPAM,SPF_PASS autolearn=no version=3.3.2 spammy=H*RU:209.85.220.68, Hx-spam-relays-external:209.85.220.68, nowadays, HX-Received:10.66.86.42 X-HELO: mail-pa0-f68.google.com Received: from mail-pa0-f68.google.com (HELO mail-pa0-f68.google.com) (209.85.220.68) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 26 Sep 2016 02:25:23 +0000 Received: by mail-pa0-f68.google.com with SMTP id j3so43119paj.2 for ; Sun, 25 Sep 2016 19:25:22 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=hPK7B6H9SkR3eO+QtdgOy5XRITcPV2YbuwFRGCh0j2g=; b=FhoeCQA/6BiEkgAEn2X1k27mv6HPXlHVp8ziXFGkNIt0K960Uanf2nEXebK6BT2/yx 6Ivvxs0AAjKa7jNTedwzuvQS9i/S0ytXLOaQ0+ECt6am6R3z/94PpBvKgHUp++mykcvp qY+6TQyazjcBVCX5ZzUQnJGjzxsFz9fPankpchpvr/eledhXCJIxlMmEdMgLe3Poz8MH fNBS1qC7tgwpGmZZgCT/jtP4ge++/snAVX8v1aRZOYqIFxConPTIL4DvBA/xsTV7NBWh sS4C6BhuJtvQ+Wt2rijteDkETWcrE2baC4UuIVoHP5K4hgyAgMY27SVwm96pn9COirTi Th8w== X-Gm-Message-State: AA6/9Rn0xCMpZ00mlerCOALdo37DlXUodBY8CUPKSBvplRprrMPOv+xC+03K5WqSgGxOFQ== X-Received: by 10.66.86.42 with SMTP id m10mr9044518paz.84.1474856721508; Sun, 25 Sep 2016 19:25:21 -0700 (PDT) Received: from localhost.localdomain (gcc1-power7.osuosl.org. [140.211.15.137]) by smtp.gmail.com with ESMTPSA id m82sm26179741pfk.64.2016.09.25.19.25.20 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 25 Sep 2016 19:25:21 -0700 (PDT) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [PATCH 2/3] Get pending events in random Date: Mon, 26 Sep 2016 02:25:00 -0000 Message-Id: <1474856716-5913-3-git-send-email-yao.qi@linaro.org> In-Reply-To: <1474856716-5913-1-git-send-email-yao.qi@linaro.org> References: <1474856716-5913-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes X-SW-Source: 2016-09/txt/msg00329.txt.bz2 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 * 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