Bugzilla bug #38599: pthreads PR_Poll optimizations. 1. Increased the
authorwtc%netscape.com
Thu, 08 Jun 2000 20:42:57 +0000
changeset 1410 a5f25c8013c65562f20f1ea8d97178cc41741915
parent 1409 1441f24706f3fc618be55b4fd6785ddcab9b7577
child 1411 0d6020abaad52fc089bd6fd0bcd890e3df2d4f70
push idunknown
push userunknown
push dateunknown
bugs38599
Bugzilla bug #38599: pthreads PR_Poll optimizations. 1. Increased the size of the stack pollfd structure array from 4 to 64. 2. Made the malloc'ed pollfd structure array a thread private data. Modified files: primpl.h, ptio.c, ptthread.c
pr/include/private/primpl.h
pr/src/pthreads/ptio.c
pr/src/pthreads/ptthread.c
--- a/pr/include/private/primpl.h
+++ b/pr/include/private/primpl.h
@@ -1487,16 +1487,22 @@ struct PRThread {
     void *sp;                       /* recorded sp for garbage collection */
     PRThread *next, *prev;          /* simple linked list of all threads */
     PRUint32 suspend;               /* used to store suspend and resume flags */
 #ifdef PT_NO_SIGTIMEDWAIT
     pthread_mutex_t suspendResumeMutex;
     pthread_cond_t suspendResumeCV;
 #endif
     PRUint32 interrupt_blocked;     /* interrupt blocked */
+    struct pollfd *syspoll_list;    /* Unix polling list used by PR_Poll */
+    PRUint32 syspoll_count;         /* number of elements in syspoll_list */
+#if defined(_PR_POLL_WITH_SELECT)
+    int *selectfd_list;             /* Unix fd's that PR_Poll selects on */
+    PRUint32 selectfd_count;        /* number of elements in selectfd_list */
+#endif
 #elif defined(_PR_BTHREADS)
     PRUint32 flags;
     _MDThread md;
     PRBool io_pending;
     PRInt32 io_fd;
     PRBool io_suspended;
 #else /* not pthreads or Be threads */
     _MDLock threadLock;             /* Lock to protect thread state variables.
--- a/pr/src/pthreads/ptio.c
+++ b/pr/src/pthreads/ptio.c
@@ -3111,33 +3111,42 @@ static PRInt32 _pr_poll_with_poll(
      */
     PRIntervalTime start, elapsed, remaining;
 
     if (pt_TestAbort()) return -1;
 
     if (0 == npds) PR_Sleep(timeout);
     else
     {
-#define STACK_POLL_DESC_COUNT 4
+#define STACK_POLL_DESC_COUNT 64
         struct pollfd stack_syspoll[STACK_POLL_DESC_COUNT];
         struct pollfd *syspoll;
         PRIntn index, msecs;
 
         if (npds <= STACK_POLL_DESC_COUNT)
         {
             syspoll = stack_syspoll;
         }
         else
         {
-            syspoll = (struct pollfd*)PR_MALLOC(npds * sizeof(struct pollfd));
-            if (NULL == syspoll)
+            PRThread *me = PR_GetCurrentThread();
+            if (npds > me->syspoll_count)
             {
-                PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
-                return -1;
+                PR_Free(me->syspoll_list);
+                me->syspoll_list =
+                    (struct pollfd*)PR_MALLOC(npds * sizeof(struct pollfd));
+                if (NULL == me->syspoll_list)
+                {
+                    me->syspoll_count = 0;
+                    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+                    return -1;
+                }
+                me->syspoll_count = npds;
             }
+            syspoll = me->syspoll_list;
         }
 
         for (index = 0; index < npds; ++index)
         {
             PRInt16 in_flags_read = 0, in_flags_write = 0;
             PRInt16 out_flags_read = 0, out_flags_write = 0;
 
             if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))
@@ -3326,19 +3335,16 @@ retry:
                             if (syspoll[index].revents & POLLHUP)
                                 out_flags |= PR_POLL_HUP;
                         }
                     }
                     pds[index].out_flags = out_flags;
                 }
             }
         }
