MINOR: activity: declare a new structure to collect per-function activity
The new sched_activity structure will be used to collect task-level activity based on the target function. The principle is to declare a large enough array to make collisions rare (256 entries), and hash the function pointer using a reduced XXH to decide where to store the stats. On first computation an entry is definitely assigned to the array and it's done atomically. A special entry (0) is used to store collisions ("others"). The goal is to make it easy and inexpensive for the scheduler code to use these to store #calls, cpu_time and lat_time for each task.
This commit is contained in:
parent
aa622b822b
commit
3fb6a7b46e
|
@ -74,6 +74,19 @@ struct activity {
|
|||
char __end[0] __attribute__((aligned(64))); // align size to 64.
|
||||
};
|
||||
|
||||
|
||||
/* global profiling stats from the scheduler: each entry corresponds to a
|
||||
* task or tasklet ->process function pointer, with a number of calls and
|
||||
* a total time. Each entry is unique, except entry 0 which is for colliding
|
||||
* hashes (i.e. others). All of these must be accessed atomically.
|
||||
*/
|
||||
struct sched_activity {
|
||||
const void *func;
|
||||
uint64_t calls;
|
||||
uint64_t cpu_time;
|
||||
uint64_t lat_time;
|
||||
};
|
||||
|
||||
#endif /* _HAPROXY_ACTIVITY_T_H */
|
||||
|
||||
/*
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#ifndef _HAPROXY_ACTIVITY_H
|
||||
#define _HAPROXY_ACTIVITY_H
|
||||
|
||||
#include <import/xxhash.h>
|
||||
#include <haproxy/activity-t.h>
|
||||
#include <haproxy/api.h>
|
||||
#include <haproxy/freq_ctr.h>
|
||||
|
@ -30,6 +31,7 @@
|
|||
extern unsigned int profiling;
|
||||
extern unsigned long task_profiling_mask;
|
||||
extern struct activity activity[MAX_THREADS];
|
||||
extern struct sched_activity sched_activity[256];
|
||||
|
||||
void report_stolen_time(uint64_t stolen);
|
||||
|
||||
|
@ -88,6 +90,31 @@ static inline void activity_count_runtime()
|
|||
}
|
||||
}
|
||||
|
||||
/* Computes the index of function pointer <func> for use with sched_activity[]
|
||||
* or any other similar array passed in <array>, and returns a pointer to the
|
||||
* entry after having atomically assigned it to this function pointer. Note
|
||||
* that in case of collision, the first entry is returned instead ("other").
|
||||
*/
|
||||
static inline struct sched_activity *sched_activity_entry(struct sched_activity *array, const void *func)
|
||||
{
|
||||
uint64_t hash = XXH64_avalanche(XXH64_mergeRound((size_t)func, (size_t)func));
|
||||
struct sched_activity *ret;
|
||||
const void *old = NULL;
|
||||
|
||||
hash ^= (hash >> 32);
|
||||
hash ^= (hash >> 16);
|
||||
hash ^= (hash >> 8);
|
||||
hash &= 0xff;
|
||||
ret = &array[hash];
|
||||
|
||||
if (likely(ret->func == func))
|
||||
return ret;
|
||||
|
||||
if (HA_ATOMIC_CAS(&ret->func, &old, func))
|
||||
return ret;
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
#endif /* _HAPROXY_ACTIVITY_H */
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@ unsigned long task_profiling_mask = 0;
|
|||
/* One struct per thread containing all collected measurements */
|
||||
struct activity activity[MAX_THREADS] __attribute__((aligned(64))) = { };
|
||||
|
||||
/* One struct per function pointer hash entry (256 values, 0=collision) */
|
||||
struct sched_activity sched_activity[256] __attribute__((aligned(64))) = { };
|
||||
|
||||
/* Updates the current thread's statistics about stolen CPU time. The unit for
|
||||
* <stolen> is half-milliseconds.
|
||||
|
|
Loading…
Reference in New Issue