CPU_SET, CPU_CLR, CPU_ISSET, CPU_ZERO, CPU_COUNT, CPU_AND, CPU_OR, CPU_XOR,
CPU_EQUAL, CPU_ALLOC, CPU_ALLOC_SIZE, CPU_FREE, CPU_SET_S, CPU_CLR_S,
CPU_ISSET_S, CPU_ZERO_S, CPU_COUNT_S, CPU_AND_S, CPU_OR_S, CPU_XOR_S,
CPU_EQUAL_S - макросы
для работы
с наборами
ЦП
Standard C library (
libc,
-lc)
#define _GNU_SOURCE /* Смотрите feature_test_macros(7) */
#include <sched.h>
void CPU_ZERO(cpu_set_t *set);
void CPU_SET(int cpu, cpu_set_t *set);
void CPU_CLR(int cpu, cpu_set_t *set);
int CPU_ISSET(int cpu, cpu_set_t *set);
int CPU_COUNT(cpu_set_t *set);
void CPU_AND(cpu_set_t *destset,
cpu_set_t *srcset1, cpu_set_t *srcset2);
void CPU_OR(cpu_set_t *destset,
cpu_set_t *srcset1, cpu_set_t *srcset2);
void CPU_XOR(cpu_set_t *destset,
cpu_set_t *srcset1, cpu_set_t *srcset2);
int CPU_EQUAL(cpu_set_t *set1, cpu_set_t *set2);
cpu_set_t *CPU_ALLOC(int num_cpus);
void CPU_FREE(cpu_set_t *set);
size_t CPU_ALLOC_SIZE(int num_cpus);
void CPU_ZERO_S(size_t setsize, cpu_set_t *set);
void CPU_SET_S(int cpu, size_t setsize, cpu_set_t *set);
void CPU_CLR_S(int cpu, size_t setsize, cpu_set_t *set);
int CPU_ISSET_S(int cpu, size_t setsize, cpu_set_t *set);
int CPU_COUNT_S(size_t setsize, cpu_set_t *set);
void CPU_AND_S(size_t setsize, cpu_set_t *destset,
cpu_set_t *srcset1, cpu_set_t *srcset2);
void CPU_OR_S(size_t setsize, cpu_set_t *destset,
cpu_set_t *srcset1, cpu_set_t *srcset2);
void CPU_XOR_S(size_t setsize, cpu_set_t *destset,
cpu_set_t *srcset1, cpu_set_t *srcset2);
int CPU_EQUAL_S(size_t setsize, cpu_set_t *set1, cpu_set_t *set2);
Набор ЦП
описывается
структурой
данных
cpu_set_t.
Набор ЦП
используется
в
sched_setaffinity(2) и
подобных
интерфейсах.
Тип данных
cpu_set_t
реализован
в виде
битовой
маски.
Однако
структуру
данных
следует
считать
«чёрным
ящиком»:
все
действия с
наборами
ЦП следует
выполнять
с помощью
макросов,
описанных
на этой
странице.
Для работы
с набором
ЦП
set
предоставляются
следующие
макросы:
-
CPU_ZERO()
- Очищает
set, после
этого он не
содержит
ЦП.
-
CPU_SET()
- Добавляет
ЦП cpu в set.
-
CPU_CLR()
- Удаляет
ЦП cpu из set.
-
CPU_ISSET()
- Проверяет,
является
ли ЦП cpu
членом set.
-
CPU_COUNT()
- Возвращает
количество
ЦП в set.
Макросы,
имеющие
аргумент
cpu,
не
вызывают
побочных
эффектов,
все
перечисленные
выше
макросы
могут
использовать
аргумент
более
одного
раза.
Значение
первого ЦП
системы в
cpu
обозначается
как 0,
значение
следующего
ЦП в
cpu равно
1 и т. д.
Нельзя
предполагать
о
доступности
каких-либо
ЦП, или что
набор ЦП
непрерывен,
так как ЦП
могут
динамически
отключаться
или вообще
отсутствовать.
Константой
CPU_SETSIZE (в
настоящее
время 1024)
задаётся
значение
на 1 большее,
чем
максимальный
номер ЦП,
который
можно
хранить в
cpu_set_t.
Следующие
макросы
выполняют
логические
операции
над
наборами
ЦП:
-
CPU_AND()
- Сохраняет
пересечение
наборов srcset1
и srcset2 в destset
(который
может быть
одним из
наборов-аргументов).
-
CPU_OR()
- Сохраняет
объединение
наборов srcset1
и srcset2 в destset
(который
может быть
одним из
наборов-аргументов).
-
CPU_XOR()
- Сохраняет
результат
XOR наборов
srcset1 и srcset2 в destset
(который
может быть
одним из
наборов-аргументов).
Операция XOR
возвращает
набор из
ЦП, которые
есть в
одном из srcset1
или srcset2, но не
в обоих
одновременно.
-
CPU_EQUAL()
- Проверяет,
что два
набора ЦП
содержат
одинаковые
ЦП.
Так как
некоторым
приложениям
может
потребоваться
наборы ЦП
динамически
изменяемых
размеров
(например,
для
выделения
наборов
больше, чем
определено
стандартным
типом
данных
cpu_set_t), glibc
предоставляет
набор
макросов
для этого.
Следующие
макросы
используются
для
выделения
и удаления
наборов ЦП:
-
CPU_ALLOC()
- Выделяет
набор ЦП,
достаточный
для
хранения
ЦП в
диапазоне
от 0 до num_cpus-1.
-
CPU_ALLOC_SIZE()
- Возвращает
размер
набора ЦП в
байтах,
который
необходим
для
хранения
ЦП в
диапазоне
от 0 до num_cpus-1.
Данный
макрос
предоставляет
значение,
которое
можно
использовать
в
аргументе
setsize в
макросах
CPU_*_S(),
описанных
далее.
-
CPU_FREE()
- Освобождает
набор ЦП,
выделенный
ранее с
помощью
CPU_ALLOC().
Макросы,
чьи имена
заканчиваются
на «_S»,
аналогичны
макросам с
тем же
именем без
суффикса.
Эти
макросы
выполняют
те же
задачи что
и их
аналоги, но
они
работают с
динамически
выделяемыми
наборами
ЦП, размер
которых
равен
setsize
байт.
Макросы
CPU_ISSET()
и
CPU_ISSET_S()
возвращают
ненулевое
значение,
если
cpu есть
в
set; в
противном
случае
возвращается
0.
Макросы
CPU_COUNT()
и
CPU_COUNT_S()
возвращают
количество
ЦП в
set.
Макросы
CPU_EQUAL()
и
CPU_EQUAL_S()
возвращают
ненулевое
значение,
если два
набора ЦП
одинаковы;
в
противном
случае
возвращается
0.
При
успешном
выполнении
макрос
CPU_ALLOC()
возвращает
указатель,
при ошибке
возвращается
NULL (ошибки те
же, что и у
malloc(3)).
Макрос
CPU_ALLOC_SIZE()
возвращает
количество
байт,
требуемое
для
хранения
набора ЦП
указанных
элементов.
Другие
функции не
возвращают
никаких
значений.
Макросы
CPU_ZERO(),
CPU_SET(),
CPU_CLR() и
CPU_ISSET()
добавлены
в glibc версии 2.3.3.
Макрос
CPU_COUNT()
впервые
появилась
в glibc версии 2.6.
Макросы
CPU_AND(),
CPU_OR(),
CPU_XOR(),
CPU_EQUAL(),
CPU_ALLOC(),
CPU_ALLOC_SIZE(),
CPU_FREE(),
CPU_ZERO_S(),
CPU_SET_S(),
CPU_CLR_S(),
CPU_ISSET_S(),
CPU_AND_S(),
CPU_OR_S(),
CPU_XOR_S() и
CPU_EQUAL_S() впервые
появились
в glibc версии 2.7.
Данные
интерфейсы
есть
только в Linux.
Для
создания
копии
набора ЦП
используйте
memcpy(3).
Так как
наборы ЦП
это
битовые
маски,
выделяемые
в единицах
длинных
слов,
реальное
количество
ЦП в
динамически
выделенном
наборе ЦП
будет
округлено
до
следующего
кратного
sizeof(unsigned long).
Приложение
должно
считать
содержимое
этих
дополнительных
бит
неопределённым.
Несмотря
на
похожесть
имён,
заметим,
что
константа
CPU_SETSIZE
определяет
количество
ЦП в типе
данных
cpu_set_t
(то есть,
эффективное
количество
битов в
битовой
маске), в то
время как
аргумент
setsize
макросов
CPU_*_S() — это
размер в
байтах.
Типы
данных
параметров
и
возвращаемых
значений,
показанных
в ОБЗОРЕ —
подсказки,
что
ожидается
в каждом
случае.
Однако так
как эти
интерфейсы
реализованы
как
макросы,
компилятор
не
обязательно
поймает
все ошибки
приведения
типов, если
вы
нарушите
предположения.
На
32-разрядных
платформах
в glibc 2.8 и ранее
CPU_ALLOC ()
выделяет
вдвое
больше
пространства,
как
требуется,
и
CPU_ALLOC_SIZE()
возвращает
значение
вдвое
большее,
чем должно.
Эта ошибка
не должна
влиять на
семантику
программы,
но
приводит к
трате
впустую
памяти и
менее
эффективной
работе
макросов
для
динамически
выделяемых
наборов ЦП.
Эти ошибки
исправлены
в glibc версии 2.9.
Следующая
программа
показывает
использование
некоторых
макросов,
работающих
с
динамически
выделяемыми
наборами
ЦП.
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
int
main(int argc, char *argv[])
{
cpu_set_t *cpusetp;
size_t size, num_cpus;
if (argc < 2) {
fprintf(stderr, "Использование: %s <количество-ЦП>\n", argv[0]);
exit(EXIT_FAILURE);
}
num_cpus = atoi(argv[1]);
cpusetp = CPU_ALLOC(num_cpus);
if (cpusetp == NULL) {
perror("CPU_ALLOC");
exit(EXIT_FAILURE);
}
size = CPU_ALLOC_SIZE(num_cpus);
CPU_ZERO_S(size, cpusetp);
for (size_t cpu = 0; cpu < num_cpus; cpu += 2)
CPU_SET_S(cpu, size, cpusetp);
printf("CPU_COUNT() набора: %d\n", CPU_COUNT_S(size, cpusetp));
CPU_FREE(cpusetp);
exit(EXIT_SUCCESS);
}
sched_setaffinity(2),
pthread_attr_setaffinity_np(3),
pthread_setaffinity_np(3),
cpuset(7)
Русский
перевод
этой
страницы
руководства
был сделан
Azamat Hackimov <
[email protected]>, Dmitriy S. Seregin
<
[email protected]>, Dmitry Bolkhovskikh <
[email protected]>,
Katrin Kutepova <
[email protected]>, Yuri Kozlov
<
[email protected]> и Иван
Павлов <
[email protected]>
Этот
перевод
является
бесплатной
документацией;
прочитайте
Стандартную
общественную
лицензию GNU
версии 3
или более
позднюю,
чтобы
узнать об
условиях
авторского
права. Мы не
несем
НИКАКОЙ
ОТВЕТСТВЕННОСТИ.
Если вы
обнаружите
ошибки в
переводе
этой
страницы
руководства,
пожалуйста,
отправьте
электронное
письмо на
[email protected]