-
-        if (syspoll != stack_syspoll)
-            PR_DELETE(syspoll);
     }
     return ready;
 
 } /* _pr_poll_with_poll */
 
 #if defined(_PR_POLL_WITH_SELECT)
 /*
  * OSF1 and HPUX report the POLLHUP event for a socket when the
@@ -3357,35 +3363,43 @@ static PRInt32 _pr_poll_with_select(
      */
     PRIntervalTime start, elapsed, remaining;
 
     if (pt_TestAbort()) return -1;
 
     if (0 == npds) PR_Sleep(timeout);
     else
     {
-#define STACK_POLL_DESC_COUNT 4
-        int stack_syspollfd[STACK_POLL_DESC_COUNT];
-        int *syspollfd;
+#define STACK_POLL_DESC_COUNT 64
+        int stack_selectfd[STACK_POLL_DESC_COUNT];
+        int *selectfd;
 		fd_set rd, wr, ex, *rdp = NULL, *wrp = NULL, *exp = NULL;
 		struct timeval tv, *tvp;
         PRIntn index, msecs, maxfd = 0;
 
         if (npds <= STACK_POLL_DESC_COUNT)
         {
-            syspollfd = stack_syspollfd;
+            selectfd = stack_selectfd;
         }
         else
         {
-            syspollfd = (int *)PR_MALLOC(npds * sizeof(int));
-            if (NULL == syspollfd)
+            PRThread *me = PR_GetCurrentThread();
+            if (npds > me->selectfd_count)
             {
-                PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
-                return -1;
+                PR_Free(me->selectfd_list);
+                me->selectfd_list = (int *)PR_MALLOC(npds * sizeof(int));
+                if (NULL == me->selectfd_list)
+                {
+                    me->selectfd_count = 0;
+                    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+                    return -1;
+                }
+                me->selectfd_count = npds;
             }
+            selectfd = me->selectfd_list;
         }
 		FD_ZERO(&rd);
 		FD_ZERO(&wr);
 		FD_ZERO(&ex);
 
         for (index = 0; index < npds; ++index)
         {
             PRInt16 in_flags_read = 0, in_flags_write = 0;
@@ -3435,17 +3449,17 @@ static PRInt32 _pr_poll_with_select(
                         pds[index].fd, PR_NSPR_IO_LAYER);
                     PR_ASSERT(NULL != bottom);  /* what to do about that? */
                     pds[index].out_flags = 0;  /* pre-condition */
                     if ((NULL != bottom)
                     && (_PR_FILEDESC_OPEN == bottom->secret->state))
                     {
                         if (0 == ready)
                         {
-                            syspollfd[index] = bottom->secret->md.osfd;
+                            selectfd[index] = bottom->secret->md.osfd;
                             if (in_flags_read & PR_POLL_READ)
                             {
                                 pds[index].out_flags |=
                                     _PR_POLL_READ_SYS_READ;
 								FD_SET(bottom->secret->md.osfd, &rd);
 								rdp = &rd;
                             }
                             if (in_flags_read & PR_POLL_WRITE)
@@ -3468,20 +3482,20 @@ static PRInt32 _pr_poll_with_select(
                                     _PR_POLL_WRITE_SYS_WRITE;
 								FD_SET(bottom->secret->md.osfd, &wr);
 								wrp = &wr;
                             }
                             if (pds[index].in_flags & PR_POLL_EXCEPT) {
 								FD_SET(bottom->secret->md.osfd, &ex);
 								exp = &ex;
 							}
-							if ((syspollfd[index] > maxfd) &&
+							if ((selectfd[index] > maxfd) &&
 									(pds[index].out_flags ||
 									(pds[index].in_flags & PR_POLL_EXCEPT)))
-								maxfd = syspollfd[index];
+								maxfd = selectfd[index];
                         }
                     }
                     else
                     {
                         if (0 == ready)
                         {
                             int i;
                             for (i = 0; i < index; i++)
@@ -3492,23 +3506,22 @@ static PRInt32 _pr_poll_with_select(
                         ready += 1;  /* this will cause an abrupt return */
                         pds[index].out_flags = PR_POLL_NVAL;  /* bogii */
                     }
                 }
             }
         }
         if (0 == ready)
         {
-			if ((maxfd + 1) > FD_SETSIZE) {
+			if ((maxfd + 1) > FD_SETSIZE)
+			{
 				/*
 				 * maxfd too large to be used with select, fall back to
 				 * calling poll
 				 */
-				if (syspollfd != stack_syspollfd)
-					PR_DELETE(syspollfd);
 				return(_pr_poll_with_poll(pds, npds, timeout));
 			}
             switch (timeout)
             {
             case PR_INTERVAL_NO_WAIT:
 				tv.tv_sec = 0;
 				tv.tv_usec = 0;
 				tvp = &tv;
@@ -3557,69 +3570,66 @@ retry:
 					/* find all the bad fds */
 					ready = 0;
                 	for (index = 0; index < npds; ++index)
 					{
                     	pds[index].out_flags = 0;
             			if ((NULL != pds[index].fd) &&
 											(0 != pds[index].in_flags))
 						{
-							if (fcntl(syspollfd[index], F_GETFL, 0) == -1)
+							if (fcntl(selectfd[index], F_GETFL, 0) == -1)
 							{
                     			pds[index].out_flags = PR_POLL_NVAL;
 								ready++;
 							}
 						}
 					}
                 } else 
                     _PR_MD_MAP_SELECT_ERROR(oserror);
             }
             else if (ready > 0)
             {
                 for (index = 0; index < npds; ++index)
                 {
                     PRInt16 out_flags = 0;
                     if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))
                     {
-						if (FD_ISSET(syspollfd[index], &rd))
+						if (FD_ISSET(selectfd[index], &rd))
 						{
 							if (pds[index].out_flags
 							& _PR_POLL_READ_SYS_READ)
 							{
 								out_flags |= PR_POLL_READ;
 							}
 							if (pds[index].out_flags
 							& _PR_POLL_WRITE_SYS_READ)
 							{
 								out_flags |= PR_POLL_WRITE;
 							}
 						}
-						if (FD_ISSET(syspollfd[index], &wr))
+						if (FD_ISSET(selectfd[index], &wr))
 						{
 							if (pds[index].out_flags
 							& _PR_POLL_READ_SYS_WRITE)
 							{
 								out_flags |= PR_POLL_READ;
 							}
 							if (pds[index].out_flags
 							& _PR_POLL_WRITE_SYS_WRITE)
 							{
 								out_flags |= PR_POLL_WRITE;
 							}
 						}
-						if (FD_ISSET(syspollfd[index], &ex))
+						if (FD_ISSET(selectfd[index], &ex))
 							out_flags |= PR_POLL_EXCEPT;
                     }
                     pds[index].out_flags = out_flags;
                 }
             }
         }
