linux下的sched头文件
- 格式:doc
- 大小:208.00 KB
- 文档页数:24
linux 调用schedule函数例子Linux 调用 schedule 函数的例子在 Linux 内核中,schedule 函数是用于进行进程调度的重要函数。
它负责决定下一个要运行的进程,并切换到该进程的上下文。
下面是一个调用 schedule 函数的简单例子:```c#include <linux/sched.h>int main(void) {struct task_struct *next_task;// 调用 schedule 函数,选择下一个要运行的进程next_task = schedule();// 打印进程的 PIDprintk("Next scheduled task's PID: %d\n", next_task->pid);return 0;}```在上述例子中,我们首先包含了 `<linux/sched.h>` 头文件,该头文件包含了schedule 函数的声明。
然后,我们声明了一个指向 `task_struct` 结构体的指针`next_task`,它将用于保存调度函数返回的下一个进程。
接下来,我们调用了 schedule 函数,并将返回值赋给 `next_task`。
由于这是一个简单的示例,我们并没有传递任何参数给 schedule 函数,实际上,在实际的进程调度中,schedule 函数会根据一系列的调度策略和优先级来选择下一个要运行的进程。
最后,我们使用 printk 函数打印了下一个调度的进程的 PID。
需要注意的是,上述代码只是一个示例,无法在用户空间中直接运行。
在Linux 内核中调用 schedule 函数需要在合适的上下文中进行,通常在内核模块或调度程序的其他部分中执行。
通过了解 schedule 函数的用法及其在进程调度中的作用,我们可以更好地理解Linux 内核中的调度机制,并更好地进行系统性能优化和调试。
linux sched_setscheduler函数解析sched_setscheduler函数是一个Linux系统调用函数,用于修改进程的调度策略和优先级。
函数原型为:```cint sched_setscheduler(pid_t pid, int policy, const structsched_param *param);```参数说明:- pid:要修改调度策略和优先级的进程ID。
如果pid为0,则表示修改当前进程。
- policy:要设置的调度策略。
可以取以下值:- SCHED_OTHER:普通进程调度策略,即默认策略。
这是一个非实时调度策略,由时间片轮转算法控制。
- SCHED_FIFO:先进先出调度策略。
使用FIFO调度策略的进程优先级比其他普通进程高。
- SCHED_RR:轮转调度策略。
与FIFO策略类似,但进程会在使用完时间片后轮转到等待队列的末尾。
- SCHED_BATCH:批处理调度策略。
适合批处理作业,将进程聚集在一起批量执行。
- SCHED_IDLE:空闲调度策略。
只有在没有其他优先级较高的进程运行时,才会执行该进程。
- SCHED_DEADLINE:截止时间调度策略。
用于实时系统,根据任务的截止时间进行调度。
- param:一个指向sched_param结构体的指针,用于设置进程的优先级和其他调度参数。
sched_param结构体包含一个int类型的成员sched_priority,表示进程的优先级。
函数返回值为0表示成功,返回-1表示失败并设置errno。
sched_setscheduler函数用于修改进程的调度策略和优先级。
在修改调度策略之前,需要获得相应的权限。
调用该函数后,进程会立即按照新的调度策略和优先级进行调度。
注意事项:- 一些调度策略(如SCHED_FIFO和SCHED_RR)需要root权限,因此需要以root用户身份运行程序或具有相应的权限。
- 修改调度策略和优先级可能会影响系统的整体性能和稳定性,需要谨慎使用。
1.linux HZLinux核心几个重要跟时间有关的名词或变数,以下将介绍HZ、tick与jiffies。
HZLinux核心每隔固定周期会发出timer interrupt (IRQ 0),HZ是用来定义每一秒有几次timer interrupts。
举例来说,HZ为1000,代表每秒有1000次timer interrupts。
HZ可在编译核心时设定,如下所示(以核心版本2.6.20-15为例):adrian@adrian-desktop:~$ cd /usr/src/linuxadrian@adrian-desktop:/usr/src/linux$ make menuconfigProcessor type and features ---> Timer frequency (250 HZ) --->其中HZ可设定100、250、300或1000。
小实验观察/proc/interrupt的timer中断次数,并于一秒后再次观察其值。
理论上,两者应该相差250左右。
adrian@adrian-desktop:~$ cat /proc/interrupts | grep timer && sleep 1 && cat /proc/interrupts | grep timer0: 9309306 IO-APIC-edge timer0: 9309562 IO-APIC-edge timer上面四个栏位分别为中断号码、CPU中断次数、PIC与装置名称。
要检查系统上HZ的值是什么,就执行命令cat kernel/.config | grep '^CONFIG_HZ='2.TickTick是HZ的倒数,意即timer interrupt每发生一次中断的时间。
如HZ为250时,tick为4毫秒(millisecond)。
3.JiffiesJiffies为Linux核心变数(unsigned long),它被用来记录系统自开机以来,已经过了多少tick。
Linux V0.11目录文件简介●Makefile文件:该文件是编译辅助工具软件make的参数配置文件。
●boot目录:功能是当计算机加电时引导内核启动,将内核代码加载到内存中,并做一些进入入32位保护运行方式前的系统初始化工作。
①Bootsect.s:磁盘引导块程序,驻留磁盘第一个扇区。
0x7C00②Setup.s:读取机器的硬件配置参数,并把内核模块system移动到适当的内存位置处。
③Head.s:被编译连接在system模块的最前部分,主要进行硬件设备的探测设置和内存管理页面的初始设置工作。
●fs目录:文件系统实现程序的目录。
1、file_table.c文件中,目前仅定义了一个文件句柄(描述符)结构数组。
2、ioctl.c文件将引用kernel/chr_dev/tty.c中的函数,实现字符设备的io控制功能。
3、exec.c程序主要包含一个执行程序函数do_execve(),它是所有exec()函数簇中的主要函数。
4、fcntl.c程序用于实现文件i/o控制的系统调用函数。
5、read_write.c程序用于实现文件读/写和定位三个系统调用函数。
6、stat.c程序中实现了两个获取文件状态的系统调用函数。
7、open.c程序主要包含实现修改文件属性和创建与关闭文件的系统调用函数。
8、char_dev.c主要包含字符设备读写函数rw_char()。
9、pipe.c程序中包含管道读写函数和创建管道的系统调用。
10、file_dev.c程序中包含基于i节点和描述符结构的文件读写函数。
11、namei.c程序主要包括文件系统中目录名和文件名的操作函数和系统调用函数。
12、block_dev.c程序包含块数据读和写函数。
13、inode.c程序中包含针对文件系统i节点操作的函数。
14、truncate.c程序用于在删除文件时释放文件所占用的设备数据空间。
15、bitmap.c程序用于处理文件系统中i节点和逻辑数据块的位图。
linux sched_fifo 例子代码下面是一个简单的示例代码,展示如何使用Linux的`sched_fifo`调度程序来创建一个FIFO队列:```c#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <pthread.h>#include <sched.h>#define NUM_THREADS 5void *thread_func(void *arg) {int id = *((int *)arg);printf("Thread %d is running\n", id);sched_setscheduler(0, SCHED_FIFO, &id);while (1) {printf("Thread %d is waiting\n", id);sleep(1);}return NULL;}int main() {pthread_t threads[NUM_THREADS];int thread_ids[NUM_THREADS];for (int i = 0; i < NUM_THREADS; i++) {thread_ids[i] = i;pthread_create(&threads[i], NULL, thread_func,&thread_ids[i]);}for (int i = 0; i < NUM_THREADS; i++) {pthread_join(threads[i], NULL);}return 0;}```在这个例子中,我们创建了5个线程,每个线程都会运行一个`thread_func`函数。
在`thread_func`函数中,我们首先打印出线程的ID,然后使用`sched_setscheduler`函数将线程设置为使用`SCHED_FIFO`调度程序。
linux 线程优先级设置方法Linux操作系统中,线程是轻量级的进程,合理设置线程的优先级可以优化系统资源的分配,提高程序的执行效率。
本文将详细介绍Linux线程优先级的设置方法。
一、线程优先级概述在Linux操作系统中,线程优先级通常分为两种:静态优先级和动态优先级。
1.静态优先级:在创建线程时分配的优先级,通常在程序运行过程中不会改变。
2.动态优先级:系统根据线程的运行情况动态调整的优先级,通常与线程的CPU使用时间、等待时间等因素有关。
二、设置线程优先级的方法1.使用sched_setparam()函数设置静态优先级函数原型:```cint sched_setparam(pid_t pid, const struct sched_param *param);```示例代码:```c#include <stdio.h>#include <unistd.h>#include <sched.h>#include <pthread.h>void *thread_function(void *arg) {// 线程函数代码}int main() {pthread_t tid;struct sched_param param;int policy;// 创建线程pthread_create(&tid, NULL, thread_function, NULL);// 获取当前线程的调度策略和优先级pthread_getschedparam(pthread_self(), &policy, ¶m);// 设置优先级(数值越大,优先级越高)param.sched_priority = 30;// 设置线程优先级if (pthread_setschedparam(tid, policy, ¶m) != 0) { perror("pthread_setschedparam");return 1;}// 等待线程结束pthread_join(tid, NULL);return 0;}```2.使用nice()函数设置动态优先级函数原型:```cint nice(int inc);```示例代码:```c#include <stdio.h>#include <unistd.h>#include <sys/resource.h>int main() {// 获取当前进程的nice值int old_nice = nice(0);// 设置新的nice值(数值越小,优先级越高)if (nice(-10) == -1) {perror("nice");return 1;}// 输出新的优先级printf("New priority: %d", old_nice - 10);return 0;}```三、总结本文介绍了Linux线程优先级的设置方法,包括使用sched_setparam()函数设置静态优先级和使用nice()函数设置动态优先级。
深⼊解读Linux进程调度Schedule【转】调度系统是现代操作系统⾮常核⼼的基础⼦系统之⼀,尤其在多任务并⾏操作系统(Multitasking OS)上,系统可能运⾏于单核或者多核CPU上,进程可能处于运⾏状态或者在内存中可运⾏等待状态。
如何实现多任务同时使⽤资源并且提供给⽤户及时的响应实现实时交互以及提供⾼流量并发等对现代操作系统的设计实现带来了巨⼤挑战,⽽Linux调度⼦系统的设计同样需要实现这些看似⽭盾的要求,适应不同的使⽤场景。
我们看到Linux是⼀个复杂的现在操作系统,各个⼦系统之间相互合作才能完成⾼效的任务。
本⽂从围绕调度⼦系统,介绍了调度⼦系统核⼼的概念,并且将其与Linux各个相关组件的关系进⾏探讨,尤其是与调度⼦系统息息相关的中断(softirq和irq)⼦系统以及定时器Timer,深⼊⽽全⾯地展⽰了调度相关的各个概念以及相互联系。
由于笔者最近在调试PowerPC相关的芯⽚,因此相关的介绍会以此为例提取相关的内核源代码进⾏解读展⽰。
涉及的代码为Linux-4.4稳定发布版本,读者可以查看源码进⾏对照。
1. 相关概念要理解调度⼦系统,⾸先需要总体介绍调度的流程,对系统有⼀个⾼屋建瓴的认识之后,再在整体流程中对各个节点分别深⼊分析,从⽽掌握丰富⽽饱满的细节。
在系统启动早期,会注册硬件中断,时钟中断是硬件中断中⾮常重要的⼀种,调度过程中需要不断地刷新进程的状态以及设置调度标志已决定是否抢占进程的执⾏进⾏调度。
时钟中断就是周期性地完成此项⼯作。
这⾥⼜引出另外⼀个现代OS的调度设计思想即抢占(preempt),⽽与其对应的概念则为⾮抢占或者合作(cooperate),后⾯会给出两者的详细区别。
时钟中断属于硬件中断,Linux系统不⽀持中断嵌套,所以在中断发⽣时⼜会禁⽌本地中断(local_irq_disable),⽽为了尽快相应其他可能的硬件事件,必须要尽快完成处理并开启中断,因此引出了中断下半部,也就是softirq的概念。
1 Linux内核所在目录为/usr/src/kernels/...2 Linux头文件所在目录为/usr/include/...3 找不见头文件可以用find命令查找find / -name *.hlinux常用头文件如下:POSIX标准定义的头文件<dirent.h> 目录项<fcntl.h> 文件控制read,write,fcntl,close,link,stat,umask,unlink,fopen O_RDONLY O_WRONLY O_NONBLOCK等。
<fnmatch.h> 文件名匹配类型<glob.h> 路径名模式匹配类型<grp.h> 组文件<netdb.h> 网络数据库操作<pwd.h> 口令文件<regex.h> 正则表达式<tar.h> TAR归档值<termios.h> 终端I/O<unistd.h> 符号常量unix standard header ->unistd.h,STDIN_FILENO,STDOUT_FILENO <utime.h> 文件时间<wordexp.h> 字符扩展类型-------------------------<arpa/inet.h> INTERNET定义<net/if.h> 套接字本地接口<netinet/in.h> INTERNET地址族<netinet/tcp.h> 传输控制协议定义-------------------------<sys/mman.h> 内存管理声明<sys/select.h> Select函数<sys/socket.h> 套接字借口<sys/stat.h> 文件状态<sys/times.h> 进程时间<sys/types.h> 基本系统数据类型例如:size_t(signed int) off_t(long)<sys/un.h> UNIX域套接字定义<sys/utsname.h> 系统名<sys/wait.h> 进程控制------------------------------POSIX定义的XSI扩展头文件<cpio.h> cpio归档值<dlfcn.h> 动态链接<fmtmsg.h> 消息显示结构<ftw.h> 文件树漫游<iconv.h> 代码集转换使用程序<langinfo.h> 语言信息常量<libgen.h> 模式匹配函数定义<monetary.h> 货币类型<ndbm.h> 数据库操作<nl_types.h> 消息类别<poll.h> 轮询函数<search.h> 搜索表<strings.h> 字符串操作<syslog.h> 系统出错日志记录<ucontext.h> 用户上下文<ulimit.h> 用户限制<utmpx.h> 用户帐户数据库-----------------------------<sys/ipc.h> IPC(命名管道)<sys/msg.h> 消息队列<sys/resource.h>资源操作<sys/sem.h> 信号量<sys/shm.h> 共享存储<sys/statvfs.h> 文件系统信息<sys/time.h> 时间类型<sys/timeb.h> 附加的日期和时间定义<sys/uio.h> 矢量I/O操作------------------------------POSIX定义的可选头文件<aio.h> 异步I/O<mqueue.h> 消息队列<pthread.h> 线程<sched.h> 执行调度<semaphore.h> 信号量<spawn.h> 实时spawn接口<stropts.h> XSI STREAMS接口<trace.h> 事件跟踪3、C/C++头文件一览C#include<assert.h> //设定插入点#include<ctype.h> //字符处理#include<errno.h> //定义错误码#include<float.h> //浮点数处理#include<iso646.h> //对应各种运算符的宏#include<limits.h> //定义各种数据类型最值的常量#include<locale.h> //定义本地化C函数#include<math.h> //定义数学函数#include<setjmp.h> //异常处理支持#include<signal.h> //信号机制支持#include<stdarg.h> //不定参数列表支持#include<stddef.h> //常用常量#include<stdio.h> //定义输入/输出函数#include<stdlib.h> //定义杂项函数及内存分配函数如malloc、free、system、atoi、atol、rand、exit等#include<string.h> //字符串处理,strlen(),strcat(),strcpy(),strcmp()等等#include<time.h> //定义关于时间的函数#include<wchar.h> //宽字符处理及输入/输出#include<wctype.h> //宽字符分类传统C++#include<fstream.h> //改用<fstream>#include<iomanip.h> //改用<iomainip>#include<iostream.h> //改用<iostream>#include<strstrea.h> //该类不再支持,改用<sstream>中的stringstream ————————————————————————————————标准C++#include<algorithm> //STL 通用算法#include<bitset> //STL 位集容器#include<cctype> //字符处理#include<cerrno> //定义错误码#include<cfloat> //浮点数处理#include<ciso646> //对应各种运算符的宏#include<climits> //定义各种数据类型最值的常量#include<clocale> //定义本地化函数#include<cmath> //定义数学函数#include<complex> //复数类#include<csignal> //信号机制支持#include<csetjmp> //异常处理支持#include<cstdarg> //不定参数列表支持#include<cstddef> //常用常量#include<cstdio> //定义输入/输出函数#include<cstdlib> //定义杂项函数及内存分配函数#include<cstring> //字符串处理#include<ctime> //定义关于时间的函数#include<cwchar> //宽字符处理及输入/输出#include<cwctype> //宽字符分类#include<deque> //STL 双端队列容器#include<exception> //异常处理类#include<fstream> //文件输入/输出#include<al> //STL 定义运算函数(代替运算符)#include<limits> //定义各种数据类型最值常量#include<list> //STL 线性列表容器#include<locale> //本地化特定信息#include<map> //STL 映射容器#include<memory> //STL通过分配器进行的内存分配#include<new> //动态内存分配#include<numeric> //STL常用的数字操作#include<iomanip> //参数化输入/输出#include<ios> //基本输入/输出支持#include<iosfwd> //输入/输出系统使用的前置声明#include<iostream> //数据流输入/输出#include<istream> //基本输入流#include<iterator> //STL迭代器#include<ostream> //基本输出流#include<queue> //STL 队列容器#include<set> //STL 集合容器#include<sstream> //基于字符串的流#include<stack> //STL 堆栈容器#include<stdexcept> //标准异常类#include<streambuf> //底层输入/输出支持#include<string> //字符串类#include<typeinfo> //运行期间类型信息#include<utility> //STL 通用模板类#include<valarray> //对包含值的数组的操作#include<vector> //STL 动态数组容器————————————————————————————————C99增加的部分#include<complex.h> //复数处理#include<fenv.h> //浮点环境#include<inttypes.h> //整数格式转换#include<stdbool.h> //布尔环境#include<stdint.h> //整型环境#include<tgmath.h> //通用类型数学宏本文来自CSDN博客,转载请标明出处:/wubin1124/archive/2009/12/09/4971359.aspx******************************************************************************* ****************************************************程序在使用一个函数之前,应该首先声明该函数。
linux的include的用法在Linux中,`include` 是一个关键字,用于在C和C++编程语言中引入头文件。
包含头文件是将预定义的函数、宏、结构和其他数据类型引入到程序中的一种方法。
头文件包含在源文件中,并在编译过程中被编译器引用。
通过包含头文件,可以在程序中使用头文件中定义的函数、宏和其他定义,而无需重新实现它们。
下面是`include` 的用法:1. `#include <header.h>`:这种形式的`include` 是用于引入系统的标准库头文件。
`<header.h>` 是标准库头文件的名称。
例如,`#include <stdio.h>` 用于引入标准输入输出函数库的头文件。
2. `#include "header.h"`:这种形式的`include` 是用于引入用户自定义的头文件。
`"header.h"` 是用户自定义头文件的名称。
例如,`#include "myheader.h"` 用于引入名为`myheader.h` 的用户自定义头文件。
在包含头文件之前,编译器会搜索系统的标准库和用户指定的目录来查找头文件。
通常,标准库的头文件通常在`/usr/include` 或`/usr/local/include` 等目录中,而用户自定义的头文件可以放在任何目录中。
需要注意的是,头文件在编译过程中只是一个引用,不会直接被执行,所以可以在程序文件中多次引用同一个头文件。
此外,还可以使用条件编译指令如`#ifndef` 和`#define` 来避免重复引用同一个头文件。
综上所述,`include` 用于在Linux中引入头文件以便在程序中使用预定义的函数、宏和其他定义。
打印Linux 内核task_struct (PCB )的信息的可加模块编写废话不多说,直接上源代码:这个程序是加载进内核的模块,作⽤是:打印系统中所有进程的⼀些信息,注意:这是ubuntu系统下的操作部分函数原型:#include <linux/kernel.h>#include <linux/sched.h> //这个⽂件定义了linux 下的task_struct 数据结构#include <linux/init.h>#include <linux/module.h>#include <linux/fdtable.h>#include <linux/init_task.h> //⾥⾯定义了 init_task (0号进程)//内核模块初始化函数static int __init print_pid(void ){ struct task_struct *task,*p; //指向PCB 的指针 struct list_head *pos;//list_head 是⼀个双向链表,⽤来链接os 中的所有进程,我们可以⽤它访问系统中的所有进程, \ //每个pcb 内部都维护⼀个list_head 类型的tasks 链表,这样就可以通过>每个进程的pcb 访问所有进程了int count=0;//记录当前系统中的进程数⽬ printk("Hello World enter begin:\n"); task =&init_task; //0号进程,所有进程的⽗进程,遍历进程链表list_head 从0号进程开始 //list_for_each ⽤来遍历进程链表,让pos 从头指向task 双向链表中的每⼀个结点(task_struct),list_for_each 是⼀个宏 //list.h 头⽂件中list_for_each(pos,&task->tasks) { //list_entry 是⼀个容器宏 ,作⽤是:让pos 从指向结构体task_struct 的成员tasks,变为指向结构提task_struct 本⾝,\ //由内部成员地址指向拥有该成员的结构体地址p=list_entry(pos,struct task_struct,tasks); count ++; //++ printk("\n\n"); //现在pos 指向了每⼀个进程的pcb,那么就可以输出pcb 中的信息了 printk("pid:%d; state:%lx; prio:%d; static_prio:%d; parent'pid:%d;", p->pid,p->state,p->prio,p->static_prio,(p->parent)->pid);}printk("进程的个数:%d\n",count);return 0;}//内核退出函数static void __exit pid_exit(void ){ printk("exiting...\n");}module_init(print_pid);module_exit(pid_exit);MODULE_LICENSE("GPL");/** * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. */宏,⽤来遍历head 链表,并且让pos 指向每⼀个结点#define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next)/** * list_entry - get the struct for this entry * @ptr: the &struct list_head pointer. * @type: the type of the struct this is embedded in. * @member: the name of the list_head within the struct. */2.task_struct数据结构简单介绍,信息太多了,这⾥仅仅介绍⽬前⽤的task_struc位于<linux/sched.h>头⽂件中//linux中进程的状态/* Used in tsk->state:进程的状态都是2的次幂,保证"与"操作可以得到所有状态 */#define TASK_RUNNING 0x0000#define TASK_INTERRUPTIBLE 0x0001#define TASK_UNINTERRUPTIBLE 0x0002#define __TASK_STOPPED 0x0004#define __TASK_TRACED 0x0008插⼊⼀张图⽚说明进程之间的关系,养⽗是因为⽗亲可能被杀死,或者断了,那么系统要为当前进程找⼀个养⽗进程,否则当前进程及兄弟,孩⼦进程资源⽆法释放,导致内存⽤不了了(因为指针丢了,招不到这块内存的地址了)系统中进程的组织⽅式:3.Makefile⽂件编写.c 内核正⽂⽂件ptr 表⽰member 的地址,type 表⽰结构体的类型.member 结构体中的成员#define list_entry(ptr, type, member) \ container_of(ptr, type, member)struct task_struct {#ifdef CONFIG_THREAD_INFO_IN_TASKstruct thread_info thread_info;#endif /* -1 unrunnable, 0 runnable, >0 stopped: 进程状态*/ volatile long state; /* ⽗亲进程*/ struct task_struct __rcu *real_parent;/* 养⽗进程 采⽤链表*/ struct task_struct __rcu *parent;/* * ⼦孙,兄弟,和组领导者进程,双向链表链接 */ struct list_head children; struct list_head sibling; struct task_struct *group_leader; //每个进程task_struct 内都有⼀个list_head 双向链表,⽤来链接系统中所有的进程pcb //我们可以通过它来获得系统中所有的进程信息 struct list_head tasks; //线程对应的pidpid_t pid; //线程组的pid pid_t tgid; .... //优先级 int prio; int static_prio; int normal_prio; unsigned int rt_priority; ...Makefile ⽂件⽤来编译产⽣内核.ko 模块的⽂件架构:4.编译5.插⼊内核,并显⽰结果显⽰消息:使⽤命令dmesg,这⾥只截取了部分太多了,发现我的系统⽬前有364个进程附录:完整的task_struct定义和sched.h头⽂件obj-m:=task_struct.o #产⽣task_struct 模块的⽬标⽂件#⽬标⽂件 ⽂件 要与模块⽂件名字相同CURRENT_PATH:=$(shell pwd)LINUX_KERNEL:=$(shell uname -r)LINUX_KERNEL_PATH:=/usr/src/linux-headers-$(LINUX_KERNEL)all: make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules #编译模块#[Tab] 内核的路径 当前⽬录编译完放在哪⾥ 表明编译的是内核>⽂件clean: make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean/* SPDX-License-Identifier: GPL-2.0 */#ifndef _LINUX_SCHED_H#define _LINUX_SCHED_H/** Define 'struct task_struct' and provide the main scheduler* APIs (schedule(), wakeup variants, etc.)*/#include <uapi/linux/sched.h>#include <asm/current.h>#include <linux/pid.h>#include <linux/sem.h>#include <linux/shm.h>#include <linux/kcov.h>#include <linux/mutex.h>#include <linux/plist.h>#include <linux/hrtimer.h>#include <linux/seccomp.h>#include <linux/nodemask.h>#include <linux/rcupdate.h>#include <linux/refcount.h>#include <linux/resource.h>#include <linux/latencytop.h>#include <linux/sched/prio.h>#include <linux/sched/types.h>#include <linux/signal_types.h>#include <linux/mm_types_task.h>#include <linux/task_io_accounting.h>#include <linux/posix-timers.h>#include <linux/rseq.h>/* task_struct member predeclarations (sorted alphabetically): */struct audit_context;struct backing_dev_info;struct bio_list;struct blk_plug;struct capture_control;struct cfs_rq;struct fs_struct;struct futex_pi_state;struct io_context;struct mempolicy;struct nameidata;struct nsproxy;struct perf_event_context;struct pid_namespace;struct pipe_inode_info;struct rcu_node;struct reclaim_state;struct robust_list_head;struct root_domain;struct rq;struct sched_attr;struct sched_param;struct seq_file;struct sighand_struct;struct signal_struct;struct task_delay_info;struct task_group;/** Task state bitmask. NOTE! These bits are also* encoded in fs/proc/array.c: get_task_state().** We have two separate sets of flags: task->state* is about runnability, while task->exit_state are* about the task exiting. Confusing, but this way* modifying one set can't modify the other one by* mistake.*//* Used in tsk->state:进程的状态都是2的次幂保证"与"操作可以得到所有状态 */#define TASK_RUNNING 0x0000#define TASK_INTERRUPTIBLE 0x0001#define TASK_UNINTERRUPTIBLE 0x0002#define __TASK_STOPPED 0x0004#define __TASK_TRACED 0x0008/* Used in tsk->exit_state: */#define EXIT_DEAD 0x0010#define EXIT_ZOMBIE 0x0020#define EXIT_TRACE (EXIT_ZOMBIE | EXIT_DEAD)/* Used in tsk->state again: */#define TASK_PARKED 0x0040#define TASK_DEAD 0x0080#define TASK_WAKEKILL 0x0100#define TASK_WAKING 0x0200#define TASK_NOLOAD 0x0400#define TASK_NEW 0x0800#define TASK_STATE_MAX 0x1000/* Convenience macros for the sake of set_current_state: */#define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)#define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED)#define TASK_TRACED (TASK_WAKEKILL | __TASK_TRACED)#define TASK_IDLE (TASK_UNINTERRUPTIBLE | TASK_NOLOAD)/* Convenience macros for the sake of wake_up(): */#define TASK_NORMAL (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE)/* get_task_state(): */#define TASK_REPORT (TASK_RUNNING | TASK_INTERRUPTIBLE | \TASK_UNINTERRUPTIBLE | __TASK_STOPPED | \__TASK_TRACED | EXIT_DEAD | EXIT_ZOMBIE | \TASK_PARKED)#define task_is_traced(task) ((task->state & __TASK_TRACED) != 0)#define task_is_stopped(task) ((task->state & __TASK_STOPPED) != 0)#define task_is_stopped_or_traced(task) ((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0) #define task_contributes_to_load(task) ((task->state & TASK_UNINTERRUPTIBLE) != 0 && \(task->flags & PF_FROZEN) == 0 && \(task->state & TASK_NOLOAD) == 0)#ifdef CONFIG_DEBUG_ATOMIC_SLEEP/** Special states are those that do not use the normal wait-loop pattern. See* the comment with set_special_state().*/#define is_special_task_state(state) \((state) & (__TASK_STOPPED | __TASK_TRACED | TASK_PARKED | TASK_DEAD))#define __set_current_state(state_value) \do { \WARN_ON_ONCE(is_special_task_state(state_value));\current->task_state_change = _THIS_IP_; \current->state = (state_value); \} while (0)#define set_current_state(state_value) \do { \WARN_ON_ONCE(is_special_task_state(state_value));\current->task_state_change = _THIS_IP_; \smp_store_mb(current->state, (state_value)); \} while (0)#define set_special_state(state_value) \do { \unsigned long flags; /* may shadow */ \WARN_ON_ONCE(!is_special_task_state(state_value)); \raw_spin_lock_irqsave(¤t->pi_lock, flags); \current->task_state_change = _THIS_IP_; \current->state = (state_value); \raw_spin_unlock_irqrestore(¤t->pi_lock, flags); \} while (0)#else/** set_current_state() includes a barrier so that the write of current->state* is correctly serialised wrt the caller's subsequent test of whether to* actually sleep:** for (;;) {* set_current_state(TASK_UNINTERRUPTIBLE);* if (!need_sleep)* break;** schedule();* }* __set_current_state(TASK_RUNNING);** If the caller does not need such serialisation (because, for instance, the* condition test and condition change and wakeup are under the same lock) then* use __set_current_state().** The above is typically ordered against the wakeup, which does:** need_sleep = false;* wake_up_state(p, TASK_UNINTERRUPTIBLE);** where wake_up_state() executes a full memory barrier before accessing the* task state.** Wakeup will do: if (@state & p->state) p->state = TASK_RUNNING, that is,* once it observes the TASK_UNINTERRUPTIBLE store the waking CPU can issue a * TASK_RUNNING store which can collide with __set_current_state(TASK_RUNNING). ** However, with slightly different timing the wakeup TASK_RUNNING store can* also collide with the TASK_UNINTERRUPTIBLE store. Losing that store is not* a problem either because that will result in one extra go around the loop* and our @cond test will save the day.** Also see the comments of try_to_wake_up().*/#define __set_current_state(state_value) \current->state = (state_value)#define set_current_state(state_value) \smp_store_mb(current->state, (state_value))/** set_special_state() should be used for those states when the blocking task* can not use the regular condition based wait-loop. In that case we must* serialize against wakeups such that any possible in-flight TASK_RUNNING stores* will not collide with our state change.*/#define set_special_state(state_value) \do { \unsigned long flags; /* may shadow */ \raw_spin_lock_irqsave(¤t->pi_lock, flags); \current->state = (state_value); \raw_spin_unlock_irqrestore(¤t->pi_lock, flags); \} while (0)#endif/* Task command name length: */#define TASK_COMM_LEN 16extern void scheduler_tick(void);#define MAX_SCHEDULE_TIMEOUT LONG_MAXextern long schedule_timeout(long timeout);extern long schedule_timeout_interruptible(long timeout);extern long schedule_timeout_killable(long timeout);extern long schedule_timeout_uninterruptible(long timeout);extern long schedule_timeout_idle(long timeout);asmlinkage void schedule(void);extern void schedule_preempt_disabled(void);asmlinkage void preempt_schedule_irq(void);extern int __must_check io_schedule_prepare(void);extern void io_schedule_finish(int token);extern long io_schedule_timeout(long timeout);extern void io_schedule(void);/*** struct prev_cputime - snapshot of system and user cputime* @utime: time spent in user mode* @stime: time spent in system mode* @lock: protects the above two fields** Stores previous user/system time values such that we can guarantee* monotonicity.*/struct prev_cputime {#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVEu64 utime;u64 stime;raw_spinlock_t lock;#endif};enum vtime_state {/* Task is sleeping or running in a CPU with VTIME inactive: */VTIME_INACTIVE = 0,/* Task runs in userspace in a CPU with VTIME active: */VTIME_USER,/* Task runs in kernelspace in a CPU with VTIME active: */VTIME_SYS,};struct vtime {seqcount_t seqcount;unsigned long long starttime;enum vtime_state state;u64 utime;u64 stime;u64 gtime;};/** Utilization clamp constraints.* @UCLAMP_MIN: Minimum utilization* @UCLAMP_MAX: Maximum utilization* @UCLAMP_CNT: Utilization clamp constraints count*/enum uclamp_id {UCLAMP_MIN = 0,UCLAMP_MAX,UCLAMP_CNT};#ifdef CONFIG_SMPextern struct root_domain def_root_domain;extern struct mutex sched_domains_mutex;#endifstruct sched_info {#ifdef CONFIG_SCHED_INFO/* Cumulative counters: *//* # of times we have run on this CPU: */unsigned long pcount;/* Time spent waiting on a runqueue: */unsigned long long run_delay;/* Timestamps: *//* When did we last run on a CPU? */unsigned long long last_arrival;/* When were we last queued to run? */unsigned long long last_queued;#endif /* CONFIG_SCHED_INFO */};/** Integer metrics need fixed point arithmetic, e.g., sched/fair* has a few: load, load_avg, util_avg, freq, and capacity.** We define a basic fixed point arithmetic range, and then formalize* all these metrics based on that basic range.*/# define SCHED_FIXEDPOINT_SHIFT 10# define SCHED_FIXEDPOINT_SCALE (1L << SCHED_FIXEDPOINT_SHIFT) /* Increase resolution of cpu_capacity calculations */# define SCHED_CAPACITY_SHIFT SCHED_FIXEDPOINT_SHIFT# define SCHED_CAPACITY_SCALE (1L << SCHED_CAPACITY_SHIFT) struct load_weight {unsigned long weight;u32 inv_weight;};/*** struct util_est - Estimation utilization of FAIR tasks* @enqueued: instantaneous estimated utilization of a task/cpu* @ewma: the Exponential Weighted Moving Average (EWMA)* utilization of a task** Support data structure to track an Exponential Weighted Moving Average* (EWMA) of a FAIR task's utilization. New samples are added to the moving * average each time a task completes an activation. Sample's weight is chosen * so that the EWMA will be relatively insensitive to transient changes to the* task's workload.** The enqueued attribute has a slightly different meaning for tasks and cpus: * - task: the task's util_avg at last task dequeue time* - cfs_rq: the sum of util_est.enqueued for each RUNNABLE task on that CPU * Thus, the util_est.enqueued of a task represents the contribution on the* estimated utilization of the CPU where that task is currently enqueued.** Only for tasks we track a moving average of the past instantaneous* estimated utilization. This allows to absorb sporadic drops in utilization* of an otherwise almost periodic task.*/struct util_est {unsigned int enqueued;unsigned int ewma;#define UTIL_EST_WEIGHT_SHIFT 2} __attribute__((__aligned__(sizeof(u64))));/** The load_avg/util_avg accumulates an infinite geometric series* (see __update_load_avg() in kernel/sched/fair.c).** [load_avg definition]** load_avg = runnable% * scale_load_down(load)** where runnable% is the time ratio that a sched_entity is runnable.* For cfs_rq, it is the aggregated load_avg of all runnable and* blocked sched_entities.** [util_avg definition]** util_avg = running% * SCHED_CAPACITY_SCALE** where running% is the time ratio that a sched_entity is running on* a CPU. For cfs_rq, it is the aggregated util_avg of all runnable* and blocked sched_entities.** load_avg and util_avg don't direcly factor frequency scaling and CPU* capacity scaling. The scaling is done through the rq_clock_pelt that* is used for computing those signals (see update_rq_clock_pelt())** N.B., the above ratios (runnable% and running%) themselves are in the* range of [0, 1]. To do fixed point arithmetics, we therefore scale them* to as large a range as necessary. This is for example reflected by* util_avg's SCHED_CAPACITY_SCALE.** [Overflow issue]** The 64-bit load_sum can have 4353082796 (=2^64/47742/88761) entities* with the highest load (=88761), always runnable on a single cfs_rq,* and should not overflow as the number already hits PID_MAX_LIMIT.** For all other cases (including 32-bit kernels), struct load_weight's * weight will overflow first before we do, because:** Max(load_avg) <= Max(load.weight)** Then it is the load_weight's responsibility to consider overflow* issues.*/struct sched_avg {u64 last_update_time;u64 load_sum;u64 runnable_load_sum;u32 util_sum;u32 period_contrib;unsigned long load_avg;unsigned long runnable_load_avg;unsigned long util_avg;struct util_est util_est;} ____cacheline_aligned;struct sched_statistics {#ifdef CONFIG_SCHEDSTATSu64 wait_start;u64 wait_max;u64 wait_count;u64 wait_sum;u64 iowait_count;u64 iowait_sum;u64 sleep_start;u64 sleep_max;s64 sum_sleep_runtime;u64 block_start;u64 block_max;u64 exec_max;u64 slice_max;u64 nr_migrations_cold;u64 nr_failed_migrations_affine;u64 nr_failed_migrations_running;u64 nr_failed_migrations_hot;u64 nr_forced_migrations;u64 nr_wakeups;u64 nr_wakeups_sync;u64 nr_wakeups_migrate;u64 nr_wakeups_local;u64 nr_wakeups_remote;u64 nr_wakeups_affine;u64 nr_wakeups_affine_attempts;u64 nr_wakeups_passive;u64 nr_wakeups_idle;#endif};struct sched_entity {/* For load-balancing: */struct load_weight load;unsigned long runnable_weight;struct rb_node run_node;struct list_head group_node;unsigned int on_rq;u64 exec_start;u64 sum_exec_runtime;u64 vruntime;u64 prev_sum_exec_runtime;u64 nr_migrations;struct sched_statistics statistics;#ifdef CONFIG_FAIR_GROUP_SCHEDint depth;struct sched_entity *parent;/* rq on which this entity is (to be) queued: */struct cfs_rq *cfs_rq;/* rq "owned" by this entity/group: */struct cfs_rq *my_q;#endif#ifdef CONFIG_SMP/** Per entity load average tracking.** Put into separate cache line so it does not* collide with read-mostly values above.*/struct sched_avg avg;#endif};struct sched_rt_entity {struct list_head run_list;unsigned long timeout;unsigned long watchdog_stamp;unsigned int time_slice;unsigned short on_rq;unsigned short on_list;struct sched_rt_entity *back;#ifdef CONFIG_RT_GROUP_SCHEDstruct sched_rt_entity *parent;/* rq on which this entity is (to be) queued: */struct rt_rq *rt_rq;/* rq "owned" by this entity/group: */struct rt_rq *my_q;#endif} __randomize_layout;struct sched_dl_entity {struct rb_node rb_node;/** Original scheduling parameters. Copied here from sched_attr* during sched_setattr(), they will remain the same until* the next sched_setattr().*/u64 dl_runtime; /* Maximum runtime for each instance */ u64 dl_deadline; /* Relative deadline of each instance */ u64 dl_period; /* Separation of two instances (period) */u64 dl_bw; /* dl_runtime / dl_period */u64 dl_density; /* dl_runtime / dl_deadline *//** Actual scheduling parameters. Initialized with the values above,* they are continuously updated during task execution. Note that* the remaining runtime could be < 0 in case we are in overrun.*/s64 runtime; /* Remaining runtime for this instance */u64 deadline; /* Absolute deadline for this instance */unsigned int flags; /* Specifying the scheduler behaviour */ /** Some bool flags:** @dl_throttled tells if we exhausted the runtime. If so, the* task has to wait for a replenishment to be performed at the* next firing of dl_timer.** @dl_boosted tells if we are boosted due to DI. If so we are* outside bandwidth enforcement mechanism (but only until we* exit the critical section);** @dl_yielded tells if task gave up the CPU before consuming* all its available runtime during the last job.** @dl_non_contending tells if the task is inactive while still* contributing to the active utilization. In other words, it* indicates if the inactive timer has been armed and its handler* has not been executed yet. This flag is useful to avoid race* conditions between the inactive timer handler and the wakeup* code.** @dl_overrun tells if the task asked to be informed about runtime* overruns.*/unsigned int dl_throttled : 1;unsigned int dl_boosted : 1;unsigned int dl_yielded : 1;unsigned int dl_non_contending : 1;unsigned int dl_overrun : 1;/** Bandwidth enforcement timer. Each -deadline task has its* own bandwidth to be enforced, thus we need one timer per task.*/struct hrtimer dl_timer;/** Inactive timer, responsible for decreasing the active utilization* at the "0-lag time". When a -deadline task blocks, it contributes* to GRUB's active utilization until the "0-lag time", hence a* timer is needed to decrease the active utilization at the correct* time.*/struct hrtimer inactive_timer;};#ifdef CONFIG_UCLAMP_TASK/* Number of utilization clamp buckets (shorter alias) */#define UCLAMP_BUCKETS CONFIG_UCLAMP_BUCKETS_COUNT/** Utilization clamp for a scheduling entity* @value: clamp value "assigned" to a se* @bucket_id: bucket index corresponding to the "assigned" value* @active: the se is currently refcounted in a rq's bucket* @user_defined: the requested clamp value comes from user-space** The bucket_id is the index of the clamp bucket matching the clamp value * which is pre-computed and stored to avoid expensive integer divisions from * the fast path.** The active bit is set whenever a task has got an "effective" value assigned, * which can be different from the clamp value "requested" from user-space. * This allows to know a task is refcounted in the rq's bucket corresponding * to the "effective" bucket_id.** The user_defined bit is set whenever a task has got a task-specific clamp * value requested from userspace, i.e. the system defaults apply to this task * just as a restriction. This allows to relax default clamps when a less* restrictive task-specific value has been requested, thus allowing to* implement a "nice" semantic. For example, a task running with a 20%* default boost can still drop its own boosting to 0%.*/struct uclamp_se {unsigned int value : bits_per(SCHED_CAPACITY_SCALE);unsigned int bucket_id : bits_per(UCLAMP_BUCKETS);unsigned int active : 1;#endif /* CONFIG_UCLAMP_TASK */union rcu_special {struct {u8 blocked;u8 need_qs;u8 exp_hint; /* Hint for performance. */u8 deferred_qs;} b; /* Bits. */u32 s; /* Set of bits. */};enum perf_event_task_context {perf_invalid_context = -1,perf_hw_context = 0,perf_sw_context,perf_nr_task_contexts,};struct wake_q_node {struct wake_q_node *next;};struct task_struct {#ifdef CONFIG_THREAD_INFO_IN_TASK/** For reasons of header soup (see current_thread_info()), this* must be the first element of task_struct.*/struct thread_info thread_info;#endif/* -1 unrunnable, 0 runnable, >0 stopped: */volatile long state;/** This begins the randomizable portion of task_struct. Only* scheduling-critical items should be added above here.*/randomized_struct_fields_startvoid *stack;refcount_t usage;/* Per task flags (PF_*), defined further below: */unsigned int flags;unsigned int ptrace;#ifdef CONFIG_SMPstruct llist_node wake_entry;int on_cpu;#ifdef CONFIG_THREAD_INFO_IN_TASK/* Current CPU: */unsigned int cpu;#endifunsigned int wakee_flips;unsigned long wakee_flip_decay_ts;struct task_struct *last_wakee;/** recent_used_cpu is initially set as the last CPU used by a task* that wakes affine another task. Waker/wakee relationships can* push tasks around a CPU where each wakeup moves to the next one. * Tracking a recently used CPU allows a quick search for a recently* used CPU that may be idle.*/int recent_used_cpu;int wake_cpu;#endifint on_rq;int normal_prio;unsigned int rt_priority;const struct sched_class *sched_class;struct sched_entity se;struct sched_rt_entity rt;#ifdef CONFIG_CGROUP_SCHEDstruct task_group *sched_task_group;#endifstruct sched_dl_entity dl;#ifdef CONFIG_UCLAMP_TASK/* Clamp values requested for a scheduling entity */ struct uclamp_se uclamp_req[UCLAMP_CNT];/* Effective clamp values used for a scheduling entity */ struct uclamp_se uclamp[UCLAMP_CNT];#endif#ifdef CONFIG_PREEMPT_NOTIFIERS/* List of struct preempt_notifier: */struct hlist_head preempt_notifiers;#endif#ifdef CONFIG_BLK_DEV_IO_TRACEunsigned int btrace_seq;#endifunsigned int policy;int nr_cpus_allowed;const cpumask_t *cpus_ptr;cpumask_t cpus_mask;#ifdef CONFIG_PREEMPT_RCUint rcu_read_lock_nesting;union rcu_special rcu_read_unlock_special; struct list_head rcu_node_entry;struct rcu_node *rcu_blocked_node;#endif /* #ifdef CONFIG_PREEMPT_RCU */#ifdef CONFIG_TASKS_RCUunsigned long rcu_tasks_nvcsw;u8 rcu_tasks_holdout;u8 rcu_tasks_idx;int rcu_tasks_idle_cpu;struct list_head rcu_tasks_holdout_list;#endif /* #ifdef CONFIG_TASKS_RCU */struct sched_info sched_info;struct list_head tasks;#ifdef CONFIG_SMPstruct plist_node pushable_tasks;struct rb_node pushable_dl_tasks;#endifstruct mm_struct *mm;struct mm_struct *active_mm;/* Per-thread vma caching: */struct vmacache vmacache;#ifdef SPLIT_RSS_COUNTINGstruct task_rss_stat rss_stat;#endifint exit_state;int exit_code;int exit_signal;/* The signal sent when the parent dies: */int pdeath_signal;/* Used for emulating ABI behavior of previous Linux versions: */unsigned int personality;/* Scheduler bits, serialized by scheduler locks: */unsigned sched_reset_on_fork:1;unsigned sched_contributes_to_load:1;unsigned sched_migrated:1;unsigned sched_remote_wakeup:1;#ifdef CONFIG_PSIunsigned sched_psi_wake_requeue:1;#endif/* Force alignment to the next boundary: */unsigned :0;/* Unserialized, strictly 'current' *//* Bit to tell LSMs we're in execve(): */unsigned in_execve:1;unsigned in_iowait:1;#ifndef TIF_RESTORE_SIGMASKunsigned restore_sigmask:1;#endif#ifdef CONFIG_MEMCGunsigned in_user_fault:1;#endif#ifdef CONFIG_COMPAT_BRKunsigned brk_randomized:1;#endif#ifdef CONFIG_CGROUPS/* disallow userland-initiated cgroup migration */unsigned no_cgroup_migration:1;/* task is frozen/stopped (used by the cgroup freezer) */unsigned frozen:1;#endif#ifdef CONFIG_BLK_CGROUP/* to be used once the psi infrastructure lands upstream. */unsigned use_memdelay:1;#endifunsigned long atomic_flags; /* Flags requiring atomic access. */ struct restart_block restart_block;pid_t pid;pid_t tgid;#ifdef CONFIG_STACKPROTECTOR/* Canary value for the -fstack-protector GCC feature: */unsigned long stack_canary;#endif/** Pointers to the (original) parent process, youngest child, younger sibling, * older sibling, respectively. (p->father can be replaced with* p->real_parent->pid)*//* Real parent process: */struct task_struct __rcu *real_parent;/* Recipient of SIGCHLD, wait4() reports: */struct task_struct __rcu *parent;/** Children/sibling form the list of natural children:*/struct list_head children;struct list_head sibling;。
/** include/linux/schedh**/#ifndef _LINUX_SCHED_H#define _LINUX_SCHED_H#include <asm/param.h> /* for HZ */extern unsigned long event;#include <linux/config.h>#include <linux/binfmts.h>#include <linux/threads.h>#include <linux/kernel.h>#include <linux/types.h>#include <linux/times.h>#include <linux/timex.h>#include <linux/rbtree.h>#include <asm/system.h>#include <asm/semaphore.h>#include <asm/page.h>#include <asm/ptrace.h>#include <asm/mmu.h>#include <linux/smp.h>#include <linux/tty.h>#include <linux/sem.h>#include <linux/signal.h>#include <linux/securebits.h>#include <linux/fs_struct.h>#include <linux/low-latency.h>struct exec_domain;/** cloning flags:*/#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */#define CLONE_VM 0x00000100 /* set if VM shared between processes */#define CLONE_FS 0x00000200 /* set if fs info shared between processes */#define CLONE_FILES 0x00000400 /* set if open files shared between processes */#define CLONE_SIGHAND 0x00000800 /* set if signal handlers and blocked signals shared */#define CLONE_PID 0x00001000 /* set if pid shared */#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */#define CLONE_THREAD 0x00010000 /* Same thread group? */#define CLONE_NEWNS 0x00020000 /* New namespace group? */#define CLONE_SIGNAL (CLONE_SIGHAND | CLONE_THREAD)/** These are the constant used to fake the fixed-point load-average* counting. Some notes:* - 11 bit fractions expand to 22 bits by the multiplies: this gives* a load-average precision of 10 bits integer + 11 bits fractional* - if you want to count load-averages more often, you need more* precision, or rounding will get you. With 2-second counting freq,* the EXP_n values would be 1981, 2034 and 2043 if still using only* 11 bit fractions.*/extern unsigned long avenrun[]; /* Load averages */#define FSHIFT 11 /* nr of bits of precision */#define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */#define LOAD_FREQ (5*HZ) /* 5 sec intervals */#define EXP_1 1884 /* 1/exp(5sec/1min) as fixed-point */#define EXP_5 2014 /* 1/exp(5sec/5min) */#define EXP_15 2037 /* 1/exp(5sec/15min) */#define CALC_LOAD(load,exp,n) \load *= exp; \load += n*(FIXED_1-exp); \load >>= FSHIFT;#define CT_TO_SECS(x) ((x) / HZ)#define CT_TO_USECS(x) (((x) % HZ) * 1000000/HZ)extern int nr_threads;extern int last_pid;extern unsigned long nr_running(void);extern unsigned long nr_uninterruptible(void);#include <linux/fs.h>#include <linux/time.h>#include <linux/param.h>#include <linux/resource.h>#include <linux/timer.h>#include <asm/processor.h>//进程状态#define TASK_RUNNING 0#define TASK_INTERRUPTIBLE 1#define TASK_UNINTERRUPTIBLE 2#define TASK_ZOMBIE 4#define TASK_STOPPED 8#define __set_task_state(tsk, state_value) \ do { (tsk)->state = (state_value); } while (0)#ifdef CONFIG_SMP#define set_task_state(tsk, state_value) \ set_mb((tsk)->state, (state_value))#else#define set_task_state(tsk, state_value) \ __set_task_state((tsk), (state_value))#endif#define __set_current_state(state_value) \ do { current->state = (state_value); } while (0) #ifdef CONFIG_SMP#define set_current_state(state_value) \ set_mb(current->state, (state_value))#else#define set_current_state(state_value) \ __set_current_state(state_value)#endif/** Scheduling policies*/#define SCHED_OTHER 0#define SCHED_FIFO 1#define SCHED_RR 2struct sched_param {int sched_priority;};struct completion;#ifdef __KERNEL__#include <linux/spinlock.h>/** This serializes "schedule()" and also protects* the run-queue from deletions/modifications (but* _adding_ to the beginning of the run-queue has* a separate lock).*/extern rwlock_t tasklist_lock;extern spinlock_t mmlist_lock;typedef struct task_struct task_t; //将task_t定义为task_sturct的结构类型extern void sched_init(void);extern void init_idle(task_t *idle, int cpu);extern void show_state(void);extern void show_stack(unsigned long * esp);extern void cpu_init (void);extern void trap_init(void);extern void update_process_times(int user);extern void update_one_process(task_t *p, unsigned long user,unsigned long system, int cpu);extern void scheduler_tick(int user_tick, int system);extern void migration_init(void);extern unsigned long cache_decay_ticks;extern int set_user(uid_t new_ruid, int dumpclear);#define MAX_SCHEDULE_TIMEOUT LONG_MAXextern signed long FASTCALL(schedule_timeout(signed long timeout)); asmlinkage void schedule(void);extern int schedule_task(struct tq_struct *task);extern void flush_scheduled_tasks(void);extern int start_context_thread(void);extern int current_is_keventd(void);/*优先级* Priority of a process goes from 0..MAX_PRIO-1, valid RT* priority is 0..MAX_RT_PRIO-1, and SCHED_OTHER tasks are* in the range MAX_RT_PRIO..MAX_PRIO-1. Priority values* are inverted: lower p->prio value means higher priority.** The MAX_RT_USER_PRIO value allows the actual maximum* RT priority to be separate from the value exported to* user-space. This allows kernel threads to set their* priority to a value higher than any user task. Note:* MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO.*/#define MAX_USER_RT_PRIO 100#define MAX_RT_PRIO MAX_USER_RT_PRIO#define MAX_PRIO (MAX_RT_PRIO + 40)/** The maximum RT priority is configurable. If the resulting* bitmap is 160-bits , we can use a hand-coded routine which* is optimal. Otherwise, we fall back on a generic routine for* finding the first set bit from an arbitrarily-sized bitmap.*/#if MAX_PRIO < 160 && MAX_PRIO > 127#define sched_find_first_bit(map) _sched_find_first_bit(map)#else#define sched_find_first_bit(map) find_first_bit(map, MAX_PRIO)#endif/** The default fd array needs to be at least BITS_PER_LONG,* as this is the granularity returned by copy_fdset().*/#define NR_OPEN_DEFAULT BITS_PER_LONGstruct namespace;/*文件系统数据结构* Open file table structure*/struct files_struct {atomic_t count;rwlock_t file_lock; /* Protects all the below members. Nests inside tsk->alloc_lock */int max_fds;int max_fdset;int next_fd;struct file ** fd; /* current fd array */fd_set *close_on_exec;fd_set *open_fds;fd_set close_on_exec_init;fd_set open_fds_init;struct file * fd_array[NR_OPEN_DEFAULT];};#define INIT_FILES \{ \count: ATOMIC_INIT(1), \file_lock: RW_LOCK_UNLOCKED, \max_fds: NR_OPEN_DEFAULT, \max_fdset: __FD_SETSIZE, \next_fd: 0, \fd: &init_files.fd_array[0], \close_on_exec: &init_files.close_on_exec_init, \open_fds: &init_files.open_fds_init, \close_on_exec_init: { { 0, } }, \open_fds_init: { { 0, } }, \fd_array: { NULL, } \}/* Maximum number of active map areas.. This is a random (large) number */#define DEFAULT_MAX_MAP_COUNT (65536)extern int max_map_count;//存储管理数据结构struct mm_struct {struct vm_area_struct * mmap; /* list of VMAs */rb_root_t mm_rb;struct vm_area_struct * mmap_cache; /* last find_vma result */pgd_t * pgd;atomic_t mm_users; /* How many users with user space? */atomic_t mm_count; /* How many references to "struct mm_struct" (users count as 1) */int map_count; /* number of VMAs */struct rw_semaphore mmap_sem;spinlock_t page_table_lock; /* Protects task page tables and mm->rss */struct list_head mmlist; /* List of all active mm's. These are globally strung* together off init_mm.mmlist, and are protected* by mmlist_lock*/unsigned long start_code, end_code, start_data, end_data;unsigned long start_brk, brk, start_stack;unsigned long arg_start, arg_end, env_start, env_end;unsigned long rss, total_vm, locked_vm;unsigned long def_flags;unsigned long cpu_vm_mask;unsigned long rlimit_rss;unsigned dumpable:1;/* Architecture-specific MM context */mm_context_t context;};//结束存储管理数据结构定义extern int mmlist_nr;#define INIT_MM(name) \{ \mm_rb: RB_ROOT, \pgd: swapper_pg_dir, \mm_users: ATOMIC_INIT(2), \mm_count: ATOMIC_INIT(1), \mmap_sem: __RWSEM_INITIALIZER(name.mmap_sem), \page_table_lock: SPIN_LOCK_UNLOCKED, \mmlist: LIST_HEAD_INIT(name.mmlist), \rlimit_rss: RLIM_INFINITY, \}//信号数据结构struct signal_struct {atomic_t count;struct k_sigaction action[_NSIG];spinlock_t siglock;};#define INIT_SIGNALS { \count: ATOMIC_INIT(1), \action: { {{0,}}, }, \siglock: SPIN_LOCK_UNLOCKED \}/* user结构定义* Some day this will be a full-fledged user tracking system..*/struct user_struct {atomic_t __count; /* reference count */atomic_t processes; /* How many processes does this user have? */ atomic_t files; /* How many open files does this user have? *//* Hash table maintenance information */struct user_struct *next, **pprev;uid_t uid;};#define get_current_user() ({ \struct user_struct *__user = current->user; \atomic_inc(&__user->__count); \__user; })extern struct user_struct root_user;#define INIT_USER (&root_user)typedef struct prio_array prio_array_t;//进程控制块struct task_struct {/** offsets of these are hardcoded elsewhere - touch with care*/volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ unsigned long flags; /* per process flags, defined below */int sigpending;//虚拟地址空间上限mm_segment_t addr_limit; /* thread address space:0-0xBFFFFFFF for user-thead0-0xFFFFFFFF for kernel-thread*///指向本进程所述执行域的数据结构。