From b494cdff6922944383ef4dc20fcc90c4d823d315 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sun, 7 Apr 2019 16:17:40 -0600 Subject: [PATCH] Use std::list for event notifications in gdbserver This changes gdbserver to use std::list rather than common/queue.h for event notifications. gdb/gdbserver/ChangeLog 2019-04-19 Tom Tromey * server.c (struct vstop_notif): Derive from notif_event. : Remove. (queue_stop_reply): Update. (remove_all_on_match_ptid): Change type. Rewrite. (discard_queued_stop_replies): Rewrite. (in_queued_stop_replies_ptid): Change type. (in_queued_stop_replies): Rewrite. (notif_stop): Update. (queue_stop_reply_callback): Update. (captured_main): Don't call initialize_notif. (push_stop_notification): Update. * notif.c (notif_write_event, handle_notif_ack) (notif_event_enque, notif_push): Update. (notif_event_xfree, initialize_notif): Remove. * notif.h (struct notif_event): Include , not "common/queue.h". (struct notif_server) : Now a std::list. (notif_event_p): Remove typedef. (initialize_notif): Don't declare. (struct notif_event): Add virtual destructor. --- gdb/gdbserver/ChangeLog | 23 ++++++++++++++ gdb/gdbserver/notif.c | 37 +++++++---------------- gdb/gdbserver/notif.h | 17 +++++------ gdb/gdbserver/server.c | 80 +++++++++++++++++++++++-------------------------- 4 files changed, 78 insertions(+), 79 deletions(-) diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index f8f600e..2985281 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,26 @@ +2019-04-19 Tom Tromey + + * server.c (struct vstop_notif): Derive from notif_event. + : Remove. + (queue_stop_reply): Update. + (remove_all_on_match_ptid): Change type. Rewrite. + (discard_queued_stop_replies): Rewrite. + (in_queued_stop_replies_ptid): Change type. + (in_queued_stop_replies): Rewrite. + (notif_stop): Update. + (queue_stop_reply_callback): Update. + (captured_main): Don't call initialize_notif. + (push_stop_notification): Update. + * notif.c (notif_write_event, handle_notif_ack) + (notif_event_enque, notif_push): Update. + (notif_event_xfree, initialize_notif): Remove. + * notif.h (struct notif_event): Include , not + "common/queue.h". + (struct notif_server) : Now a std::list. + (notif_event_p): Remove typedef. + (initialize_notif): Don't declare. + (struct notif_event): Add virtual destructor. + 2019-04-17 Alan Hayward * ax.c (ax_vdebug): Call debug_printf. diff --git a/gdb/gdbserver/notif.c b/gdb/gdbserver/notif.c index d581ccc..0b526ed 100644 --- a/gdb/gdbserver/notif.c +++ b/gdb/gdbserver/notif.c @@ -61,10 +61,9 @@ static struct notif_server *notifs[] = void notif_write_event (struct notif_server *notif, char *own_buf) { - if (!QUEUE_is_empty (notif_event_p, notif->queue)) + if (!notif->queue.empty ()) { - struct notif_event *event - = QUEUE_peek (notif_event_p, notif->queue); + struct notif_event *event = notif->queue.front (); notif->write (event, own_buf); } @@ -98,16 +97,16 @@ handle_notif_ack (char *own_buf, int packet_len) /* If we're waiting for GDB to acknowledge a pending event, consider that done. */ - if (!QUEUE_is_empty (notif_event_p, np->queue)) + if (!np->queue.empty ()) { - struct notif_event *head - = QUEUE_deque (notif_event_p, np->queue); + struct notif_event *head = np->queue.front (); + np->queue.pop_front (); if (remote_debug) debug_printf ("%s: acking %d\n", np->ack_name, - QUEUE_length (notif_event_p, np->queue)); + (int) np->queue.size ()); - xfree (head); + delete head; } notif_write_event (np, own_buf); @@ -121,11 +120,11 @@ void notif_event_enque (struct notif_server *notif, struct notif_event *event) { - QUEUE_enque (notif_event_p, notif->queue, event); + notif->queue.push_back (event); if (remote_debug) debug_printf ("pending events: %s %d\n", notif->notif_name, - QUEUE_length (notif_event_p, notif->queue)); + (int) notif->queue.size ()); } @@ -134,7 +133,7 @@ notif_event_enque (struct notif_server *notif, void notif_push (struct notif_server *np, struct notif_event *new_event) { - int is_first_event = QUEUE_is_empty (notif_event_p, np->queue); + bool is_first_event = np->queue.empty (); /* Something interesting. Tell GDB about it. */ notif_event_enque (np, new_event); @@ -153,19 +152,3 @@ notif_push (struct notif_server *np, struct notif_event *new_event) putpkt_notif (buf); } } - -static void -notif_event_xfree (struct notif_event *event) -{ - xfree (event); -} - -void -initialize_notif (void) -{ - int i = 0; - - for (i = 0; i < ARRAY_SIZE (notifs); i++) - notifs[i]->queue - = QUEUE_alloc (notif_event_p, notif_event_xfree); -} diff --git a/gdb/gdbserver/notif.h b/gdb/gdbserver/notif.h index 7d07679..c052512 100644 --- a/gdb/gdbserver/notif.h +++ b/gdb/gdbserver/notif.h @@ -20,19 +20,20 @@ #define GDBSERVER_NOTIF_H #include "target.h" -#include "common/queue.h" +#include /* Structure holding information related to a single event. We keep a queue of these to push to GDB. It can be extended if the event of given notification contains more information. */ -typedef struct notif_event +struct notif_event { - /* C requires that a struct or union has at least one member. */ - char dummy; -} *notif_event_p; + virtual ~notif_event () + { + } -DECLARE_QUEUE_P (notif_event_p); + /* No payload needed. */ +}; /* A type notification to GDB. An object of 'struct notif_server' represents a type of notification. */ @@ -49,7 +50,7 @@ typedef struct notif_server /* A queue of events to GDB. A new notif_event can be enque'ed into QUEUE at any appropriate time, and the notif_reply is deque'ed only when the ack from GDB arrives. */ - QUEUE (notif_event_p) *queue; + std::list queue; /* Write event EVENT to OWN_BUF. */ void (*write) (struct notif_event *event, char *own_buf); @@ -64,6 +65,4 @@ void notif_push (struct notif_server *np, struct notif_event *event); void notif_event_enque (struct notif_server *notif, struct notif_event *event); -void initialize_notif (void); - #endif /* GDBSERVER_NOTIF_H */ diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index 36510ad..fae5b24 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -140,10 +140,8 @@ static unsigned char *mem_buf; relative to a single stop reply. We keep a queue of these to push to GDB in non-stop mode. */ -struct vstop_notif +struct vstop_notif : public notif_event { - struct notif_event base; - /* Thread or process that got the event. */ ptid_t ptid; @@ -155,8 +153,6 @@ struct vstop_notif btrace configuration. */ static struct btrace_config current_btrace_conf; -DEFINE_QUEUE_P (notif_event_p); - /* The client remote protocol state. */ static client_state g_client_state; @@ -174,32 +170,20 @@ get_client_state () static void queue_stop_reply (ptid_t ptid, struct target_waitstatus *status) { - struct vstop_notif *new_notif = XNEW (struct vstop_notif); + struct vstop_notif *new_notif = new struct vstop_notif; new_notif->ptid = ptid; new_notif->status = *status; - notif_event_enque (¬if_stop, (struct notif_event *) new_notif); + notif_event_enque (¬if_stop, new_notif); } -static int -remove_all_on_match_ptid (QUEUE (notif_event_p) *q, - QUEUE_ITER (notif_event_p) *iter, - struct notif_event *event, - void *data) +static bool +remove_all_on_match_ptid (struct notif_event *event, ptid_t filter_ptid) { - ptid_t filter_ptid = *(ptid_t *) data; struct vstop_notif *vstop_event = (struct vstop_notif *) event; - if (vstop_event->ptid.matches (filter_ptid)) - { - if (q->free_func != NULL) - q->free_func (event); - - QUEUE_remove_elem (notif_event_p, q, iter); - } - - return 1; + return vstop_event->ptid.matches (filter_ptid); } /* See server.h. */ @@ -207,8 +191,19 @@ remove_all_on_match_ptid (QUEUE (notif_event_p) *q, void discard_queued_stop_replies (ptid_t ptid) { - QUEUE_iterate (notif_event_p, notif_stop.queue, - remove_all_on_match_ptid, &ptid); + std::list::iterator iter, next, end; + end = notif_stop.queue.end (); + for (iter = notif_stop.queue.begin (); iter != end; iter = next) + { + next = iter; + ++next; + + if (remove_all_on_match_ptid (*iter, ptid)) + { + delete *iter; + notif_stop.queue.erase (iter); + } + } } static void @@ -219,27 +214,23 @@ vstop_notif_reply (struct notif_event *event, char *own_buf) prepare_resume_reply (own_buf, vstop->ptid, &vstop->status); } -/* QUEUE_iterate callback helper for in_queued_stop_replies. */ +/* Helper for in_queued_stop_replies. */ -static int -in_queued_stop_replies_ptid (QUEUE (notif_event_p) *q, - QUEUE_ITER (notif_event_p) *iter, - struct notif_event *event, - void *data) +static bool +in_queued_stop_replies_ptid (struct notif_event *event, ptid_t filter_ptid) { - ptid_t filter_ptid = *(ptid_t *) data; struct vstop_notif *vstop_event = (struct vstop_notif *) event; if (vstop_event->ptid.matches (filter_ptid)) - return 0; + return true; /* Don't resume fork children that GDB does not know about yet. */ if ((vstop_event->status.kind == TARGET_WAITKIND_FORKED || vstop_event->status.kind == TARGET_WAITKIND_VFORKED) && vstop_event->status.value.related_pid.matches (filter_ptid)) - return 0; + return true; - return 1; + return false; } /* See server.h. */ @@ -247,13 +238,18 @@ in_queued_stop_replies_ptid (QUEUE (notif_event_p) *q, int in_queued_stop_replies (ptid_t ptid) { - return !QUEUE_iterate (notif_event_p, notif_stop.queue, - in_queued_stop_replies_ptid, &ptid); + for (notif_event *event : notif_stop.queue) + { + if (in_queued_stop_replies_ptid (event, ptid)) + return true; + } + + return false; } struct notif_server notif_stop = { - "vStopped", "Stop", NULL, vstop_notif_reply, + "vStopped", "Stop", {}, vstop_notif_reply, }; static int @@ -3247,14 +3243,13 @@ queue_stop_reply_callback (thread_info *thread) manage the thread's last_status field. */ if (the_target->thread_stopped == NULL) { - struct vstop_notif *new_notif = XNEW (struct vstop_notif); + struct vstop_notif *new_notif = new struct vstop_notif; new_notif->ptid = thread->id; new_notif->status = thread->last_status; /* Pass the last stop reply back to GDB, but don't notify yet. */ - notif_event_enque (¬if_stop, - (struct notif_event *) new_notif); + notif_event_enque (¬if_stop, new_notif); } else { @@ -3789,7 +3784,6 @@ captured_main (int argc, char *argv[]) initialize_event_loop (); if (target_supports_tracepoints ()) initialize_tracepoint (); - initialize_notif (); mem_buf = (unsigned char *) xmalloc (PBUFSIZ); @@ -4412,12 +4406,12 @@ handle_serial_event (int err, gdb_client_data client_data) static void push_stop_notification (ptid_t ptid, struct target_waitstatus *status) { - struct vstop_notif *vstop_notif = XNEW (struct vstop_notif); + struct vstop_notif *vstop_notif = new struct vstop_notif; vstop_notif->status = *status; vstop_notif->ptid = ptid; /* Push Stop notification. */ - notif_push (¬if_stop, (struct notif_event *) vstop_notif); + notif_push (¬if_stop, vstop_notif); } /* Event-loop callback for target events. */ -- 2.7.4