-
-        if (syspollfd != stack_syspollfd)
-            PR_DELETE(syspollfd);
     }
     return ready;
 
 } /* _pr_poll_with_select */
 #endif	/* _PR_POLL_WITH_SELECT */
 
 PR_IMPLEMENT(PRInt32) PR_Poll(
     PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
--- a/pr/src/pthreads/ptthread.c
+++ b/pr/src/pthreads/ptthread.c
@@ -737,16 +737,22 @@ static void _pt_thread_death(void *arg)
             thred->next->prev = thred->prev;
         PR_Unlock(pt_book.ml);
     }
     _PR_DestroyThreadPrivate(thred);
     PR_Free(thred->privateData);
     if (NULL != thred->errorString)
         PR_Free(thred->errorString);
     PR_Free(thred->stack);
+    if (NULL != thred->syspoll_list);
+        PR_Free(thred->syspoll_list);
+#if defined(_PR_POLL_WITH_SELECT)
+    if (NULL != thred->selectfd_list)
+        PR_Free(thred->selectfd_list);
+#endif
 #if defined(DEBUG)
     memset(thred, 0xaf, sizeof(PRThread));
 #endif /* defined(DEBUG) */
     PR_Free(thred);
 }  /* _pt_thread_death */
 
 void _PR_InitThreads(
     PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs)