From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24818 invoked by alias); 24 Jan 2013 01:15:10 -0000 Received: (qmail 24754 invoked by uid 22791); 24 Jan 2013 01:15:08 -0000 X-SWARE-Spam-Status: No, hits=-4.6 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 24 Jan 2013 01:14:58 +0000 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1TyBP7-00017f-BH from Yao_Qi@mentor.com for gdb-patches@sourceware.org; Wed, 23 Jan 2013 17:14:57 -0800 Received: from SVR-ORW-FEM-05.mgc.mentorg.com ([147.34.97.43]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Wed, 23 Jan 2013 17:14:56 -0800 Received: from qiyao.dyndns.org.dyndns.org.dyndns.org (147.34.91.1) by svr-orw-fem-05.mgc.mentorg.com (147.34.97.43) with Microsoft SMTP Server id 14.1.289.1; Wed, 23 Jan 2013 17:14:56 -0800 From: Yao Qi To: Subject: [PATCH 3/3] gdb: replace event_queue with QUEUE Date: Thu, 24 Jan 2013 01:15:00 -0000 Message-ID: <1358990040-10962-3-git-send-email-yao@codesourcery.com> In-Reply-To: <1358990040-10962-1-git-send-email-yao@codesourcery.com> References: <1358990040-10962-1-git-send-email-yao@codesourcery.com> MIME-Version: 1.0 Content-Type: text/plain X-IsSubscribed: yes 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 X-SW-Source: 2013-01/txt/msg00581.txt.bz2 Hi, This patch rewrites 'event_queue' with QUEUE API in common/queue.h. This patch is a little different from the GDBserver one, because the event queue is used before the event loop is started. So I add a new function init_event_queue to initialize event queue earlier. Regression tested on x86_64-linux with board file {unix, native-gdbserver} x {sync, async}. gdb: 2013-01-24 Yao Qi * event-loop.c: Include "queue.h". (gdb_event_p): New typedef. (typedef struct async_event_handler): (DECLARE_QUEUE_P): Use. (DEFINE_QUEUE_P): Use. (async_queue_event): Remove. (static int gdb_wait_for_event): (process_event): Use QUEUE macros. (event_queue): Remove. (gdb_wait_for_event): Caller update. (check_async_event_handlers): Likewise. (poll_timers): Likewise. (gdb_event_xfree): New. (init_event_queue): New. * event-loop.h: Declare it. * main.c (captured_main): Call init_event_queue. --- gdb/event-loop.c | 122 ++++++++++++++++------------------------------------- gdb/event-loop.h | 1 + gdb/main.c | 4 ++ 3 files changed, 42 insertions(+), 85 deletions(-) diff --git a/gdb/event-loop.c b/gdb/event-loop.c index aea3b5e..05a4598 100644 --- a/gdb/event-loop.c +++ b/gdb/event-loop.c @@ -20,6 +20,7 @@ #include "defs.h" #include "event-loop.h" #include "event-top.h" +#include "queue.h" #ifdef HAVE_POLL #if defined (HAVE_POLL_H) @@ -68,17 +69,14 @@ typedef void (event_handler_func) (event_data); case of async signal handlers, it is invoke_async_signal_handler. */ -struct gdb_event +typedef struct gdb_event { /* Procedure to call to service this event. */ event_handler_func *proc; /* Data to pass to the event handler. */ event_data data; - - /* 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. */ @@ -140,26 +138,9 @@ typedef struct async_event_handler } async_event_handler; - -/* Event queue: - - the first event in the queue is the head of the queue. - It will be the next to be serviced. - - the last event in the 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 - { - gdb_event *first_event; /* First pending event. */ - gdb_event *last_event; /* Last pending event. */ - } -event_queue; +DECLARE_QUEUE_P (gdb_event_p); +DEFINE_QUEUE_P (gdb_event_p); +static QUEUE(gdb_event_p) *event_queue = NULL; /* Gdb_notifier is just a list of file descriptors gdb is interested in. These are the input file descriptor, and the target file @@ -274,27 +255,6 @@ static int gdb_wait_for_event (int); static void poll_timers (void); -/* 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 inserted at the head of the queue will be processed - as last in first out. Event appended at the tail of the queue - 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; -} - /* Create a generic event, to be enqueued in the event queue for processing. PROC is the procedure associated to the event. DATA is passed to PROC upon PROC invocation. */ @@ -336,10 +296,6 @@ create_file_event (int fd) static int process_event (void) { - gdb_event *event_ptr, *prev_ptr; - event_handler_func *proc; - event_data data; - /* First let's see if there are any asynchronous event handlers that are ready. These would be the result of invoking any of the signal handlers. */ @@ -350,46 +306,28 @@ process_event (void) /* 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) + if (QUEUE_is_empty (gdb_event_p, event_queue)) + /* This is the case if there are no event on the event queue. */ + return 0; + else { - /* Call the handler for the event. */ - - proc = event_ptr->proc; - data = event_ptr->data; - /* Let's get rid of the event from the event queue. We need to - do this now because while processing the event, the proc - function could end up calling 'error' and therefore jump out - to the caller of this function, gdb_do_one_event. In that - case, we would have on the event queue an event wich 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; + do this now because while processing the event, the proc + function could end up calling 'error' and therefore jump out + to the caller of this function, gdb_do_one_event. In that + case, we would have on the event queue an event wich has been + processed, but not deleted. */ + gdb_event *event_ptr = QUEUE_deque (gdb_event_p, event_queue); + /* Call the handler for the event. */ + event_handler_func *proc = event_ptr->proc; + event_data data = event_ptr->data; - prev_ptr->next_event = event_ptr->next_event; - if (event_ptr->next_event == NULL) - event_queue.last_event = prev_ptr; - } xfree (event_ptr); /* Now call the procedure associated with the event. */ (*proc) (data); return 1; } - - /* This is the case if there are no event on the event queue. */ - return 0; } /* Process one high level event. If nothing is ready at this time, @@ -456,6 +394,20 @@ gdb_do_one_event (void) return 1; } +/* Free EVENT. */ + +static void +gdb_event_xfree (struct gdb_event *event) +{ + xfree (event); +} + +void +init_event_queue (void) +{ + event_queue = QUEUE_alloc (gdb_event_p, gdb_event_xfree); +} + /* Start up the event loop. This is the entry point to the event loop from the command loop. */ @@ -922,7 +874,7 @@ gdb_wait_for_event (int block) if (file_ptr->ready_mask == 0) { file_event_ptr = create_file_event (file_ptr->fd); - async_queue_event (file_event_ptr); + QUEUE_enque (gdb_event_p, event_queue, file_event_ptr); } file_ptr->ready_mask = (gdb_notifier.poll_fds + i)->revents; } @@ -958,7 +910,7 @@ gdb_wait_for_event (int block) if (file_ptr->ready_mask == 0) { file_event_ptr = create_file_event (file_ptr->fd); - async_queue_event (file_event_ptr); + QUEUE_enque (gdb_event_p, event_queue, file_event_ptr); } file_ptr->ready_mask = mask; } @@ -1144,7 +1096,7 @@ check_async_event_handlers (void) data.ptr = hdata; event_ptr = create_event (invoke_async_event_handler, data); - async_queue_event (event_ptr); + QUEUE_enque (gdb_event_p, event_queue, event_ptr); } } } @@ -1351,7 +1303,7 @@ poll_timers (void) event_ptr = (gdb_event *) xmalloc (sizeof (gdb_event)); event_ptr->proc = handle_timer_event; event_ptr->data.integer = timer_list.first_timer->timer_id; - async_queue_event (event_ptr); + QUEUE_enque (gdb_event_p, event_queue, event_ptr); } /* Now we need to update the timeout for select/ poll, because diff --git a/gdb/event-loop.h b/gdb/event-loop.h index fc95cf1..fd7efc0 100644 --- a/gdb/event-loop.h +++ b/gdb/event-loop.h @@ -77,6 +77,7 @@ typedef void (timer_handler_func) (gdb_client_data); /* Exported functions from event-loop.c */ +extern void init_event_queue (void); extern void start_event_loop (void); extern int gdb_do_one_event (void); extern void delete_file_handler (int fd); diff --git a/gdb/main.c b/gdb/main.c index 6ed014f..689b2d8 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -997,6 +997,10 @@ captured_main (void *data) ALL_OBJFILES (objfile) load_auto_scripts_for_objfile (objfile); + /* Initialize event queue here because execution commands below + will push events to the queue. */ + init_event_queue (); + /* Process '-x' and '-ex' options. */ for (i = 0; VEC_iterate (cmdarg_s, cmdarg_vec, i, cmdarg_p); i++) switch (cmdarg_p->type) -- 1.7.7.6