SCHED_DEADLINE 是否在 Ubuntu 16.04 中得到官方支持?
Is SCHED_DEADLINE officially supported in Ubuntu 16.04?
目前我是 运行 Ubuntu 16.04,linux 内核版本为 4.16。我编写了一个虚拟程序,将其调度程序更改为 SCHED_DEADLINE。但是当我试图编译它时,它找不到 SCHED_DEADLINE 所需的结构和宏的定义。大部分代码片段取自 here(第 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)
然而,official website中发布的示例代码对我有用,但示例代码手动定义了程序中所有需要的宏和系统调用。我的目标是在不添加这些定义的情况下编译应用程序,这些定义应该已经包含在最新的内核版本中。看到很多地方说Linux3.14.10之后正式支持SCHED_DEADLINE,升级内核会自动解决这个问题。
我尝试过的事情:
- 正在重新编译 4.16 内核。以前我以为我需要在配置文件中打开一个开关,但我找不到它。
- 调查
/usr/include/linux/sched.h
。很明显宏是在这个头文件中定义的,但不知何故我的编译器找不到它。
我也查看了社区中的其他帖子,但所有这些问题都是针对较早的 linux(3.14.10 之前)。
您需要包括 #include <linux/sched.h>
但对于sched_setattr()
和gettid()
的定义,请参阅@CraigEstey
发布的link
原因在于,glibc 不会添加 linux 特定系统调用的函数包装器。
例如 gettid()
,在手册中我们可以读到:
Note: There is no glibc wrapper for this system call; see NOTES.
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
看看这篇文章: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 功能。
目前我是 运行 Ubuntu 16.04,linux 内核版本为 4.16。我编写了一个虚拟程序,将其调度程序更改为 SCHED_DEADLINE。但是当我试图编译它时,它找不到 SCHED_DEADLINE 所需的结构和宏的定义。大部分代码片段取自 here(第 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)
然而,official website中发布的示例代码对我有用,但示例代码手动定义了程序中所有需要的宏和系统调用。我的目标是在不添加这些定义的情况下编译应用程序,这些定义应该已经包含在最新的内核版本中。看到很多地方说Linux3.14.10之后正式支持SCHED_DEADLINE,升级内核会自动解决这个问题。
我尝试过的事情:
- 正在重新编译 4.16 内核。以前我以为我需要在配置文件中打开一个开关,但我找不到它。
- 调查
/usr/include/linux/sched.h
。很明显宏是在这个头文件中定义的,但不知何故我的编译器找不到它。
我也查看了社区中的其他帖子,但所有这些问题都是针对较早的 linux(3.14.10 之前)。
您需要包括 #include <linux/sched.h>
但对于sched_setattr()
和gettid()
的定义,请参阅@CraigEstey
原因在于,glibc 不会添加 linux 特定系统调用的函数包装器。
例如 gettid()
,在手册中我们可以读到:
Note: There is no glibc wrapper for this system call; see NOTES.
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
看看这篇文章: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 功能。