Официально ли поддерживается SCHED_DEADLINE в Ubuntu 16.04? - PullRequest
0 голосов
/ 29 апреля 2018

В настоящее время я использую Ubuntu 16.04 с версией ядра linux 4.16. Я написал фиктивную программу, которая меняет свой планировщик на SCHED_DEADLINE. Но когда я попытался скомпилировать его, он не может найти определения структур и макросов, необходимых для SCHED_DEADLINE. Большая часть фрагмента кода взята из здесь (стр. 24). Ниже приведена тестовая программа:

#define _GNU_SOURCE
#include <pthread.h>
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <sched.h> 


int main(int argc, char* argv[]) {

    struct sched_attr attr;
    attr.size = sizeof(attr);
    attr.sched_policy = SCHED_DEADLINE;
    attr.sched_runtime = 30000000;
    attr.sched_period = 100000000;
    attr.sched_deadline = attr.sched_period;
    if (sched_setattr(gettid(), &attr, 0))
        perror("sched_setattr()");

    return 0;
}

Вот вывод компиляции:

sched_deadline.c: In function ‘main’:
sched_deadline.c:11:20: error: storage size of ‘attr’ isn’t known
  struct sched_attr attr;
                    ^
sched_deadline.c:12:21: error: invalid application of ‘sizeof’ to incomplete type ‘struct attr’
  attr.size = sizeof(struct attr);
                     ^
sched_deadline.c:13:22: error: ‘SCHED_DEADLINE’ undeclared (first use in this function)
  attr.sched_policy = SCHED_DEADLINE;

Моя версия gcc:

gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)

Однако пример кода, размещенного на официальном сайте , работает для меня, но пример кода вручную определяет все необходимые макросы и системные вызовы в программе. Моя цель состояла в том, чтобы скомпилировать приложение без добавления тех определений, которые уже должны быть включены в новейшую версию ядра. Я видел разные места, где говорилось, что SCHED_DEADLINE официально поддерживается после Linux 3.14.10, и обновление ядра автоматически решит эту проблему.

Вещи, которые я пробовал:

  • Перекомпиляция ядра 4.16. Ранее я думал, что мне нужно включить переключатель в файле конфигурации, но я не смог его найти.
  • Посмотрите на /usr/include/linux/sched.h. Ясно, что макросы определены в этом заголовочном файле, но каким-то образом мой компилятор не может его найти.

Я также просматривал другие посты в сообществе, но все эти вопросы относятся к старому linux (до 3.14.10).

1 Ответ

0 голосов
/ 29 апреля 2018

Вам необходимо включить #include <linux/sched.h>

Но для определения sched_setattr() и gettid() см. Ссылку, опубликованную @ CraigEstey

Причина в том, что glibc не будет добавлять функции-обертки специфичного для Linux системного вызова. Например, для gettid(), в руководстве мы можем прочитать это:

Примечание. Для этого системного вызова не существует оболочки glibc; см. ПРИМЕЧАНИЯ.

Glibc не предоставляет оболочки для этого системного вызова; позвони с помощью Системный вызов (2). Идентификатор потока, возвращаемый этим вызовом, отличается от идентификатора потока POSIX

Посмотрите на эту статью: https://lwn.net/Articles/711058/

#define _GNU_SOURCE
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sched.h>
#include <linux/sched.h>
#include <sys/types.h>

struct sched_attr {
    uint32_t size;

    uint32_t sched_policy;
    uint64_t sched_flags;

    /* SCHED_NORMAL, SCHED_BATCH */
    int32_t sched_nice;

    /* SCHED_FIFO, SCHED_RR */
    uint32_t sched_priority;

    /* SCHED_DEADLINE (nsec) */
    uint64_t sched_runtime;
    uint64_t sched_deadline;
    uint64_t 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 main(int argc, char* argv[]) {

    struct sched_attr attr = {
        .size = sizeof(attr),
        .sched_policy = SCHED_DEADLINE,
        .sched_runtime = 30000000,
        .sched_period = 100000000,
        .sched_deadline = 100000000
    };

    pid_t tid = syscall(SYS_gettid);

    if (sched_setattr(tid, &attr, 0))
        perror("sched_setattr()");

    return 0;
}

Или более короткий код без переопределения struct sched_attr

#define _GNU_SOURCE
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/sched/types.h>
#include <linux/sched.h>
#include <sys/types.h>

int sched_setattr(pid_t pid, const struct sched_attr *attr, unsigned int flags)
{
   return syscall(__NR_sched_setattr, pid, attr, flags);
}

int main(int argc, char* argv[]) {

    struct sched_attr attr = {
        .size = sizeof(attr),
        .sched_policy = SCHED_DEADLINE,
        .sched_runtime = 30000000,
        .sched_period = 100000000,
        .sched_deadline = 100000000
    };

    pid_t tid = syscall(SYS_gettid);

    if (sched_setattr(tid, &attr, 0))
        perror("sched_setattr()");

    return 0;
}

Но это должно быть выполнено от имени пользователя root, в противном случае я получил sched_setattr(): Operation not permitted Или приложение должно иметь правильные возможности Linux.

...