/
githubmirror
/
numactl
Обзор
Документация
Войти
/
githubmirror
/
numactl
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
distance.c
115 строк
3 KB
Phong X. Nguyen
Set _GNU_SOURCE more broadly
04 авг 2025, 18:34
04 авг 2025, 18:34
c227f8f
Код
Авторство
О чём код?
/* Discover distances Copyright (C) 2005 Andi Kleen, SuSE Labs. libnuma is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; version 2.1. libnuma is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should find a copy of v2.1 of the GNU Lesser General Public License somewhere on your Linux system; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA All calls are undefined when numa_available returns an error. */ #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <errno.h> #include "numa.h" #include "numaint.h" static int distance_numnodes; static int *distance_table; static void parse_numbers(char *s, int *iptr) { int i, d, j; char *end; int maxnode = numa_max_node(); for (i = 0, j = 0; i <= maxnode; i++, j++) { d = strtoul(s, &end, 0); /* Skip unavailable nodes */ while (j<=maxnode && !numa_bitmask_isbitset(numa_nodes_ptr, j)) j++; if (s == end) break; *(iptr+j) = d; s = end; } } static int read_distance_table(void) { int nd, len; char *line = NULL; size_t linelen = 0; int maxnode = numa_max_node() + 1; int *table = NULL; int err = -1; for (nd = 0;; nd++) { char fn[100]; FILE *dfh; sprintf(fn, "/sys/devices/system/node/node%d/distance", nd); dfh = fopen(fn, "r"); if (!dfh) { if (errno == ENOENT) err = 0; if (!err && nd<maxnode) continue; else break; } len = getdelim(&line, &linelen, '\n', dfh); fclose(dfh); if (len <= 0) break; if (!table) { table = calloc(maxnode * maxnode, sizeof(int)); if (!table) { errno = ENOMEM; break; } } parse_numbers(line, table + nd * maxnode); } free(line); if (err) { numa_warn(W_distance, "Cannot parse distance information in sysfs: %s", strerror(errno)); free(table); return err; } /* Update the global table pointer. Race window here with other threads, but in the worst case we leak one distance array one time, which is tolerable. This avoids a dependency on pthreads. */ if (distance_table) { free(table); return 0; } distance_numnodes = maxnode; distance_table = table; return 0; } int numa_distance(int a, int b) { if (!distance_table) { int err = read_distance_table(); if ((err < 0) || (!distance_table)) return 0; } if ((unsigned)a >= distance_numnodes || (unsigned)b >= distance_numnodes) return 0; return distance_table[a * distance_numnodes + b]; }