Программа numa_rt_prio.c
запускает фоновый поток с политикой SCHED_FIFO и приоритетом в реальном времени на ядре 4 процессора, а затем программа перемещает одну страницу памяти на узел NUMA 0:
#define _GNU_SOURCE
#include <assert.h>
#include <numa.h>
#include <numaif.h>
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
const int MY_POLICY= SCHED_FIFO;
const int MY_PRIORITY= 10;
struct ThreadCtrl
{
volatile int terminationRequested;
};
static void *startRoutine(void *args)
{
struct ThreadCtrl *ctrl= (struct ThreadCtrl *) args;
while (! ctrl->terminationRequested)
{
}
return 0;
}
int main(int argc, char **argv)
{
int error= 0;
pthread_attr_t attr;
error= pthread_attr_init(&attr);
assert(error == 0);
const int THREAD_CORE= 4;
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(THREAD_CORE, &cpuset);
error= pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpuset);
assert(error == 0);
error= pthread_attr_setschedpolicy(&attr, MY_POLICY);
assert(error == 0);
error= pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
assert(error == 0);
struct sched_param threadParam;
error= pthread_attr_getschedparam(&attr, &threadParam);
assert(error == 0);
threadParam.sched_priority= MY_PRIORITY;
error= pthread_attr_setschedparam(&attr, &threadParam);
assert(error == 0);
pthread_t thread;
struct ThreadCtrl threadCtrl= {.terminationRequested = 0};
error= pthread_create(&thread, &attr, startRoutine, &threadCtrl);
assert(error == 0);
printf("Sleeping and waiting until thread runs ...\n");
sleep(3);
printf("Awaked\n");
const size_t BUF_SIZE= 42;
void *ptr;
error= posix_memalign(&ptr, sysconf(_SC_PAGE_SIZE), BUF_SIZE);
assert(error == 0);
char *buf= ptr;
memset(buf, 0, BUF_SIZE);
int pageNode= 0;
int status= -1;
ptr= buf;
printf("Moving one page ...\n");
error= move_pages(0, 1, &ptr, &pageNode, &status, MPOL_MF_MOVE);
assert(error == 0);
assert(status == pageNode);
printf("One page has been moved ...\n");
threadCtrl.terminationRequested= 1;
error= pthread_join(thread, 0);
assert(error == 0);
return EXIT_SUCCESS;
}
После компиляциис cc -Wall -o numa_rt_prio -pthread numa_rt_prio.c -lnuma
вызов (конечно как root) иногда блокируется:
# ./numa_rt_prio
Sleeping and waiting until thread runs ...
Awaked
Moving one page ...
Но иногда программа запускается без проблем:
# ./numa_rt_prio
Sleeping and waiting until thread runs ...
Awaked
Moving one page ...
One page has been moved ...
Если фоновый поток выполняется безприоритеты реального времени, move_pages () всегда успешно выполняется.Если фоновый поток не привязан к какому-либо ядру ЦП, move_pages () также всегда успешно выполняется.
Даже уменьшение sched_rt_runtime_us
не помогает:
$ cat /proc/sys/kernel/sched_rt_runtime_us
550000
Есть ли у вас какие-либо представления о том, чтопроблема?