当前位置: 首页 > news >正文

外贸网站seo教程建站备案

外贸网站seo教程,建站备案,昆明网络推广方式有哪些,虾皮跨境电商平台入驻Linux-0.11 kernel目录进程管理sched.c详解 sched.c主要功能是负责进程的调度#xff0c;其最核心的函数就是schedule。除schedule以外#xff0c; sleep_on和wake_up也是相对重要的函数。 schedule void schedule(void)schedule函数的基本功能可以分为两大块#xff0c;…Linux-0.11 kernel目录进程管理sched.c详解 sched.c主要功能是负责进程的调度其最核心的函数就是schedule。除schedule以外 sleep_on和wake_up也是相对重要的函数。 schedule void schedule(void)schedule函数的基本功能可以分为两大块 第一块是检查task中的报警信息和信号 第二块则是进行任务的调度。 在第一块中首先从任务数组的尾部任务开始检查alarm是否小于当前系统滴答值如果小于则代表alarm时间已经到期。将进程的signal中的SIGALARM位置1。 接着就看如果检查进程的信号中如果处理BLOCK位以外还有别的信号并且如果任务处于可中断状态则将任务置为就绪状态。 int i,next,c; struct task_struct ** p;for(p LAST_TASK ; p FIRST_TASK ; --p)if (*p) {if ((*p)-alarm (*p)-alarm jiffies) { //如果设置了任务定时的值alarm 并且已经过期(*p)-signal | (1(SIGALRM-1)); //将信号的SIGALARM位置为1(*p)-alarm 0;}if (((*p)-signal ~(_BLOCKABLE (*p)-blocked)) (*p)-stateTASK_INTERRUPTIBLE)//如果信号位图中除了被阻塞的信号外还有其他信号 并且任务处于可中断状态(*p)-stateTASK_RUNNING; //修改任务的状态为就绪态}第二块的代码就是任务调度的核心代码。 这里会从任务数组的尾部任务开始进行遍历从所有任务从选取counter值最大的任务作为下一个运行的任务去执行。 while (1) {c -1;next 0;i NR_TASKS;p task[NR_TASKS];//从最后一个任务开始while (--i) { //遍历所有的task 取出其中counter最大的taskif (!*--p)continue;if ((*p)-state TASK_RUNNING (*p)-counter c)//取出所有任务中counter值最大的任务作为下一个任务c (*p)-counter, next i;}if (c) break;//如果当前没有RUNNING状态的任务的counter可以大于-1那么则去更新counter的值counter counter/2 priorityfor(p LAST_TASK ; p FIRST_TASK ; --p)if (*p)(*p)-counter ((*p)-counter 1) (*p)-priority;//更新counter值 counter counter/2 priority } //切换任务执行next switch_to(next);show_task void show_task(int nr,struct task_struct * p)该函数的作用是显示任务序号为nr的进程的pid进程状态以及内核栈剩余的大小。 int i,j 4096-sizeof(struct task_struct);printk(%d: pid%d, state%d, ,nr,p-pid,p-state); i0;此时j指向PCB所在内存页的顶部 i指向task_struct结构体的下一个字节。下面这段代码的所用实际就是统计内核栈中空闲大小。 while (ij !((char *)(p1))[i])i; printk(%d (of %d) chars free in kernel stack\n\r,i,j);show_stat void show_stat(void)该函数内部调用show_task函数实际上就是遍历task数组 调用show_stat函数显示进程相关信息。 int i;for (i0;iNR_TASKS;i)//遍历task数组if (task[i])show_task(i,task[i]);//调用show_taskmath_state_restore void math_state_restore()该函数的作用是将当前协处理器内容保存到老协处理器状态数组中并将当前任务的协处理器内容加载进协处理器。 sys_pause int sys_pause(void)该函数是pause的系统调用。该函数会将当前任务的状态修改为可中断的状态 并调用schedule函数去进行进程的调度。 调用pause函数的进程会进入睡眠状态 直到收到一个信号。 current-state TASK_INTERRUPTIBLE; schedule();sleep_on void sleep_on(struct task_struct **p)该函数的作用是将当前的task置为不可中断的等待状态 直到被wake_up唤醒再继续执行。入参p是等待任务队列的头指针。通过p指针和tmp变量将等待的任务串在了一起。 该函数首先对一些异常情况进行了处理他 例如p是空指针。或者当前task是任务0。 struct task_struct *tmp;// 若指针无效则退出。指针所指的对象可以是NULL但指针本身不会为0)。 if (!p)return; if (current (init_task.task)) // 如果当前任务是任务0则死机(impossible!)。panic (task[0] trying to sleep);接着让当前等待任务的头指针指向当前任务。并将当前任务修改为不可中断的等待状态。进行调用schedule函数让操作系统切换其他任务执行。 tmp *p; *p current; current-state TASK_UNINTERRUPTIBLE; schedule(); 当程序从schedule()返回继续执行时说明任务已经被显式的wake_up如果此时还有其他进程仍然在等待那么也一同唤醒。 因为任务都在等待同样的资源 那么当资源可用的时候 就可以唤醒所有等待的任务。 if (tmp) // 若还存在等待的任务则也将其置为就绪状态唤醒。tmp-state 0;interruptible_sleep_on void interruptible_sleep_on (struct task_struct **p)该函数与sleep_on类似但是该函数会将任务的状态修改为可中断的等待状态 而sleep_on则是将任务修改为不可中断的等待状态。因此通过interruptible_sleep_on而等待的task是可以被信号唤醒的。 而通过sleep_on而等待的task是不会被信号唤醒的只能通过wake_up函数唤醒。 下面这段代码与sleep_on并无太大区别 只是将进程的状态修改为可中断的等待状态。 struct task_struct *tmp;if (!p)return;if (current (init_task.task))panic (task[0] trying to sleep);tmp *p;*p current; repeat:current-state TASK_INTERRUPTIBLE;schedule ();由于任务是可以被信号唤醒的因此下面需要判断唤醒的任务是否是等待任务队列的头节点。如果不是则需要等待其他任务。 if (*p *p ! current) {(**p).state 0;goto repeat; }下面一句代码有误应该是*p tmp让队列头指针指向其余等待任务否则在当前任务之前插入 等待队列的任务均被抹掉了 *p NULL; if (tmp)tmp-state 0;wake_up void wake_up(struct task_struct **p)该函数的作用就是唤醒某一个任务。其用于唤醒p指向的等待队列中的任务。 if (p *p) {(**p).state 0; // 置为就绪可运行状态。*p NULL; }ticks_to_floppy_on int ticks_to_floppy_on(unsigned int nr)该函数指定软盘到正常运转状态所需延迟滴答数时间。 floppy_on void floppy_on(unsigned int nr)该函数等待指定软驱马达启动所需时间。 floppy_off void floppy_off(unsigned int nr)关闭相应的软驱马达停转定时器3s。 moff_timer[nr]3*HZ;do_floppy_timer void do_floppy_timer(void)如果马达启动定时到则唤醒进程。 if (mon_timer[i]) {if (!--mon_timer[i])wake_up(iwait_motor);如果马达停转定时到期则复位相应马达启动位并更新数字输出到寄存器。 else if (!moff_timer[i]) {current_DOR ~mask;outb(current_DOR,FD_DOR);add_timer add_timer(long jiffies, void (*fn)(void)) 、 该函数的作用是设置定时值和相应的处理函数。如果定时的值小于0 那么立即调用处理函数。 c if (jiffies 0)(fn)();如果定时的值大于0 那么首先取timer_list数组中寻找一个位置将该位置上的滴答数设置为jiffies将该位置上的fn设置为入参fn。并让next_timer指向它。 for (p timer_list ; p timer_list TIME_REQUESTS ; p)if (!p-fn)break; if (p timer_list TIME_REQUESTS)panic(No more time requests free); p-fn fn; p-jiffies jiffies; p-next next_timer; next_timer p;下面这段代码的作用是将刚刚插入链表中的timer移动的合适的位置。 由于next_timer这个链表上的jiffies是一个相对值即相对于前面一个timer还有多久到期。因此上面步骤的timer也需要进行转换。 while (p-next p-next-jiffies p-jiffies) {p-jiffies - p-next-jiffies;//减去下一个timer的jiffiesfn p-fn;//将当前的fn保存给临时变量p-fn p-next-fn;//将当前的fn设置为下一个timer的fnp-next-fn fn;//将下一个timer的fn设置为临时变量fnjiffies p-jiffies;//将jiffies保存给一个临时变量p-jiffies p-next-jiffies;//将当前的jiffies设置为下一个timer的jiffiesp-next-jiffies jiffies;//将下一个timer的jiffies设置为当前的jiffiesp p-next;//这一步骤实际上将p向后挪动到合适的位置 并把jiffies转化成相对值。 }do_timer void do_timer(long cpl)该函数是时钟中断的处理函数。其在system_call.s中的timer_interrupt函数中被调用。 参数cpl表示的是当前的特权级 0表示时钟中断发生时当前运行在内核态3表示时钟中断发生时当前运行在用户态。 下面的代码根据cpl的值将进程PCB中的utime和stime进行修改。如果cpl为0则增加stime(supervisor time) 如果cpl为3 则增加utime。 if (cpl)current-utime; elsecurrent-stime;下面对定时器的链表进行遍历。 将链表的第一个定时器的滴答数减1。如果滴答数已经等于0 代表该定时器已经到期那么需要调用相应的处理程序进行处理。 if (next_timer) {next_timer-jiffies--;while (next_timer next_timer-jiffies 0) {void (*fn)(void);fn next_timer-fn;next_timer-fn NULL;next_timer next_timer-next;(fn)();} }下面代码则是将当前运行的进程的时间片减去1如果此时进程时间片没有用完该函数则返回。 如果此时进程时间已经用完则将时间片设置为0。并且如果此时cpl表明中断发生用户态那么还将会触发进程的调度。 if ((--current-counter)0) return; current-counter0;sys_alarm int sys_alarm(long seconds)该函数用于设置报警值。 jiffies是指的是系统开机到目前经历的滴答数。 current-alarm的单位也是系统滴答数。 因此(current-alarm - jiffies) /100 就代表就是当前的定时器还剩下多少秒。 而设置alarm值则需要加上系统当前的滴答数据jiffies 如下图所示: sys_getpid int sys_getpid(void)该函数用于获取进程的pid。 sys_getppid int sys_getppid(void)该函数用于获取父进程的pid。 sys_getuid int sys_getuid(void)该函数用于获取用户的uid。 sys_geteuid int sys_geteuid(void)该函数用于获取用户的有效id(euid)。 sys_getgid int sys_getgid(void)获取组和id号(gid)。 sys_getegid int sys_getegid(void)取有效的组id(egid) sys_nice int sys_nice(long increment)该函数的作用是降低进程在调度时的优先级。 sched_init void sched_init(void)该函数的作用是初始化进程调度模块。 首先在gdt表中设置任务0的tss和ldt值。接着对其他任务的tss和ldt进行初始化。 set_tss_desc(gdtFIRST_TSS_ENTRY,(init_task.task.tss)); set_ldt_desc(gdtFIRST_LDT_ENTRY,(init_task.task.ldt)); p gdt2FIRST_TSS_ENTRY; for(i1;iNR_TASKS;i) {task[i] NULL;p-ap-b0;p;p-ap-b0;p; }显式地将任务0的tss加载到寄存器tr中 显式地将任务0的ldt加载到ldtr中。 ltr(0); lldt(0);下面的代码用于初始化8253定时器。通道0选择工作方式3二进制计数方式。 outb_p(0x36,0x43); /* binary, mode 3, LSB/MSB, ch 0 */ outb_p(LATCH 0xff , 0x40); /* LSB */ outb(LATCH 8 , 0x40); /* MSB */设置时钟中断处理程序的处理函数 设置系统调用的中断处理函数。 set_intr_gate(0x20,timer_interrupt); outb(inb_p(0x21)~0x01,0x21); set_system_gate(0x80,system_call);
http://www.w-s-a.com/news/357091/

