rewrite of swiss, swiss will not be public but l4 specific

This commit is contained in:
Youmu Liu
2026-10-08 18:15:05 +08:00
parent 1845a00390
commit 2e7c3040f4
18 changed files with 367 additions and 391 deletions
+56 -16
View File
@@ -27,8 +27,11 @@ typedef struct nif_linux_max_context {
} nif_linux_max_context;
typedef struct nif_linux_fill_cpu_context {
uint64_t *internal;
uint32_t *global;
uint32_t *processor_group_ids;
uint32_t *socket_ids;
uint32_t *cpu_indices;
uint32_t *numa_node_ids;
int numa_id;
int index;
} nif_linux_fill_cpu_context;
@@ -118,14 +121,37 @@ static int nif_linux_track_max_id(int value, void *context)
return 1;
}
static int nif_linux_read_socket_id(int cpu_id, uint32_t *socket_id)
{
char path[160];
char buffer[64];
char *end = NULL;
long parsed_value;
snprintf(path, sizeof(path),
"/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu_id);
if (!nif_linux_read_first_line(path, buffer, sizeof(buffer)))
return 0;
errno = 0;
parsed_value = strtol(buffer, &end, 10);
if (end == buffer || errno == ERANGE || parsed_value < 0 || parsed_value > UINT32_MAX)
return 0;
*socket_id = (uint32_t)parsed_value;
return 1;
}
static int nif_linux_fill_cpu_id(int value, void *context)
{
nif_linux_fill_cpu_context *fill_context = (nif_linux_fill_cpu_context *)context;
uint32_t socket_id = 0;
if (!nif_linux_read_socket_id(value, &socket_id))
return 0;
if (fill_context->internal != NULL)
fill_context->internal[fill_context->index] = (uint64_t)fill_context->index;
if (fill_context->global != NULL)
fill_context->global[fill_context->index] = (uint32_t)value;
fill_context->processor_group_ids[fill_context->index] = 0u;
fill_context->socket_ids[fill_context->index] = socket_id;
fill_context->cpu_indices[fill_context->index] = (uint32_t)value;
fill_context->numa_node_ids[fill_context->index] = (uint32_t)fill_context->numa_id;
fill_context->index++;
return 1;
@@ -211,12 +237,14 @@ static int nif_linux_populate_writable_mapping(void *address, size_t size)
#endif
}
/* Pin the calling thread to a single logical processor.
* core_id >= 0 : bind to that logical processor (global index, across groups).
* core_id < 0 : clear affinity constraint within the current group. */
NIF_API void NIF_DECL nif_set_thread_affinity(int core_id, int numa_id)
/* Linux has no Windows-style processor groups; processor_group_id is ignored. */
NIF_API void NIF_DECL nif_set_thread_affinity(int cpu_index, int processor_group_id)
{
int cpu_count = (int)sysconf(_SC_NPROCESSORS_ONLN);
(void)processor_group_id;
int cpu_count = (int)sysconf(_SC_NPROCESSORS_CONF);
if (cpu_index >= cpu_count)
cpu_count = cpu_index + 1;
if (cpu_count <= 0)
return;
@@ -227,11 +255,11 @@ NIF_API void NIF_DECL nif_set_thread_affinity(int core_id, int numa_id)
CPU_ZERO_S(size, set);
if (core_id < 0) {
if (cpu_index < 0) {
for (int i = 0; i < cpu_count; i++)
CPU_SET_S((int)i, size, set);
} else {
CPU_SET_S(core_id, size, set);
CPU_SET_S(cpu_index, size, set);
}
pthread_setaffinity_np(pthread_self(), size, set);
@@ -264,9 +292,14 @@ NIF_API int NIF_DECL nif_get_numa_overall(int *out_numa_count, int *count_of_eac
return 1;
}
NIF_API int NIF_DECL nif_get_numa_each(int numa_id, uint64_t *internal, uint32_t *global)
NIF_API int NIF_DECL nif_get_numa_each(int numa_id,
uint32_t *processor_group_ids,
uint32_t *socket_ids,
uint32_t *cpu_indices,
uint32_t *numa_node_ids)
{
if (numa_id < 0)
if (numa_id < 0 || processor_group_ids == NULL || socket_ids == NULL ||
cpu_indices == NULL || numa_node_ids == NULL)
return 0;
char path[128];
@@ -275,7 +308,14 @@ NIF_API int NIF_DECL nif_get_numa_each(int numa_id, uint64_t *internal, uint32_t
if (!nif_linux_read_first_line(path, buffer, sizeof(buffer)))
return 0;
nif_linux_fill_cpu_context fill_context = { internal, global, 0 };
nif_linux_fill_cpu_context fill_context = {
processor_group_ids,
socket_ids,
cpu_indices,
numa_node_ids,
numa_id,
0
};
return nif_linux_visit_id_list(buffer, nif_linux_fill_cpu_id, &fill_context);
}