Module: sip-router Branch: sr_3.0 Commit: 71d2f90e262a139f6beed666d2b9ac1f127274b4 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=71d2f90e...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@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; } }