File 0986-erts-Active-once-wakes-up-IO-possing-thread-unnecess.patch of Package erlang

From 488050720fb845748c75c2c3ab7f58b149f872a4 Mon Sep 17 00:00:00 2001
From: Micael Karlberg <bmk@erlang.org>
Date: Thu, 9 Jul 2020 22:42:57 +0200
Subject: [PATCH] [erts] Active-once wakes up IO possing thread unnecessarily

inet:setopts([{active,once}]) wakes up IO polling thread unnecessarily,
leading to lock contention and visibly higher CPU utilization.

OTP-16847 (ERL-1301)
---
 erts/emulator/drivers/common/inet_drv.c | 28 +++++++++++++++++--------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 2ef452fa01..4facb11721 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -6841,26 +6841,34 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len)
 
     if ( ((desc->stype == SOCK_STREAM) && IS_CONNECTED(desc)) ||
 	((desc->stype == SOCK_DGRAM) && IS_OPEN(desc))) {
+        int trigger_recv;
+
+        /* XXX: UDP sockets could also trigger immediate read here NIY */
+        trigger_recv =
+            (desc->stype==SOCK_STREAM) &&
+            !old_active &&
+            (desc->active == INET_ONCE || desc->active == INET_MULTI) &&
+            (desc->htype == old_htype);
+
+        if (trigger_recv) {
+            return 2;
+        }
 
 	if (desc->active != old_active) {
             /* Need to cancel the read_packet timer if we go from active to passive. */
             if (desc->active == INET_PASSIVE && desc->stype == SOCK_DGRAM)
                 driver_cancel_timer(desc->port);
-	    sock_select(desc, (FD_READ|FD_CLOSE), (desc->active>0));
+
+            sock_select(desc, (FD_READ|FD_CLOSE), (desc->active>0));
         }
 
 	/* XXX: UDP sockets could also trigger immediate read here NIY */
 	if ((desc->stype==SOCK_STREAM) && desc->active) {
 	    if (!old_active || (desc->htype != old_htype)) {
 		/* passive => active change OR header type change in active mode */
-		/* Return > 1 if only active changed to INET_ONCE -> direct read if
-		   header type is unchanged. */
-		/* XXX fprintf(stderr,"desc->htype == %d, old_htype == %d, 
-		   desc->active == %d, old_active == %d\r\n",(int)desc->htype, 
-		   (int) old_htype, (int) desc->active, (int) old_active );*/
-		return 1+(desc->htype == old_htype &&
-                          (desc->active == INET_ONCE || desc->active == INET_MULTI));
+		return 1;
 	    }
+
 	    return 0;
 	}
     }
@@ -9309,7 +9317,9 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf,
 	     * Same as above, but active changed to once w/o header type
 	     * change, so try a read instead of just deliver. 
 	     */
-	    tcp_recv((tcp_descriptor *) desc, 0);
+            if ((tcp_recv((tcp_descriptor *) desc, 0) >= 0) && desc->active) {
+                sock_select(desc, (FD_READ|FD_CLOSE), 1);
+            }
 	    return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize);
 	}
     }
-- 
2.26.2

openSUSE Build Service is sponsored by