Improve pending checks in poll loop by ordering them by trigger frequency
authorclaudio <claudio@openbsd.org>
Wed, 18 Jan 2023 13:20:00 +0000 (13:20 +0000)
committerclaudio <claudio@openbsd.org>
Wed, 18 Jan 2023 13:20:00 +0000 (13:20 +0000)
and by making peer_imsg_pending() a true O(1) function.
OK tb@

usr.sbin/bgpd/rde.c
usr.sbin/bgpd/rde_peer.c

index 2f0fa6c..cc18625 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde.c,v 1.587 2023/01/17 16:09:01 claudio Exp $ */
+/*     $OpenBSD: rde.c,v 1.588 2023/01/18 13:20:00 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -249,8 +249,8 @@ rde_main(int debug, int verbose)
                        }
                }
 
-               if (rib_dump_pending() || rde_update_queue_pending() ||
-                   nexthop_pending() || peer_imsg_pending())
+               if (peer_imsg_pending() || rde_update_queue_pending() ||
+                   nexthop_pending() || rib_dump_pending())
                        timeout = 0;
 
                if (poll(pfd, i, timeout) == -1) {
index 310a466..eb8d6f5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde_peer.c,v 1.25 2022/09/23 15:49:20 claudio Exp $ */
+/*     $OpenBSD: rde_peer.c,v 1.26 2023/01/18 13:20:01 claudio Exp $ */
 
 /*
  * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
@@ -28,6 +28,7 @@
 
 struct peer_tree        peertable;
 struct rde_peer                *peerself;
+static long             imsg_pending;
 
 CTASSERT(sizeof(peerself->recv_eor) * 8 > AID_MAX);
 CTASSERT(sizeof(peerself->sent_eor) * 8 > AID_MAX);
@@ -610,6 +611,7 @@ peer_imsg_push(struct rde_peer *peer, struct imsg *imsg)
                fatal(NULL);
        imsg_move(&iq->imsg, imsg);
        SIMPLEQ_INSERT_TAIL(&peer->imsg_queue, iq, entry);
+       imsg_pending++;
 }
 
 /*
@@ -629,29 +631,18 @@ peer_imsg_pop(struct rde_peer *peer, struct imsg *imsg)
 
        SIMPLEQ_REMOVE_HEAD(&peer->imsg_queue, entry);
        free(iq);
+       imsg_pending--;
 
        return 1;
 }
 
-static void
-peer_imsg_queued(struct rde_peer *peer, void *arg)
-{
-       int *p = arg;
-
-       *p = *p || !SIMPLEQ_EMPTY(&peer->imsg_queue);
-}
-
 /*
  * Check if any imsg are pending, return 0 if none are pending
  */
 int
 peer_imsg_pending(void)
 {
-       int pending = 0;
-
-       peer_foreach(peer_imsg_queued, &pending);
-
-       return pending;
+       return imsg_pending != 0;
 }
 
 /*
@@ -665,5 +656,6 @@ peer_imsg_flush(struct rde_peer *peer)
        while ((iq = SIMPLEQ_FIRST(&peer->imsg_queue)) != NULL) {
                SIMPLEQ_REMOVE_HEAD(&peer->imsg_queue, entry);
                free(iq);
+               imsg_pending--;
        }
 }