相关文章:

  • 嘉兴seo网站推广中山建网站多少钱
  • 高端汽车网站建设帮别人做网站自己为什么会被抓
  • 网站开发实验室建设方案wordpress 主题丢失
  • 珠宝网站建设平台分析报告郑州最新发布
  • 世界杯最新排名泉州seo网站关键词优
  • 广州公司网站提供如何推广新品
  • 网站建设如何描述沈阳网站建设推广平台
  • 用dw制作个介绍家乡网站学生个人简历
  • 建设银行企业网站访问不了wordpress搬到谷歌服务器
  • 网站建设与网站优化销售别墅庭院园林景观设计公司
  • 沈阳红方城网站建设专业的微网站哪家好
  • 医院网站asp东营信息发布平台
  • 网站全站建设开题报告范文南京本地网站
  • 网站漏洞扫描工具wampserver集成环境搭建了一个织梦cms网站
  • 如何在局域网上做网站宁波设计公司排行榜
  • 自己的电脑做网站服务器吗百度搜索风云榜总榜
  • 做化妆品的一些网站企业网站建设与营运计划书
  • 重庆速代网络科技seo整站优化服务教程
  • 成都比较好的装修设计公司seo3的空间构型
  • 开发商建设审批网站成都创意设计公司
  • 百度快照比网站上线时间早wordpress新建阅读量字段
  • 国家工程建设标准化协会网站网站开发工具有
  • 上海网站建设集中公关公司组织架构图
  • wordpress副标题的作用百度网站标题优化
  • 大连哪家公司做网站比较好wordpress 判断用户组
  • 网站空间1g多少钱东莞公司高端网站建设
  • 网站服务器出错是什么意思做餐饮酒店网站
  • 房地产网站建设策划方案网站建设教程简笔画
  • 3d室内设计软件wordpress本地优化加速版
  • 南京高新区规划建设局网站石家庄哪里做网站比较好