是否在Ubuntu 16.04中正式支持SCHED_DEADLINE

时间:2021-11-04 12:12:47

Currently I'm running Ubuntu 16.04 with linux kernel version to be 4.16. I wrote a dummy program that changes its scheduler to SCHED_DEADLINE. But when I tried to compile it, it cannot find definition of structs and macros needed for SCHED_DEADLINE. Most of the code snippet was taken from here (page 24). Below is the test program:

目前我正在运行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;
}

Here's the output of the compilation:

这是编译的输出:

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;

My gcc version:

我的gcc版本:

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

However, the sample code posted in the official website works for me, but the sample code manually defines all the needed macros and system calls in the program. My goal was to compile the application without adding those definitions, which should already be included in the newest kernel version. I have seen various places saying that SCHED_DEADLINE is officially supported after Linux 3.14.10, and upgrading the kernel would automatically solve this issue.

但是,官方网站上发布的示例代码适用于我,但示例代码手动定义了程序中所需的所有宏和系统调用。我的目标是编译应用程序而不添加那些应该已经包含在最新内核版本中的定义。我见过各种各样的地方说在Linux 3.14.10之后正式支持SCHED_DEADLINE,升级内核会自动解决这个问题。

Things I've tried:

我尝试过的事情:

  • Recompiling 4.16 kernel. Previously I thought I need to turn on a switch in config file, but I was not able to find it.
  • 重新编译4.16内核。以前我以为我需要打开配置文件中的开关,但我无法找到它。
  • Look into /usr/include/linux/sched.h. Clearly the macros are defined in this header file, but somehow my compiler cannot find it.
  • 查看/usr/include/linux/sched.h。显然宏是在这个头文件中定义的,但不知怎的,我的编译器找不到它。

I also looked into other posts in the community, but all those questions are for older linux (pre 3.14.10).

我还查看了社区中的其他帖子,但所有这些问题都是针对较旧的linux(3.14.10之前的版本)。

1 个解决方案

#1


3  

You need to include #include <linux/sched.h>

您需要包含#include

But for the definition of sched_setattr() and gettid(), see the link posted by @CraigEstey

但是对于sched_setattr()和gettid()的定义,请参阅@CraigEstey发布的链接

The reason about that, it that glibc will not add function wrappers of linux specific syscall. For example for gettid(), in the manual we can read this:

原因是,glibc不会添加linux特定系统调用的函数包装器。例如对于gettid(),在手册中我们可以读到:

Note: There is no glibc wrapper for this system call; see NOTES.

注意:此系统调用没有glibc包装器;见注意。

Glibc does not provide a wrapper for this system call; call it using syscall(2). The thread ID returned by this call is not the same thing as a POSIX thread ID

Glibc不为此系统调用提供包装器;使用syscall(2)调用它。此调用返回的线程ID与POSIX线程ID不同

Have a look at this article: https://lwn.net/Articles/711058/

看看这篇文章: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;
}

Or a more shorter code, without the redefinition of struct sched_attr

或者更短的代码,没有重新定义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;
}

But this needs to be executed as root, otherwise I got sched_setattr(): Operation not permitted Or the application needs to have the right linux capabilities.

但是这需要以root身份执行,否则我得到了sched_setattr():不允许操作或者应用程序需要具有正确的linux功能。

#1


3  

You need to include #include <linux/sched.h>

您需要包含#include

But for the definition of sched_setattr() and gettid(), see the link posted by @CraigEstey

但是对于sched_setattr()和gettid()的定义,请参阅@CraigEstey发布的链接

The reason about that, it that glibc will not add function wrappers of linux specific syscall. For example for gettid(), in the manual we can read this:

原因是,glibc不会添加linux特定系统调用的函数包装器。例如对于gettid(),在手册中我们可以读到:

Note: There is no glibc wrapper for this system call; see NOTES.

注意:此系统调用没有glibc包装器;见注意。

Glibc does not provide a wrapper for this system call; call it using syscall(2). The thread ID returned by this call is not the same thing as a POSIX thread ID

Glibc不为此系统调用提供包装器;使用syscall(2)调用它。此调用返回的线程ID与POSIX线程ID不同

Have a look at this article: https://lwn.net/Articles/711058/

看看这篇文章: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;
}

Or a more shorter code, without the redefinition of struct sched_attr

或者更短的代码,没有重新定义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;
}

But this needs to be executed as root, otherwise I got sched_setattr(): Operation not permitted Or the application needs to have the right linux capabilities.

但是这需要以root身份执行,否则我得到了sched_setattr():不允许操作或者应用程序需要具有正确的linux功能。