Hi All,
Rather than using malloc'ed list entries in the mail loop, use a single linked
in-place list.
This avoid lots of mallocs and frees as the main loop iterates.
thanks,
Mike
>From cd148e46e37f11b603df89faa5e0d86f7382ac9a Mon Sep 17 00:00:00 2001
From: Mike McCormack <mj.mccorm...@samsung.com>
Date: Thu, 2 Dec 2010 14:58:50 +0900
Subject: [PATCH] Convert fd_handlers_to_call to a singly linked list
---
trunk/ecore/src/lib/ecore/ecore_main.c | 120 +++++++++++++++++---------------
1 files changed, 65 insertions(+), 55 deletions(-)
diff --git a/trunk/ecore/src/lib/ecore/ecore_main.c b/trunk/ecore/src/lib/ecore/ecore_main.c
index d6de0c7..0902146 100644
--- a/trunk/ecore/src/lib/ecore/ecore_main.c
+++ b/trunk/ecore/src/lib/ecore/ecore_main.c
@@ -61,6 +61,7 @@ struct _Ecore_Fd_Handler
{
EINA_INLIST;
ECORE_MAGIC;
+ Ecore_Fd_Handler *next_ready;
int fd;
Ecore_Fd_Handler_Flags flags;
Ecore_Fd_Cb func;
@@ -119,9 +120,9 @@ static Eina_List *fd_handlers_with_prep = NULL;
static Eina_List *fd_handlers_with_buffer = NULL;
static Eina_List *fd_handlers_to_delete = NULL;
-static Eina_List *fd_handlers_to_call = NULL;
-static Eina_List *fd_handlers_to_call_current;
-static Eina_List *fd_handlers_to_call_current_next;
+/* single linked list of ready fdhs, terminated by loop to self */
+static Ecore_Fd_Handler *fd_handlers_to_call;
+static Ecore_Fd_Handler *fd_handlers_to_call_current;
#ifdef _WIN32
static Ecore_Win32_Handler *win32_handlers = NULL;
@@ -154,6 +155,24 @@ static gboolean ecore_idling;
static gboolean ecore_fds_ready;
#endif
+static inline void
+_ecore_try_add_to_call_list(Ecore_Fd_Handler *fdh)
+{
+ /* check if this fdh is already in the list */
+ if (fdh->next_ready)
+ return;
+ if (fdh->read_active || fdh->write_active || fdh->error_active)
+ {
+ /*
+ * make sure next_ready is non-null by pointing to ourselves
+ * use that to indicate this fdh is in the ready list
+ * insert at the head of the list to avoid trouble
+ */
+ fdh->next_ready = fd_handlers_to_call ? fd_handlers_to_call : fdh;
+ fd_handlers_to_call = fdh;
+ }
+}
+
#ifdef HAVE_EPOLL
static inline int
_ecore_get_epoll_fd(void)
@@ -320,8 +339,7 @@ static inline int _ecore_main_fdh_poll_mark_active(void)
for (i = 0; i < ret; i++)
{
Ecore_Fd_Handler *fdh;
- Eina_Bool pst, st;
-
+
fdh = ev[i].data.ptr;
if (!ECORE_MAGIC_CHECK(fdh, ECORE_MAGIC_FD_HANDLER))
{
@@ -334,15 +352,15 @@ static inline int _ecore_main_fdh_poll_mark_active(void)
ERR("deleted fd in epoll");
continue;
}
- pst = st = fdh->read_active | fdh->write_active | fdh->error_active;
- if ((ev[i].events & EPOLLIN) && (!fdh->read_active))
- st = fdh->read_active = EINA_TRUE;
- if ((ev[i].events & EPOLLOUT) && (!fdh->write_active))
- st = fdh->write_active = EINA_TRUE;
- if ((ev[i].events & EPOLLERR) && (!fdh->error_active))
- st = fdh->error_active = EINA_TRUE;
- if (pst != st)
- fd_handlers_to_call = eina_list_append(fd_handlers_to_call, fdh);
+
+ if (ev[i].events & EPOLLIN)
+ fdh->read_active = EINA_TRUE;
+ if (ev[i].events & EPOLLOUT)
+ fdh->write_active = EINA_TRUE;
+ if (ev[i].events & EPOLLERR)
+ fdh->error_active = EINA_TRUE;
+
+ _ecore_try_add_to_call_list(fdh);
}
return ret;
@@ -353,7 +371,6 @@ static inline int _ecore_main_fdh_poll_mark_active(void)
static inline int _ecore_main_fdh_poll_mark_active(void)
{
Ecore_Fd_Handler *fdh;
- Eina_Bool pst, st;
int ret = 0;
/* call the prepare callback for all handlers */
@@ -362,15 +379,15 @@ static inline int _ecore_main_fdh_poll_mark_active(void)
if (fdh->delete_me)
continue;
- pst = st = fdh->read_active | fdh->write_active | fdh->error_active;
- if ((fdh->gfd.revents & G_IO_IN) && (!fdh->read_active))
- st = fdh->read_active = EINA_TRUE;
- if ((fdh->gfd.revents & G_IO_OUT) && (!fdh->write_active))
- st = fdh->write_active = EINA_TRUE;
- if ((fdh->gfd.revents & G_IO_ERR) && (!fdh->error_active))
- st = fdh->error_active = EINA_TRUE;
- if (pst != st)
- fd_handlers_to_call = eina_list_append(fd_handlers_to_call, fdh);
+ if (fdh->gfd.revents & G_IO_IN)
+ fdh->read_active = EINA_TRUE;
+ if (fdh->gfd.revents & G_IO_OUT)
+ fdh->write_active = EINA_TRUE;
+ if (fdh->gfd.revents & G_IO_ERR)
+ fdh->error_active = EINA_TRUE;
+
+ _ecore_try_add_to_call_list(fdh);
+
if (fdh->gfd.revents & (G_IO_IN|G_IO_OUT|G_IO_ERR)) ret++;
}
@@ -751,6 +768,7 @@ ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, Ecore_Fd_Cb func
fdh = calloc(1, sizeof(Ecore_Fd_Handler));
if (!fdh) return NULL;
ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER);
+ fdh->next_ready = NULL;
fdh->fd = fd;
fdh->flags = flags;
if (_ecore_main_fdh_poll_add(fdh) < 0)
@@ -984,9 +1002,7 @@ _ecore_main_shutdown(void)
fd_handlers_with_prep = eina_list_free(fd_handlers_with_prep);
if (fd_handlers_to_delete)
fd_handlers_to_delete = eina_list_free(fd_handlers_to_delete);
- if (fd_handlers_to_call)
- fd_handlers_to_call = eina_list_free(fd_handlers_to_call);
-
+ fd_handlers_to_call = NULL;
fd_handlers_to_call_current = NULL;
fd_handlers_to_delete = NULL;
fd_handler_current = NULL;
@@ -1124,16 +1140,13 @@ _ecore_main_select(double timeout)
{
if (!fdh->delete_me)
{
- Eina_Bool pst, st;
- pst = st = fdh->read_active | fdh->write_active | fdh->error_active;
- if ((FD_ISSET(fdh->fd, &rfds)) && (!fdh->read_active))
- st = fdh->read_active = EINA_TRUE;
- if ((FD_ISSET(fdh->fd, &wfds)) && (!fdh->write_active))
- st = fdh->write_active = EINA_TRUE;
- if ((FD_ISSET(fdh->fd, &exfds)) && (!fdh->error_active))
- st = fdh->error_active = EINA_TRUE;
- if (pst != st)
- fd_handlers_to_call = eina_list_append(fd_handlers_to_call, fdh);
+ if (FD_ISSET(fdh->fd, &rfds))
+ fdh->read_active = EINA_TRUE;
+ if (FD_ISSET(fdh->fd, &wfds))
+ fdh->write_active = EINA_TRUE;
+ if (FD_ISSET(fdh->fd, &exfds))
+ fdh->error_active = EINA_TRUE;
+ _ecore_try_add_to_call_list(fdh);
}
}
#endif /* HAVE_EPOLL */
@@ -1270,22 +1283,16 @@ _ecore_main_win32_handlers_cleanup(void)
static void
_ecore_main_fd_handlers_call(void)
{
+ /* grab a new list */
if (!fd_handlers_to_call_current)
{
- /* regular main loop, start from head */
fd_handlers_to_call_current = fd_handlers_to_call;
- fd_handlers_to_call_current_next = eina_list_next(fd_handlers_to_call_current);
- }
- else
- {
- /* recursive main loop, continue from where we were */
- fd_handlers_to_call_current = fd_handlers_to_call_current_next;
- fd_handlers_to_call_current_next = eina_list_next(fd_handlers_to_call_current);
+ fd_handlers_to_call = NULL;
}
while (fd_handlers_to_call_current)
{
- Ecore_Fd_Handler *fdh = fd_handlers_to_call_current->data;
+ Ecore_Fd_Handler *fdh = fd_handlers_to_call_current;
if (!fdh->delete_me)
{
@@ -1311,9 +1318,16 @@ _ecore_main_fd_handlers_call(void)
}
}
- fd_handlers_to_call = eina_list_remove_list(fd_handlers_to_call, fd_handlers_to_call_current);
- fd_handlers_to_call_current = fd_handlers_to_call_current_next;
- fd_handlers_to_call_current_next = eina_list_next(fd_handlers_to_call_current_next);
+ /* stop when we point to ourselves */
+ if (fdh->next_ready == fdh)
+ {
+ fdh->next_ready = NULL;
+ fd_handlers_to_call_current = NULL;
+ break;
+ }
+
+ fd_handlers_to_call_current = fdh->next_ready;
+ fdh->next_ready = NULL;
}
}
@@ -1338,12 +1352,8 @@ _ecore_main_fd_handlers_buf_call(void)
if (fdh->buf_func(fdh->buf_data, fdh))
{
ret |= fdh->func(fdh->data, fdh);
- if (!fdh->read_active)
- {
- fdh->read_active = EINA_TRUE;
- if ((!fdh->write_active) && (!fdh->error_active))
- fd_handlers_to_call = eina_list_append(fd_handlers_to_call, fdh);
- }
+ fdh->read_active = EINA_TRUE;
+ _ecore_try_add_to_call_list(fdh);
}
fdh->references--;
}
--
1.7.0.4
------------------------------------------------------------------------------
Increase Visibility of Your 3D Game App & Earn a Chance To Win $500!
Tap into the largest installed PC base & get more eyes on your game by
optimizing for Intel(R) Graphics Technology. Get started today with the
Intel(R) Software Partner Program. Five $500 cash prizes are up for grabs.
http://p.sf.net/sfu/intelisp-dev2dev
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel