forked from enlightenment/efl
From: Mike McCormack <mj.mccormack@samsung.com>
Subject: [E-devel] [PATCH] ecore main loop "fd_handlers_to_call" list optimization Date: Thu, 02 Dec 2010 15:22:13 +0900 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 SVN revision: 56368
This commit is contained in:
parent
7d8b4f6f68
commit
56b1e2dcc4
|
@ -61,6 +61,7 @@ struct _Ecore_Fd_Handler
|
||||||
{
|
{
|
||||||
EINA_INLIST;
|
EINA_INLIST;
|
||||||
ECORE_MAGIC;
|
ECORE_MAGIC;
|
||||||
|
Ecore_Fd_Handler *next_ready;
|
||||||
int fd;
|
int fd;
|
||||||
Ecore_Fd_Handler_Flags flags;
|
Ecore_Fd_Handler_Flags flags;
|
||||||
Ecore_Fd_Cb func;
|
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_with_buffer = NULL;
|
||||||
static Eina_List *fd_handlers_to_delete = NULL;
|
static Eina_List *fd_handlers_to_delete = NULL;
|
||||||
|
|
||||||
static Eina_List *fd_handlers_to_call = NULL;
|
/* single linked list of ready fdhs, terminated by loop to self */
|
||||||
static Eina_List *fd_handlers_to_call_current;
|
static Ecore_Fd_Handler *fd_handlers_to_call;
|
||||||
static Eina_List *fd_handlers_to_call_current_next;
|
static Ecore_Fd_Handler *fd_handlers_to_call_current;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static Ecore_Win32_Handler *win32_handlers = NULL;
|
static Ecore_Win32_Handler *win32_handlers = NULL;
|
||||||
|
@ -166,6 +167,24 @@ _ecore_fd_valid(void)
|
||||||
#endif
|
#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
|
#ifdef HAVE_EPOLL
|
||||||
static inline int
|
static inline int
|
||||||
_ecore_get_epoll_fd(void)
|
_ecore_get_epoll_fd(void)
|
||||||
|
@ -332,7 +351,6 @@ static inline int _ecore_main_fdh_poll_mark_active(void)
|
||||||
for (i = 0; i < ret; i++)
|
for (i = 0; i < ret; i++)
|
||||||
{
|
{
|
||||||
Ecore_Fd_Handler *fdh;
|
Ecore_Fd_Handler *fdh;
|
||||||
Eina_Bool pst, st;
|
|
||||||
|
|
||||||
fdh = ev[i].data.ptr;
|
fdh = ev[i].data.ptr;
|
||||||
if (!ECORE_MAGIC_CHECK(fdh, ECORE_MAGIC_FD_HANDLER))
|
if (!ECORE_MAGIC_CHECK(fdh, ECORE_MAGIC_FD_HANDLER))
|
||||||
|
@ -346,15 +364,15 @@ static inline int _ecore_main_fdh_poll_mark_active(void)
|
||||||
ERR("deleted fd in epoll");
|
ERR("deleted fd in epoll");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pst = st = fdh->read_active | fdh->write_active | fdh->error_active;
|
|
||||||
if ((ev[i].events & EPOLLIN) && (!fdh->read_active))
|
if (ev[i].events & EPOLLIN)
|
||||||
st = fdh->read_active = EINA_TRUE;
|
fdh->read_active = EINA_TRUE;
|
||||||
if ((ev[i].events & EPOLLOUT) && (!fdh->write_active))
|
if (ev[i].events & EPOLLOUT)
|
||||||
st = fdh->write_active = EINA_TRUE;
|
fdh->write_active = EINA_TRUE;
|
||||||
if ((ev[i].events & EPOLLERR) && (!fdh->error_active))
|
if (ev[i].events & EPOLLERR)
|
||||||
st = fdh->error_active = EINA_TRUE;
|
fdh->error_active = EINA_TRUE;
|
||||||
if (pst != st)
|
|
||||||
fd_handlers_to_call = eina_list_append(fd_handlers_to_call, fdh);
|
_ecore_try_add_to_call_list(fdh);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -365,7 +383,6 @@ static inline int _ecore_main_fdh_poll_mark_active(void)
|
||||||
static inline int _ecore_main_fdh_poll_mark_active(void)
|
static inline int _ecore_main_fdh_poll_mark_active(void)
|
||||||
{
|
{
|
||||||
Ecore_Fd_Handler *fdh;
|
Ecore_Fd_Handler *fdh;
|
||||||
Eina_Bool pst, st;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* call the prepare callback for all handlers */
|
/* call the prepare callback for all handlers */
|
||||||
|
@ -374,15 +391,15 @@ static inline int _ecore_main_fdh_poll_mark_active(void)
|
||||||
if (fdh->delete_me)
|
if (fdh->delete_me)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pst = st = fdh->read_active | fdh->write_active | fdh->error_active;
|
if (fdh->gfd.revents & G_IO_IN)
|
||||||
if ((fdh->gfd.revents & G_IO_IN) && (!fdh->read_active))
|
fdh->read_active = EINA_TRUE;
|
||||||
st = fdh->read_active = EINA_TRUE;
|
if (fdh->gfd.revents & G_IO_OUT)
|
||||||
if ((fdh->gfd.revents & G_IO_OUT) && (!fdh->write_active))
|
fdh->write_active = EINA_TRUE;
|
||||||
st = fdh->write_active = EINA_TRUE;
|
if (fdh->gfd.revents & G_IO_ERR)
|
||||||
if ((fdh->gfd.revents & G_IO_ERR) && (!fdh->error_active))
|
fdh->error_active = EINA_TRUE;
|
||||||
st = fdh->error_active = EINA_TRUE;
|
|
||||||
if (pst != st)
|
_ecore_try_add_to_call_list(fdh);
|
||||||
fd_handlers_to_call = eina_list_append(fd_handlers_to_call, fdh);
|
|
||||||
if (fdh->gfd.revents & (G_IO_IN|G_IO_OUT|G_IO_ERR)) ret++;
|
if (fdh->gfd.revents & (G_IO_IN|G_IO_OUT|G_IO_ERR)) ret++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,6 +780,7 @@ ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, Ecore_Fd_Cb func
|
||||||
fdh = calloc(1, sizeof(Ecore_Fd_Handler));
|
fdh = calloc(1, sizeof(Ecore_Fd_Handler));
|
||||||
if (!fdh) return NULL;
|
if (!fdh) return NULL;
|
||||||
ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER);
|
ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER);
|
||||||
|
fdh->next_ready = NULL;
|
||||||
fdh->fd = fd;
|
fdh->fd = fd;
|
||||||
fdh->flags = flags;
|
fdh->flags = flags;
|
||||||
if (_ecore_main_fdh_poll_add(fdh) < 0)
|
if (_ecore_main_fdh_poll_add(fdh) < 0)
|
||||||
|
@ -999,9 +1017,8 @@ _ecore_main_shutdown(void)
|
||||||
fd_handlers_with_prep = eina_list_free(fd_handlers_with_prep);
|
fd_handlers_with_prep = eina_list_free(fd_handlers_with_prep);
|
||||||
if (fd_handlers_to_delete)
|
if (fd_handlers_to_delete)
|
||||||
fd_handlers_to_delete = eina_list_free(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_call_current = NULL;
|
||||||
fd_handlers_to_delete = NULL;
|
fd_handlers_to_delete = NULL;
|
||||||
fd_handler_current = NULL;
|
fd_handler_current = NULL;
|
||||||
|
@ -1140,16 +1157,13 @@ _ecore_main_select(double timeout)
|
||||||
{
|
{
|
||||||
if (!fdh->delete_me)
|
if (!fdh->delete_me)
|
||||||
{
|
{
|
||||||
Eina_Bool pst, st;
|
if (FD_ISSET(fdh->fd, &rfds))
|
||||||
pst = st = fdh->read_active | fdh->write_active | fdh->error_active;
|
fdh->read_active = EINA_TRUE;
|
||||||
if ((FD_ISSET(fdh->fd, &rfds)) && (!fdh->read_active))
|
if (FD_ISSET(fdh->fd, &wfds))
|
||||||
st = fdh->read_active = EINA_TRUE;
|
fdh->write_active = EINA_TRUE;
|
||||||
if ((FD_ISSET(fdh->fd, &wfds)) && (!fdh->write_active))
|
if (FD_ISSET(fdh->fd, &exfds))
|
||||||
st = fdh->write_active = EINA_TRUE;
|
fdh->error_active = EINA_TRUE;
|
||||||
if ((FD_ISSET(fdh->fd, &exfds)) && (!fdh->error_active))
|
_ecore_try_add_to_call_list(fdh);
|
||||||
st = fdh->error_active = EINA_TRUE;
|
|
||||||
if (pst != st)
|
|
||||||
fd_handlers_to_call = eina_list_append(fd_handlers_to_call, fdh);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* HAVE_EPOLL */
|
#endif /* HAVE_EPOLL */
|
||||||
|
@ -1286,22 +1300,16 @@ _ecore_main_win32_handlers_cleanup(void)
|
||||||
static void
|
static void
|
||||||
_ecore_main_fd_handlers_call(void)
|
_ecore_main_fd_handlers_call(void)
|
||||||
{
|
{
|
||||||
|
/* grab a new list */
|
||||||
if (!fd_handlers_to_call_current)
|
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 = fd_handlers_to_call;
|
||||||
fd_handlers_to_call_current_next = eina_list_next(fd_handlers_to_call_current);
|
fd_handlers_to_call = NULL;
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fd_handlers_to_call_current)
|
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)
|
if (!fdh->delete_me)
|
||||||
{
|
{
|
||||||
|
@ -1328,9 +1336,16 @@ _ecore_main_fd_handlers_call(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fd_handlers_to_call = eina_list_remove_list(fd_handlers_to_call, fd_handlers_to_call_current);
|
/* stop when we point to ourselves */
|
||||||
fd_handlers_to_call_current = fd_handlers_to_call_current_next;
|
if (fdh->next_ready == fdh)
|
||||||
fd_handlers_to_call_current_next = eina_list_next(fd_handlers_to_call_current_next);
|
{
|
||||||
|
fdh->next_ready = NULL;
|
||||||
|
fd_handlers_to_call_current = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd_handlers_to_call_current = fdh->next_ready;
|
||||||
|
fdh->next_ready = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1355,12 +1370,8 @@ _ecore_main_fd_handlers_buf_call(void)
|
||||||
if (fdh->buf_func(fdh->buf_data, fdh))
|
if (fdh->buf_func(fdh->buf_data, fdh))
|
||||||
{
|
{
|
||||||
ret |= fdh->func(fdh->data, fdh);
|
ret |= fdh->func(fdh->data, fdh);
|
||||||
if (!fdh->read_active)
|
|
||||||
{
|
|
||||||
fdh->read_active = EINA_TRUE;
|
fdh->read_active = EINA_TRUE;
|
||||||
if ((!fdh->write_active) && (!fdh->error_active))
|
_ecore_try_add_to_call_list(fdh);
|
||||||
fd_handlers_to_call = eina_list_append(fd_handlers_to_call, fdh);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fdh->references--;
|
fdh->references--;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue