文件:util-affinity.h util-affinity.c
#ifndef __UTIL_AFFINITY_H__
#define __UTIL_AFFINITY_H__
#include "suricata-common.h"
#include "conf.h"
#if defined OS_FREEBSD
#include <sched.h>
#include <sys/param.h>
#include <sys/resource.h>
#include <sys/cpuset.h>
#include <sys/thr.h>
#define cpu_set_t cpuset_t
#elif defined __OpenBSD__
#include <sched.h>
#include <sys/param.h>
#include <sys/resource.h>
#elif defined OS_DARWIN
#include <mach/mach.h>
#include <mach/mach_init.h>
#include <mach/thread_policy.h>
// thread_affinity_policy_data_t 是一种用于描述线程关联性(affinity)策略的数据结构。
// 关联性是指一种指导操作系统调度器的机制,使特定的线程更倾向于在特定的CPU核心或核心集上运行。这对于某些高性能计算任务或实时任务可能非常有用,因为它可以减少上下文切换和缓存失效的开销。
// thread_affinity_policy_data_t`是一种特定的数据类型,用于设定线程关联性策略。下面是这个结构的定义:
// typedef struct thread_affinity_policy {
// int affinity_tag;
// } thread_affinity_policy_data_t;
// 其中 `affinity_tag` 是一个整数,用于表示线程的关联标签(affinity tag)。线程具有相同关联标签的倾向于在同一处理器核心上运行。
// 当你要设置线程的关联性策略时,你可以创建一个 `thread_affinity_policy_data_t` 结构,设置适当的关联标签,
// 并使用 `thread_policy_set` 函数将其应用于特定线程。
// 示例:
// thread_affinity_policy_data_t policy;
// policy.affinity_tag = 1; // 1 is the affinity tag
// thread_policy_set(thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, THREAD_AFFINITY_POLICY_COUNT);
// 这里的 `THREAD_AFFINITY_POLICY` 和 `THREAD_AFFINITY_POLICY_COUNT` 是描述策略类型和大小的常量。
// 请注意,线程关联性是一个提示,而不是一个硬性规定。即使为线程设置了关联性策略,操作系统调度器仍然可能会在其他处理器上运行该线程。
// 关联性策略的效果也可能因操作系统和硬件架构的不同而有所不同。
// `affinity_tag`是一个抽象的标签,用于将具有相同关联性需求的线程组合在一起。
// 当你为多个线程设置相同的`affinity_tag`时,操作系统的调度器会尽量让这些线程在同一个CPU核心或核心组上运行。
// `affinity_tag`的具体值没有特定的含义。它只是一个标识符或标签,用于将具有相同关联性需求的线程组合在一起。
// 在以下示例中:
// policy.affinity_tag = 1; // 1 is the affinity tag
// 数字`1`只是一个标识符。你可以选择任何整数值作为关联标签,只要你在你的应用程序或系统中一致使用它就可以了。
// 如果你在多个线程之间设置相同的`affinity_tag`值,那么操作系统将尽量让这些线程在同一处理器核心上运行。
// 这样做的目的通常是为了提高缓存效率和性能,因为在同一核心上运行的线程可以共享缓存和其他资源。
// 请注意,线程关联性是一个建议性的机制,而不是强制性的。调度器可能会基于系统的其他需求和负载来忽略或覆盖关联性设置。
// 这条宏定义将 cpu_set_t 重新定义为 thread_affinity_policy_data_t。这样,在代码中使用 cpu_set_t 时,实际上是在使用 thread_affinity_policy_data_t 类型。
#define cpu_set_t thread_affinity_policy_data_t
// 这条宏定义重新定义了 CPU_SET 宏。它接受一个 CPU 编号 cpu_id 和一个 CPU 集合 new_mask 作为参数,
// 并将 new_mask 中的 affinity_tag 设置为 cpu_id + 1。这似乎是一种将 CPU 编号映射到 affinity_tag 的方式。
#define CPU_SET(cpu_id, new_mask) (*(new_mask)).affinity_tag = (cpu_id + 1)
// 这条宏定义重新定义了 CPU_ISSET 宏。它接受一个 CPU 编号 cpu_id 和一个 CPU 集合 new_mask 作为参数,
#define CPU_ISSET(cpu_id, new_mask) ((*(new_mask)).affinity_tag == (cpu_id + 1))
// 这条宏定义重新定义了 CPU_ZERO 宏。它接受一个 CPU 集合 new_mask 作为参数,并将 new_mask 中的 affinity_tag 设置为 THREAD_AFFINITY_TAG_NULL。
#define CPU_ZERO(new_mask) (*(new_mask)).affinity_tag = THREAD_AFFINITY_TAG_NULL
#endif
enum {
RECEIVE_CPU_SET,
WORKER_CPU_SET,
VERDICT_CPU_SET,
MANAGEMENT_CPU_SET,
MAX_CPU_SET
};
// BALANCED_AFFINITY: 这个常量值可能表示一种"平衡"的线程亲和性配置模式。
// 在多线程程序中,线程亲和性指的是将线程绑定到特定的 CPU 核心或处理器,以优化性能。
// "平衡"的线程亲和性可能意味着线程会在多个 CPU 核心之间分配,以实现负载均衡。
// EXCLUSIVE_AFFINITY: 这个常量值可能表示一种"独占"的线程亲和性配置模式。
// 在这种模式下,每个线程会被绑定到一个特定的 CPU 核心或处理器,从而实现更精细的性能控制和优化。
// 这可以用于确保某些关键任务始终在同一核心上执行,避免由于核心切换而引起的性能下降。
// MAX_AFFINITY: 这个常量值可能表示一个枚举值的上限。在这里,它可能被用来表示枚举的最大值或可选项的总数。
enum {
BALANCED_AFFINITY,
EXCLUSIVE_AFFINITY,
MAX_AFFINITY
};
// 用于存储线程亲和性(thread affinity)的相关设置信息。
// 用于保存不同线程亲和性类型的相关信息,包括名称、模式、优先级、线程数目以及允许运行的 CPU 集合等。
// 它可能在代码中用于组织和管理不同线程亲和性设置的数据。
// 从配置中读取节点信息,然后将其保存到这个结构体中。
typedef struc ThreadsAffinityType_ {
const char *name; // 一个指向字符串的指针,用于存储线程亲和性类型的名称。
uint8_t mode_flag; // 一个8位无符号整数,用于存储线程亲和性的模式标志。
int prio; // 一个整数,用于存储线程亲和性的优先级。
uint32_t nb_threads; // 一个32位无符号整数,用于存储线程数目。
SCMutex taf_mutex; // 一个名为 taf_mutex 的互斥锁,用于保护线程亲和性设置的访问。
uint16_t lcpu; /* use by exclusive mode */
#if !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenB