Module: sip-router
Branch: sr_3.0
Commit: 71d2f90e262a139f6beed666d2b9ac1f127274b4
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=71d2f90…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Sat Jun 19 00:16:38 2010 +0200
io_wait: kqueue: use a bigger array
Use a bigger array for kevent(). Instead of the fd number, use
2* max_fd_no (2 because read and write events are not merged) and
with extra space for possible changelist errors.
(minor optimization)
(cherry picked from commit a9cdfc2938ca73d6ba40f5896c6a8930c2e73f85)
---
io_wait.c | 15 ++++++++++++---
io_wait.h | 9 ++++++---
2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/io_wait.c b/io_wait.c
index 5adb8d2..1b29813 100644
--- a/io_wait.c
+++ b/io_wait.c
@@ -542,13 +542,21 @@ int init_io_wait(io_wait_h* h, int max_fd, enum poll_types
poll_method)
#endif
#ifdef HAVE_KQUEUE
case POLL_KQUEUE:
- h->kq_array=local_malloc(sizeof(*(h->kq_array))*h->max_fd_no);
+ h->kq_changes_size=KQ_CHANGES_ARRAY_SIZE;
+ /* kevent returns different events for read & write
+ => to get all the possible events in one call we
+ need twice the number of added fds + space
+ for possible changelist errors.
+ OTOH if memory is to be saved at all costs, one can
+ decrease the array size.
+ */
+ h->kq_array_size=2 * h->max_fd_no + h->kq_changes_size;
+ h->kq_array=local_malloc(sizeof(*(h->kq_array))*h->kq_array_size);
if (h->kq_array==0){
LOG(L_CRIT, "ERROR: init_io_wait: could not alloc"
" kqueue event array\n");
goto error;
}
- h->kq_changes_size=KQ_CHANGES_ARRAY_SIZE;
h->kq_changes=local_malloc(sizeof(*(h->kq_changes))*
h->kq_changes_size);
if (h->kq_changes==0){
@@ -557,7 +565,8 @@ int init_io_wait(io_wait_h* h, int max_fd, enum poll_types
poll_method)
goto error;
}
h->kq_nchanges=0;
- memset((void*)h->kq_array, 0, sizeof(*(h->kq_array))*h->max_fd_no);
+ memset((void*)h->kq_array, 0,
+ sizeof(*(h->kq_array))*h->kq_array_size);
memset((void*)h->kq_changes, 0,
sizeof(*(h->kq_changes))* h->kq_changes_size);
if (init_kqueue(h)<0){
diff --git a/io_wait.h b/io_wait.h
index c28f53d..e04efd8 100644
--- a/io_wait.h
+++ b/io_wait.h
@@ -148,7 +148,9 @@ struct io_wait_handler{
int flags;
struct fd_map* fd_hash;
int fd_no; /* current index used in fd_array and the passed size for
- ep_array & kq_array*/
+ ep_array (for kq_array at least
+ max(twice the size, kq_changes_size) should be
+ be passed). */
int max_fd_no; /* maximum fd no, is also the size of fd_array,
fd_hash and ep_array*/
/* common stuff for POLL, SIGIO_RT and SELECT
@@ -170,6 +172,7 @@ struct io_wait_handler{
struct kevent* kq_array; /* used for the eventlist*/
struct kevent* kq_changes; /* used for the changelist */
size_t kq_nchanges;
+ size_t kq_array_size; /* array size */
size_t kq_changes_size; /* size of the changes array */
#endif
#ifdef HAVE_DEVPOLL
@@ -1115,7 +1118,7 @@ inline static int io_wait_loop_kqueue(io_wait_h* h, int t, int
repeat)
do {
again:
n=kevent(h->kq_fd, h->kq_changes, apply_changes, h->kq_array,
- h->fd_no, &tspec);
+ h->kq_array_size, &tspec);
if (unlikely(n==-1)){
if (unlikely(errno==EINTR)) goto again; /* signal, ignore it */
else {
@@ -1127,7 +1130,7 @@ again:
/* some of the FDs in kq_changes are bad (already closed)
and there is not enough space in kq_array to return all
of them back */
- apply_changes = h->fd_no;
+ apply_changes = h->kq_array_size;
goto again;
}
}