
Count the number of threads busy when we try to assign work, and if everyone
is busy one yield the CPU (using sched_yield()).
Also check if work has been done, and if not yield the CPU; this is done to
avoid looping in the case where all fds are busy.


 net.c |   21 +++++++++++++++++++--
 1 files changed, 19 insertions(+), 2 deletions(-)

diff -puN net.c~everybody_busy net.c
--- cur/net.c~everybody_busy	2004-01-17 21:09:04.000000000 -0300
+++ cur-root/net.c	2004-01-17 21:09:04.000000000 -0300
@@ -128,7 +128,8 @@ int net_init(int nthreads) {
 
 /* main select loop */
 void net_select_loop(int nthreads) {
-	int i, j, rv;
+	int rv;
+	unsigned int i, j, busycount, workdone;
 	int connfd, maxfd;
 	fd_set readfds;
 	struct timeval tv;
@@ -161,6 +162,7 @@ void net_select_loop(int nthreads) {
 			goto rebuild;
 		}
 		
+		workdone = 0;
 		for (i = 3; i <= maxfd; i++) {
 			/* skip the ones not in the set or busy and lfd */
 			if (!FD_ISSET(i, &readfds) || fd_busy[i] || i == lfd)
@@ -168,6 +170,7 @@ void net_select_loop(int nthreads) {
 			
 			/* loop looking for an idle thread; see
 			 * doc/multithread */
+			busycount = 0;
 			for (j = 0; j < nthreads; j++) {
 				if (!thread_busy[j]) {
 					/* we found one, so mark it busy, tell
@@ -177,9 +180,17 @@ void net_select_loop(int nthreads) {
 					fd_busy[i] = 1;
 					fd_to_process[j] = i;
 					pthread_mutex_unlock(&thread_lock[j]);
+					workdone = 1;
 					break;
 				}
+				busycount++;
 			}
+			
+			/* if everybody is busy, yield the cpu */
+			if (unlikely(busycount == nthreads)) {
+				sched_yield();
+			}
+			
 			/* if we didn't find any idle thread to assign the
 			 * job, just loop and go back to select */
 		}
@@ -203,6 +214,12 @@ void net_select_loop(int nthreads) {
 				maxfd = connfd;
 			
 			active_fd[connfd] = 1;
+			workdone = 1;
+		}
+
+		/* if we didn't do any work, yield the cpu */
+		if (unlikely(!workdone)) {
+			sched_yield();
 		}
 		
 		/* rebuild the fd sets for select */
@@ -232,7 +249,7 @@ void *net_proc_loop(void *tno) {
 		pthread_mutex_lock(&thread_lock[tid]);
 		
 		fd = fd_to_process[tid];
-			
+		
 		cmd = net_get_cmd(fd);
 		if (cmd == NULL)
 			goto end_loop;

_
