Я пытаюсь использовать планировщик крайних сроков на моем Ubuntu Ubuntu 18.04.2 LTS с базовым ядром 4.15.0-48.Следуя документу ядра https://www.kernel.org/doc/Documentation/scheduler/sched-deadline.txt, Я пытаюсь использовать планировщик крайних сроков для задач, которые назначаются конкретным процессорам для улучшения реакции в реальном времени.Но я получаю ошибку «sched_setattr: Операция не разрешена».
В приведенных ниже кодах, демонстрирующих проблему, я установил процессор 8-11 в основной поток.В потоке реального времени я установил планировщик как планировщик крайнего срока.
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <linux/unistd.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <sys/syscall.h>
#include <pthread.h>
#include <iostream>
#define gettid() syscall(__NR_gettid)
#define SCHED_DEADLINE 6
/* XXX use the proper syscall numbers */
#ifdef __x86_64__
#define __NR_sched_setattr 314
#define __NR_sched_getattr 315
#endif
#ifdef __i386__
#define __NR_sched_setattr 351
#define __NR_sched_getattr 352
#endif
static volatile int done;
struct sched_attr
{
__u32 size;
__u32 sched_policy;
__u64 sched_flags;
/* SCHED_NORMAL, SCHED_BATCH */
__s32 sched_nice;
/* SCHED_FIFO, SCHED_RR */
__u32 sched_priority;
/* SCHED_DEADLINE (nsec) */
__u64 sched_runtime;
__u64 sched_deadline;
__u64 sched_period;
};
int sched_setattr(pid_t pid,
const struct sched_attr *attr,
unsigned int flags)
{
return syscall(__NR_sched_setattr, pid, attr, flags);
}
int sched_getattr(pid_t pid,
struct sched_attr *attr,
unsigned int size,
unsigned int flags){
return syscall(__NR_sched_getattr, pid, attr, size, flags);
}
void *run_deadline(void *data) {
struct sched_attr attr;
int x = 0;
int ret;
unsigned int flags = 0;
std::cout<<"deadline thread started "<< gettid()<<std::endl;
#if 1
attr.size = sizeof(attr);
attr.sched_flags = 0;
attr.sched_nice = 0;
attr.sched_priority = 0;
/* This creates a 10ms/30ms reservation */
attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = 10 * 1000 * 1000;
attr.sched_period = attr.sched_deadline = 50 * 1000 * 1000;
ret = sched_setattr(0, &attr, flags);
if (ret < 0) {
done = 0;
perror("sched_setattr");
exit(-1);
}
#endif
cpu_set_t current_set;
sched_getaffinity(0,sizeof(cpu_set_t),¤t_set);
std::cout<<"deadline thread running on " << sched_getcpu()<<std::endl;
while (!done) {
x++;
}
std::cout<<"deadline thread dies "<< gettid()<<std::endl;
return NULL;
}
int main (int argc, char **argv)
{
pthread_t thread;
std::cout<<"main thread: " << gettid()<<std::endl;
// setting the affinity to 8-11
unsigned long mask = 0xf00;
size_t num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
cpu_set_t *_cpuset = CPU_ALLOC(num_cpus);
size_t size = CPU_ALLOC_SIZE(num_cpus);
CPU_ZERO_S(size, _cpuset);
unsigned int bit_mask = mask;
while (bit_mask > 0) {
int one_psn = __builtin_ffs(bit_mask) - 1;
bit_mask &= (bit_mask - 1);
CPU_SET_S(one_psn, size, _cpuset);
std::cout<<"set affinity to cpu: " << one_psn<<std::endl;
}
errno = 0;
if (0 != sched_setaffinity(0, size, _cpuset)) {
std::cout<<"sched_setaffinity error = " << errno << std::endl;
}
pthread_create(&thread, NULL, run_deadline, NULL);
cpu_set_t current_set;
sched_getaffinity(0,sizeof(cpu_set_t),¤t_set);
std::cout<<"main thread running on " << sched_getcpu()<<std::endl;
sleep(1000);
done = 1;
pthread_join(thread, NULL);
std::cout<<"main dies [%ld] "<< gettid()<<std::endl;
return 0;
}
скомпилируйте его с помощью g ++ -g -o dl dl.c -pthread и запустите с помощью sudo ./dl, и я получу вывод ниже
main thread: 13536
set affinity to cpu: 8
set affinity to cpu: 9
set affinity to cpu: 10
set affinity to cpu: 11
main thread running on 8
deadline thread started 13537
sched_setattr: Operation not permitted