REORG: time/activity: move activity measurements to activity.{c,h}
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.
This commit is contained in:
parent
17306b905e
commit
609aad9e73
2
Makefile
2
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 \
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
69
include/proto/activity.h
Normal file
69
include/proto/activity.h
Normal file
@ -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:
|
||||
*/
|
@ -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 */
|
||||
|
||||
|
63
include/types/activity.h
Normal file
63
include/types/activity.h
Normal file
@ -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:
|
||||
*/
|
@ -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 */
|
||||
|
31
src/activity.c
Normal file
31
src/activity.c
Normal file
@ -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);
|
||||
}
|
@ -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>
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
@ -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>
|
||||
|
12
src/time.c
12
src/time.c
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user