]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
REORG: time/activity: move activity measurements to activity.{c,h}
authorWilly Tarreau <w@1wt.eu>
Thu, 22 Nov 2018 07:31:09 +0000 (08:31 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 22 Nov 2018 10:48:41 +0000 (11:48 +0100)
At the moment the situation with activity measurement is quite tricky
because the struct activity is defined in global.h and declared in
haproxy.c, with operations made in time.h and relying on freq_ctr
which are defined in freq_ctr.h which itself includes time.h. It's
barely possible to touch any of these files without breaking all the
circular dependency.

Let's move all this stuff to activity.{c,h} and be done with it. The
measurement of active and stolen time is now done in a dedicated
function called just after tv_before_poll() instead of mixing the two,
which used to be a lazy (but convenient) decision.

No code was changed, stuff was just moved around.

15 files changed:
Makefile
include/common/time.h
include/proto/activity.h [new file with mode: 0644]
include/proto/fd.h
include/types/activity.h [new file with mode: 0644]
include/types/global.h
src/activity.c [new file with mode: 0644]
src/cli.c
src/ev_epoll.c
src/ev_kqueue.c
src/ev_poll.c
src/ev_select.c
src/haproxy.c
src/stream.c
src/time.c

index a5269db0b24ff692a7db0ca1552b50034fdf1679..73f7dd40a2ff84b930ad5966b4f3ff29be9ed5ba 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -943,7 +943,7 @@ OBJS = src/proto_http.o src/cfgparse-listen.o src/proto_htx.o src/stream.o    \
        src/http.o src/hpack-dec.o src/action.o src/proto_udp.o src/http_acl.o \
        src/xxhash.o src/hpack-enc.o src/h2.o src/freq_ctr.o src/lru.o         \
        src/protocol.o src/arg.o src/hpack-huff.o src/hdr_idx.o src/base64.o   \
-       src/hash.o src/mailers.o
+       src/hash.o src/mailers.o src/activity.o
 
 EBTREE_OBJS = $(EBTREE_DIR)/ebtree.o $(EBTREE_DIR)/eb32sctree.o \
               $(EBTREE_DIR)/eb32tree.o $(EBTREE_DIR)/eb64tree.o \
index a1664b491f64ab679eca0612c1a1d21d735a9175..b9efd714b9b8ffbefc3076380fca3da4ac284996 100644 (file)
@@ -85,11 +85,6 @@ REGPRM2 int tv_ms_cmp(const struct timeval *tv1, const struct timeval *tv2);
  */
 REGPRM2 int tv_ms_cmp2(const struct timeval *tv1, const struct timeval *tv2);
 
-/* Updates the current thread's statistics about stolen CPU time. The unit for
- * <stolen> is half-milliseconds.
- */
-REGPRM1 void report_stolen_time(uint64_t stolen);
-
 /**** general purpose functions and macros *******************************/
 
 
@@ -581,26 +576,6 @@ static inline void measure_idle()
  */
 static inline void tv_entering_poll()
 {
-       uint64_t new_mono_time;
-       uint64_t new_cpu_time;
-       int64_t stolen;
-
-       new_cpu_time   = now_cpu_time();
-       new_mono_time  = now_mono_time();
-
-       if (prev_cpu_time && prev_mono_time) {
-               new_cpu_time  -= prev_cpu_time;
-               new_mono_time -= prev_mono_time;
-               stolen = new_mono_time - new_cpu_time;
-               if (stolen >= 500000) {
-                       stolen /= 500000;
-                       /* more than half a millisecond difference might
-                        * indicate an undesired preemption.
-                        */
-                       report_stolen_time(stolen);
-               }
-       }
-
        gettimeofday(&before_poll, NULL);
 }
 
diff --git a/include/proto/activity.h b/include/proto/activity.h
new file mode 100644 (file)
index 0000000..4cf9c8d
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * include/proto/activity.h
+ * This file contains macros and inline functions for activity measurements.
+ *
+ * Copyright (C) 2000-2018 Willy Tarreau - w@1wt.eu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, version 2.1
+ * exclusively.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _PROTO_ACTIVITY_H
+#define _PROTO_ACTIVITY_H
+
+#include <common/config.h>
+#include <common/hathreads.h>
+#include <common/time.h>
+#include <types/activity.h>
+
+extern struct activity activity[MAX_THREADS];
+
+
+void report_stolen_time(uint64_t stolen);
+
+/* Collect date and time information before calling poll(). This will be used
+ * to count the run time of the past loop and the sleep time of the next poll.
+ */
+static inline void activity_count_runtime()
+{
+       uint64_t new_mono_time;
+       uint64_t new_cpu_time;
+       int64_t stolen;
+
+       new_cpu_time   = now_cpu_time();
+       new_mono_time  = now_mono_time();
+
+       if (prev_cpu_time && prev_mono_time) {
+               new_cpu_time  -= prev_cpu_time;
+               new_mono_time -= prev_mono_time;
+               stolen = new_mono_time - new_cpu_time;
+               if (unlikely(stolen >= 500000)) {
+                       stolen /= 500000;
+                       /* more than half a millisecond difference might
+                        * indicate an undesired preemption.
+                        */
+                       report_stolen_time(stolen);
+               }
+       }
+}
+
+
+#endif /* _PROTO_ACTIVITY_H */
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ * End:
+ */
index 03e318284e9bbed071a70adeccbb622940868c09..81aea87bc8f0db2a0cb6ec5ccc05f80461bdcde1 100644 (file)
@@ -30,9 +30,8 @@
 #include <common/config.h>
 #include <common/ticks.h>
 #include <common/time.h>
-
 #include <types/fd.h>
-#include <types/global.h>
+#include <proto/activity.h>
 
 /* public variables */
 
diff --git a/include/types/activity.h b/include/types/activity.h
new file mode 100644 (file)
index 0000000..99922b4
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * include/types/activity.h
+ * This file contains structure declarations for activity measurements.
+ *
+ * Copyright (C) 2000-2018 Willy Tarreau - w@1wt.eu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, version 2.1
+ * exclusively.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TYPES_ACTIVITY_H
+#define _TYPES_ACTIVITY_H
+
+#include <common/config.h>
+#include <types/freq_ctr.h>
+
+/* per-thread activity reports. It's important that it's aligned on cache lines
+ * because some elements will be updated very often. Most counters are OK on
+ * 32-bit since this will be used during debugging sessions for troubleshooting
+ * in iterative mode.
+ */
+struct activity {
+       unsigned int loops;        // complete loops in run_poll_loop()
+       unsigned int wake_cache;   // active fd_cache prevented poll() from sleeping
+       unsigned int wake_tasks;   // active tasks prevented poll() from sleeping
+       unsigned int wake_signal;  // pending signal prevented poll() from sleeping
+       unsigned int poll_exp;     // number of times poll() sees an expired timeout (includes wake_*)
+       unsigned int poll_drop;    // poller dropped a dead FD from the update list
+       unsigned int poll_dead;    // poller woke up with a dead FD
+       unsigned int poll_skip;    // poller skipped another thread's FD
+       unsigned int fd_skip;      // fd cache skipped another thread's FD
+       unsigned int fd_lock;      // fd cache skipped a locked FD
+       unsigned int fd_del;       // fd cache detected a deleted FD
+       unsigned int conn_dead;    // conn_fd_handler woke up on an FD indicating a dead connection
+       unsigned int stream;       // calls to process_stream()
+       unsigned int empty_rq;     // calls to process_runnable_tasks() with nothing for the thread
+       unsigned int long_rq;      // process_runnable_tasks() left with tasks in the run queue
+       unsigned int cpust_total;  // sum of half-ms stolen per thread
+       struct freq_ctr cpust_1s;  // avg amount of half-ms stolen over last second
+       struct freq_ctr_period cpust_15s; // avg amount of half-ms stolen over last 15s
+       char __pad[0]; // unused except to check remaining room
+       char __end[0] __attribute__((aligned(64))); // align size to 64.
+};
+
+#endif /* _TYPES_ACTIVITY_H */
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ * End:
+ */
index 7c6f9542013d1b7515f6d83b06af4f19a8cdf2ee..5a3f338a44cb3ee02e5638a13aae09f09eb4471b 100644 (file)
@@ -28,7 +28,6 @@
 #include <common/standard.h>
 #include <common/hathreads.h>
 
-#include <types/freq_ctr.h>
 #include <types/listener.h>
 #include <types/proxy.h>
 #include <types/task.h>
@@ -177,34 +176,6 @@ struct global {
 #endif
 };
 
-/* per-thread activity reports. It's important that it's aligned on cache lines
- * because some elements will be updated very often. Most counters are OK on
- * 32-bit since this will be used during debugging sessions for troubleshooting
- * in iterative mode.
- */
-struct activity {
-       unsigned int loops;        // complete loops in run_poll_loop()
-       unsigned int wake_cache;   // active fd_cache prevented poll() from sleeping
-       unsigned int wake_tasks;   // active tasks prevented poll() from sleeping
-       unsigned int wake_signal;  // pending signal prevented poll() from sleeping
-       unsigned int poll_exp;     // number of times poll() sees an expired timeout (includes wake_*)
-       unsigned int poll_drop;    // poller dropped a dead FD from the update list
-       unsigned int poll_dead;    // poller woke up with a dead FD
-       unsigned int poll_skip;    // poller skipped another thread's FD
-       unsigned int fd_skip;      // fd cache skipped another thread's FD
-       unsigned int fd_lock;      // fd cache skipped a locked FD
-       unsigned int fd_del;       // fd cache detected a deleted FD
-       unsigned int conn_dead;    // conn_fd_handler woke up on an FD indicating a dead connection
-       unsigned int stream;       // calls to process_stream()
-       unsigned int empty_rq;     // calls to process_runnable_tasks() with nothing for the thread
-       unsigned int long_rq;      // process_runnable_tasks() left with tasks in the run queue
-       unsigned int cpust_total;  // sum of half-ms stolen per thread
-       struct freq_ctr cpust_1s;  // avg amount of half-ms stolen over last second
-       struct freq_ctr_period cpust_15s; // avg amount of half-ms stolen over last 15s
-       char __pad[0]; // unused except to check remaining room
-       char __end[0] __attribute__((aligned(64))); // align size to 64.
-};
-
 /*
  * Structure used to describe the processes in master worker mode
  */
@@ -221,7 +192,6 @@ struct mworker_proc {
 };
 
 extern struct global global;
-extern struct activity activity[MAX_THREADS];
 extern int  pid;                /* current process id */
 extern int  relative_pid;       /* process id starting at 1 */
 extern unsigned long pid_bit;   /* bit corresponding to the process id */
diff --git a/src/activity.c b/src/activity.c
new file mode 100644 (file)
index 0000000..c843b47
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * activity measurement functions.
+ *
+ * Copyright 2000-2018 Willy Tarreau <w@1wt.eu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <common/config.h>
+#include <common/standard.h>
+#include <common/hathreads.h>
+#include <types/activity.h>
+#include <proto/freq_ctr.h>
+
+/* One struct per thread containing all collected measurements */
+struct activity activity[MAX_THREADS] __attribute__((aligned(64))) = { };
+
+
+/* Updates the current thread's statistics about stolen CPU time. The unit for
+ * <stolen> is half-milliseconds.
+ */
+void report_stolen_time(uint64_t stolen)
+{
+       activity[tid].cpust_total += stolen;
+       update_freq_ctr(&activity[tid].cpust_1s, stolen);
+       update_freq_ctr_period(&activity[tid].cpust_15s, 15000, stolen);
+}
index ef58ba616cd3725291dd3676a6877f2d86d2b1dc..f0bba331e89e405cf3d2cc216edf0dda1494967e 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -45,6 +45,7 @@
 #include <types/dns.h>
 #include <types/stats.h>
 
+#include <proto/activity.h>
 #include <proto/backend.h>
 #include <proto/channel.h>
 #include <proto/checks.h>
index 9d111ce6531a9200f64cd35ac495f4fe45d865f3..a9f96ab800c9e582574cc53089772280aeb55686 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <types/global.h>
 
+#include <proto/activity.h>
 #include <proto/fd.h>
 
 
@@ -147,6 +148,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
        /* now let's wait for polled events */
        wait_time = compute_poll_timeout(exp);
        tv_entering_poll();
+       activity_count_runtime();
        status = epoll_wait(epoll_fd[tid], epoll_events, global.tune.maxpollevents, wait_time);
        tv_leaving_poll(wait_time, status);
 
index c1c3e1164582f1fc6017e65b50589b8a92ce227b..dc1310cff8234153af4e386ac0b1b93f81e0293b 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <types/global.h>
 
+#include <proto/activity.h>
 #include <proto/fd.h>
 
 
@@ -135,6 +136,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
        timeout.tv_nsec = (delta_ms % 1000) * 1000000;
        fd = global.tune.maxpollevents;
        tv_entering_poll();
+       activity_count_runtime();
        status = kevent(kqueue_fd[tid], // int kq
                        NULL,      // const struct kevent *changelist
                        0,         // int nchanges
index b08274ccce7f70b496469717418c753e6041e4b8..ce5e38f96e60a4e48541af5deee850cc0e9a50a7 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <types/global.h>
 
+#include <proto/activity.h>
 #include <proto/fd.h>
 
 
@@ -195,6 +196,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
        /* now let's wait for events */
        wait_time = compute_poll_timeout(exp);
        tv_entering_poll();
+       activity_count_runtime();
        status = poll(poll_events, nbfd, wait_time);
        tv_leaving_poll(wait_time, status);
 
index 464635b0f4e52da418f4ad8945ff3f45282cae3d..f435813aaa2cb2703ebbb36ff95b0ead3e1bd731 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <types/global.h>
 
+#include <proto/activity.h>
 #include <proto/fd.h>
 
 
@@ -165,6 +166,7 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
        delta.tv_sec  = (delta_ms / 1000);
        delta.tv_usec = (delta_ms % 1000) * 1000;
        tv_entering_poll();
+       activity_count_runtime();
        status = select(maxfd,
                        readnotnull ? tmp_evts[DIR_RD] : NULL,
                        writenotnull ? tmp_evts[DIR_WR] : NULL,
index 79de01b0618922e8c0d352b0dc33fcf1e86cd59d..b8337b313512fbc7f02b9f0198cbd2ca7dbe0c65 100644 (file)
@@ -93,6 +93,7 @@
 #include <types/peers.h>
 
 #include <proto/acl.h>
+#include <proto/activity.h>
 #include <proto/arg.h>
 #include <proto/auth.h>
 #include <proto/backend.h>
@@ -170,8 +171,6 @@ struct global global = {
        /* others NULL OK */
 };
 
-struct activity activity[MAX_THREADS] __attribute__((aligned(64))) = { };
-
 /*********************************************************************/
 
 int stopping;  /* non zero means stopping in progress */
index 41555544cd6b9101cb7418942810df4ff9c946ba..3c84cbe6bf6e92b09dead266763806a0354078a1 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <proto/acl.h>
 #include <proto/action.h>
+#include <proto/activity.h>
 #include <proto/arg.h>
 #include <proto/backend.h>
 #include <proto/channel.h>
index b404b258147628a9f969d5e57660284bf9c8efc4..8f9b94341331a54c816d4dd0ec1d46fdabf41d05 100644 (file)
@@ -18,8 +18,6 @@
 #include <common/standard.h>
 #include <common/time.h>
 #include <common/hathreads.h>
-#include <types/global.h>
-#include <proto/freq_ctr.h>
 
 THREAD_LOCAL unsigned int   ms_left_scaled;  /* milliseconds left for current second (0..2^32-1) */
 THREAD_LOCAL unsigned int   now_ms;          /* internal date in milliseconds (may wrap) */
@@ -264,16 +262,6 @@ REGPRM2 void tv_update_date(int max_wait, int interrupted)
        return;
 }
 
-/* Updates the current thread's statistics about stolen CPU time. The unit for
- * <stolen> is half-milliseconds.
- */
-REGPRM1 void report_stolen_time(uint64_t stolen)
-{
-       activity[tid].cpust_total += stolen;
-       update_freq_ctr(&activity[tid].cpust_1s, stolen);
-       update_freq_ctr_period(&activity[tid].cpust_15s, 15000, stolen);
-}
-
 /*
  * Local variables:
  *  c-indent-level: 8