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

Reply via email to