[PATCH 1/3] gdbserver: replace event_queue with QUEUE

Yao Qi
2013-01-24T01:15:02Z

Hi,
We recently add a new data structure QUEUE (in common/queue.h), and we
can use it more widely. This patch is to rewrite 'event_queue' in
event-loop.c using QUEUE.

Regression tested on x86_64-linux with boardfile
{unix, native-gdbserver} x {sync, async}.

gdb/gdbserver:

2013-01-24 Yao Qi <yao@codesourcery.com>

* event-loop.c: Include "queue.h".
(gdb_event_p): New typedef.
(struct gdb_event) <next_event>: Remove.
(event_queue): Change to QUEUE(gdb_event_p).
(async_queue_event): Remove.
(process_event): Use API from QUEUE.
(wait_for_event): Likewise.
(gdb_event_xfree): New.
(start_event_loop): Initialize "event_queue".
---
gdb/gdbserver/event-loop.c | 118 ++++++++++++--------------------------------
1 files changed, 31 insertions(+), 87 deletions(-)

diff --git a/gdb/gdbserver/event-loop.c b/gdb/gdbserver/event-loop.c
index 87487e0..53442e6 100644
--- a/gdb/gdbserver/event-loop.c
+++ b/gdb/gdbserver/event-loop.c
@@ -19,6 +19,7 @@
/* Based on src/gdb/event-loop.c. */

#include "server.h"
+#include "queue.h"

#include <sys/types.h>
#include <string.h>
@@ -46,7 +47,8 @@ typedef int (event_handler_func) (gdb_fildes_t);
#define GDB_WRITABLE (1<<2)
#define GDB_EXCEPTION (1<<3)

-/* Events are queued by calling async_queue_event and serviced later
+/* Events are queued by calling 'QUEUE_enque (gdb_event_p, event_queue,
+ file_event_ptr)' and serviced later
on by do_one_event. An event can be, for instance, a file
descriptor becoming ready to be read. Servicing an event simply
means that the procedure PROC will be called. We have 2 queues,
@@ -57,17 +59,14 @@ typedef int (event_handler_func) (gdb_fildes_t);
descriptor whose state change generated the event, plus doing other
cleanups and such. */

-struct gdb_event
+typedef struct gdb_event
{
/* Procedure to call to service this event. */
event_handler_func *proc;

/* File descriptor that is ready. */
gdb_fildes_t fd;
-
- /* Next in list of events or NULL. */
- struct gdb_event *next_event;
- };
+ } *gdb_event_p;

/* Information about each file descriptor we register with the event
loop. */
@@ -97,25 +96,9 @@ typedef struct file_handler
}
file_handler;

-/* Event queue:
-
- Events can be inserted at the front of the queue or at the end of
- the queue. Events will be extracted from the queue for processing
- starting from the head. Therefore, events inserted at the head of
- the queue will be processed in a last in first out fashion, while
- those inserted at the tail of the queue will be processed in a
- first in first out manner. All the fields are NULL if the queue is
- empty. */
-
-static struct
- {
- /* The first pending event. */
- gdb_event *first_event;
-
- /* The last pending event. */
- gdb_event *last_event;
- }
-event_queue;
+DECLARE_QUEUE_P(gdb_event_p);
+static QUEUE(gdb_event_p) *event_queue = NULL;
+DEFINE_QUEUE_P(gdb_event_p);

/* Gdb_notifier is just a list of file descriptors gdb is interested
in. These are the input file descriptor, and the target file
@@ -170,27 +153,6 @@ static struct
}
callback_list;

-/* Insert an event object into the gdb event queue.
-
- EVENT_PTR points to the event to be inserted into the queue. The
- caller must allocate memory for the event. It is freed after the
- event has ben handled. Events in the queue will be processed head
- to tail, therefore, events will be processed first in first
- out. */
-
-static void
-async_queue_event (gdb_event *event_ptr)
-{
- /* The event will become the new last_event. */
-
- event_ptr->next_event = NULL;
- if (event_queue.first_event == NULL)
- event_queue.first_event = event_ptr;
- else
- event_queue.last_event->next_event = event_ptr;
- event_queue.last_event = event_ptr;
-}
-
/* Process one event. If an event was processed, 1 is returned
otherwise 0 is returned. Scan the queue from head to tail,
processing therefore the high priority events first, by invoking
@@ -199,46 +161,18 @@ async_queue_event (gdb_event *event_ptr)
static int
process_event (void)
{
- gdb_event *event_ptr, *prev_ptr;
- event_handler_func *proc;
- gdb_fildes_t fd;
-
- /* Look in the event queue to find an event that is ready
- to be processed. */
-
- for (event_ptr = event_queue.first_event;
- event_ptr != NULL;
- event_ptr = event_ptr->next_event)
+ /* Let's get rid of the event from the event queue. We need to
+ do this now because while processing the event, since the
+ proc function could end up jumping out to the caller of this
+ function. In that case, we would have on the event queue an
+ event which has been processed, but not deleted. */
+ if (!QUEUE_is_empty (gdb_event_p, event_queue))
{
- /* Call the handler for the event. */
-
- proc = event_ptr->proc;
- fd = event_ptr->fd;
-
- /* Let's get rid of the event from the event queue. We need to
- do this now because while processing the event, since the
- proc function could end up jumping out to the caller of this
- function. In that case, we would have on the event queue an
- event which has been processed, but not deleted. */
-
- if (event_queue.first_event == event_ptr)
- {
- event_queue.first_event = event_ptr->next_event;
- if (event_ptr->next_event == NULL)
- event_queue.last_event = NULL;
- }
- else
- {
- prev_ptr = event_queue.first_event;
- while (prev_ptr->next_event != event_ptr)
- prev_ptr = prev_ptr->next_event;
-
- prev_ptr->next_event = event_ptr->next_event;
- if (event_ptr->next_event == NULL)
- event_queue.last_event = prev_ptr;
- }
- free (event_ptr);
+ gdb_event *event_ptr = QUEUE_deque (gdb_event_p, event_queue);
+ event_handler_func *proc = event_ptr->proc;
+ gdb_fildes_t fd = event_ptr->fd;

+ xfree (event_ptr);
/* Now call the procedure associated with the event. */
if ((*proc) (fd))
return -1;
@@ -522,7 +456,6 @@ static int
wait_for_event (void)
{
file_handler *file_ptr;
- gdb_event *file_event_ptr;
int num_found = 0;

/* Make sure all output is done before getting another event. */
@@ -580,8 +513,9 @@ wait_for_event (void)

if (file_ptr->ready_mask == 0)
{
- file_event_ptr = create_file_event (file_ptr->fd);
- async_queue_event (file_event_ptr);
+ gdb_event *file_event_ptr = create_file_event (file_ptr->fd);
+
+ QUEUE_enque (gdb_event_p, event_queue, file_event_ptr);
}
file_ptr->ready_mask = mask;
}
@@ -589,12 +523,22 @@ wait_for_event (void)
return 0;
}

+/* Free EVENT. */
+
+static void
+gdb_event_xfree (struct gdb_event *event)
+{
+ xfree (event);
+}
+
/* Start up the event loop. This is the entry point to the event
loop. */

void
start_event_loop (void)
{
+ event_queue = QUEUE_alloc (gdb_event_p, gdb_event_xfree);
+
/* Loop until there is nothing to do. This is the entry point to
the event loop engine. If nothing is ready at this time, wait
for something to happen (via wait_for_event), then process it.
--
1.7.7.6