[sr-dev] git:andrei/tcp_tls_changes: io_wait: kqueue: use a bigger array

Andrei Pelinescu-Onciul andrei at iptel.org
Sat Jun 19 17:13:29 CEST 2010


Module: sip-router
Branch: andrei/tcp_tls_changes
Commit: 99682621f360bcbd5b0def1f7498f457e25f59ab
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=99682621f360bcbd5b0def1f7498f457e25f59ab

Author: Andrei Pelinescu-Onciul <andrei at iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei at 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)

---

 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 0c73402..f0e01be 100644
--- 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){
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;
 			}
 		}




More information about the sr-dev mailing list