io_wait: kqueue: use a bigger array
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Fri, 18 Jun 2010 22:16:38 +0000 (00:16 +0200)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Fri, 18 Jun 2010 23:02:48 +0000 (01:02 +0200)
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)

io_wait.c
io_wait.h

index 0c73402..f0e01be 100644 (file)
--- a/io_wait.c
+++ b/io_wait.c
@@ -549,13 +549,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){
@@ -564,7 +572,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){
index c28f53d..e04efd8 100644 (file)
--- 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;
                        }
                }