blob: 42569f203e14c158762008383d0a15369dc49973 [file] [log] [blame]
Willy Tarreau609aad92018-11-22 08:31:09 +01001/*
Willy Tarreaua04ded52020-06-02 10:29:48 +02002 * include/haproxy/activity.h
Willy Tarreau609aad92018-11-22 08:31:09 +01003 * This file contains macros and inline functions for activity measurements.
4 *
Willy Tarreaua04ded52020-06-02 10:29:48 +02005 * Copyright (C) 2000-2020 Willy Tarreau - w@1wt.eu
Willy Tarreau609aad92018-11-22 08:31:09 +01006 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation, version 2.1
10 * exclusively.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
Willy Tarreaua04ded52020-06-02 10:29:48 +020022#ifndef _HAPROXY_ACTIVITY_H
23#define _HAPROXY_ACTIVITY_H
Willy Tarreau609aad92018-11-22 08:31:09 +010024
Willy Tarreau3fb6a7b2021-01-28 19:19:26 +010025#include <import/xxhash.h>
Willy Tarreaua04ded52020-06-02 10:29:48 +020026#include <haproxy/activity-t.h>
Willy Tarreaub2551052020-06-09 09:07:15 +020027#include <haproxy/api.h>
Willy Tarreau66347942020-06-01 12:18:08 +020028#include <haproxy/freq_ctr.h>
Willy Tarreaub2551052020-06-09 09:07:15 +020029#include <haproxy/time.h>
Willy Tarreau609aad92018-11-22 08:31:09 +010030
Willy Tarreau75c62c22018-11-22 11:02:09 +010031extern unsigned int profiling;
Willy Tarreaud9add3a2019-04-25 08:57:41 +020032extern unsigned long task_profiling_mask;
Willy Tarreau609aad92018-11-22 08:31:09 +010033extern struct activity activity[MAX_THREADS];
Willy Tarreau3fb6a7b2021-01-28 19:19:26 +010034extern struct sched_activity sched_activity[256];
Willy Tarreau609aad92018-11-22 08:31:09 +010035
Willy Tarreau609aad92018-11-22 08:31:09 +010036void report_stolen_time(uint64_t stolen);
37
38/* Collect date and time information before calling poll(). This will be used
39 * to count the run time of the past loop and the sleep time of the next poll.
Willy Tarreaubaba82f2018-11-22 08:42:42 +010040 * It also makes use of the just updated before_poll timer to count the loop's
41 * run time and feed the average loop time metric (in microseconds).
Willy Tarreau609aad92018-11-22 08:31:09 +010042 */
43static inline void activity_count_runtime()
44{
45 uint64_t new_mono_time;
46 uint64_t new_cpu_time;
47 int64_t stolen;
Willy Tarreaubaba82f2018-11-22 08:42:42 +010048 uint32_t run_time;
Willy Tarreaud2d33482019-04-25 17:09:07 +020049 uint32_t up, down;
50
51 /* 1 millisecond per loop on average over last 1024 iterations is
52 * enough to turn on profiling.
53 */
54 up = 1000;
55 down = up * 99 / 100;
Willy Tarreau609aad92018-11-22 08:31:09 +010056
57 new_cpu_time = now_cpu_time();
58 new_mono_time = now_mono_time();
59
Willy Tarreau81036f22019-05-20 19:24:50 +020060 if (ti->prev_cpu_time && ti->prev_mono_time) {
61 new_cpu_time -= ti->prev_cpu_time;
62 new_mono_time -= ti->prev_mono_time;
Willy Tarreau609aad92018-11-22 08:31:09 +010063 stolen = new_mono_time - new_cpu_time;
64 if (unlikely(stolen >= 500000)) {
65 stolen /= 500000;
66 /* more than half a millisecond difference might
67 * indicate an undesired preemption.
68 */
69 report_stolen_time(stolen);
70 }
71 }
Willy Tarreaubaba82f2018-11-22 08:42:42 +010072
73 run_time = (before_poll.tv_sec - after_poll.tv_sec) * 1000000U + (before_poll.tv_usec - after_poll.tv_usec);
Willy Tarreauaa622b82021-01-28 21:44:22 +010074 run_time = swrate_add(&activity[tid].avg_loop_us, TIME_STATS_SAMPLES, run_time);
Willy Tarreaud9add3a2019-04-25 08:57:41 +020075
Willy Tarreauaa622b82021-01-28 21:44:22 +010076 /* In automatic mode, reaching the "up" threshold on average switches
77 * profiling to "on" when automatic, and going back below the "down"
78 * threshold switches to off. The forced modes don't check the load.
Willy Tarreaud2d33482019-04-25 17:09:07 +020079 */
Willy Tarreaud9add3a2019-04-25 08:57:41 +020080 if (!(task_profiling_mask & tid_bit)) {
Willy Tarreaud2d33482019-04-25 17:09:07 +020081 if (unlikely((profiling & HA_PROF_TASKS_MASK) == HA_PROF_TASKS_ON ||
Willy Tarreauaa622b82021-01-28 21:44:22 +010082 ((profiling & HA_PROF_TASKS_MASK) == HA_PROF_TASKS_AON &&
83 swrate_avg(run_time, TIME_STATS_SAMPLES) >= up)))
84 _HA_ATOMIC_OR(&task_profiling_mask, tid_bit);
Willy Tarreaud9add3a2019-04-25 08:57:41 +020085 } else {
Willy Tarreaud2d33482019-04-25 17:09:07 +020086 if (unlikely((profiling & HA_PROF_TASKS_MASK) == HA_PROF_TASKS_OFF ||
Willy Tarreauaa622b82021-01-28 21:44:22 +010087 ((profiling & HA_PROF_TASKS_MASK) == HA_PROF_TASKS_AOFF &&
88 swrate_avg(run_time, TIME_STATS_SAMPLES) <= down)))
89 _HA_ATOMIC_AND(&task_profiling_mask, ~tid_bit);
Willy Tarreaud9add3a2019-04-25 08:57:41 +020090 }
Willy Tarreau609aad92018-11-22 08:31:09 +010091}
92
Willy Tarreau3fb6a7b2021-01-28 19:19:26 +010093/* Computes the index of function pointer <func> for use with sched_activity[]
94 * or any other similar array passed in <array>, and returns a pointer to the
95 * entry after having atomically assigned it to this function pointer. Note
96 * that in case of collision, the first entry is returned instead ("other").
97 */
98static inline struct sched_activity *sched_activity_entry(struct sched_activity *array, const void *func)
99{
100 uint64_t hash = XXH64_avalanche(XXH64_mergeRound((size_t)func, (size_t)func));
101 struct sched_activity *ret;
102 const void *old = NULL;
103
104 hash ^= (hash >> 32);
105 hash ^= (hash >> 16);
106 hash ^= (hash >> 8);
107 hash &= 0xff;
108 ret = &array[hash];
109
110 if (likely(ret->func == func))
111 return ret;
112
113 if (HA_ATOMIC_CAS(&ret->func, &old, func))
114 return ret;
115
116 return array;
117}
Willy Tarreau609aad92018-11-22 08:31:09 +0100118
Willy Tarreaua04ded52020-06-02 10:29:48 +0200119#endif /* _HAPROXY_ACTIVITY_H */
Willy Tarreau609aad92018-11-22 08:31:09 +0100120
121/*
122 * Local variables:
123 * c-indent-level: 8
124 * c-basic-offset: 8
125 * End:
126 */