#ifndef HIGHWAY_HWY_CONTRIB_THREAD_POOL_TOPOLOGY_H_
#define HIGHWAY_HWY_CONTRIB_THREAD_POOL_TOPOLOGY_H_
#include <stddef.h>
#include <vector>
#include "hwy/base.h"
#include "hwy/bit_set.h"
namespace hwy {
HWY_CONTRIB_DLLEXPORT bool HaveThreadingSupport();
static constexpr size_t kMaxLogicalProcessors = 1024;
using LogicalProcessorSet = BitSet4096<kMaxLogicalProcessors>;
HWY_CONTRIB_DLLEXPORT bool GetThreadAffinity(LogicalProcessorSet& lps);
HWY_CONTRIB_DLLEXPORT bool SetThreadAffinity(const LogicalProcessorSet& lps);
static inline bool PinThreadToLogicalProcessor(size_t lp) {
LogicalProcessorSet lps;
lps.Set(lp);
return SetThreadAffinity(lps);
}
HWY_CONTRIB_DLLEXPORT size_t TotalLogicalProcessors();
struct Topology {
HWY_CONTRIB_DLLEXPORT Topology();
struct Cluster {
LogicalProcessorSet lps;
uint64_t private_kib = 0; uint64_t shared_kib = 0; uint64_t reserved1 = 0;
uint64_t reserved2 = 0;
uint64_t reserved3 = 0;
};
struct Core {
LogicalProcessorSet lps;
uint64_t reserved = 0;
};
struct Package {
std::vector<Cluster> clusters;
std::vector<Core> cores;
};
std::vector<Package> packages;
#pragma pack(push, 1)
struct LP {
uint16_t cluster = 0; uint16_t core = 0; uint8_t package = 0; uint8_t smt = 0; uint8_t node = 0;
uint8_t reserved = 0;
};
#pragma pack(pop)
std::vector<LP> lps; };
#pragma pack(push, 1)
struct Cache {
static constexpr uint16_t kMaxAssociativity = 128;
uint32_t size_kib = 0;
uint32_t sets = 0;
uint16_t bytes_per_line = 0;
uint16_t associativity = 0; uint16_t cores_sharing = 0; uint16_t reserved = 0;
};
static_assert(sizeof(Cache) == 16, "Unexpected size");
#pragma pack(pop)
HWY_CONTRIB_DLLEXPORT const Cache* DataCaches();
}
#endif