FreeBSD 4.5 进程调度

来源:互联网 发布:疯狂联盟升级数据 编辑:程序博客网 时间:2024/06/03 22:53

FreeBSD 4.5  使用分时调度算法:分配时间配额。


调度算法基于多级反馈队列。

系统会动态的调整线程的优先级, 反映出资源需求和线程消耗的资源量。系统根据线程优先级的变化在运行队列之间移动。


运行队列:系统维护三个运行队列, 分别管理实时进程, 普通进程, IDEL 进程


队列结构:

每个运行队列按优先级分为32(NQS) 个运行链, 运行链内的线程不再按优先级排序



队列的定义:

src/sys/kern/kern_switch.c/* * We have NQS (32) run queues per scheduling class.  For the normal * class, there are 128 priorities scaled onto these 32 queues.  New * processes are added to the last entry in each queue, and processes * are selected for running by taking them from the head and maintaining * a simple FIFO arrangement.  Realtime and Idle priority processes have * and explicit 0-31 priority which maps directly onto their class queue * index.  When a queue has something in it, the corresponding bit is * set in the queuebits variable, allowing a single read to determine * the state of all 32 queues and then a ffs() to find the first busy * queue. */struct rq queues[NQS];struct rq rtqueues[NQS];struct rq idqueues[NQS];u_int32_t queuebits;u_int32_t rtqueuebits;u_int32_t idqueuebits;

程序类型和优先级关系:



动态调整程序优先级接口:



schedcpu()

callout, 每秒运行一次,遍历系统所有进程, 重新计算进程优先级, 更新睡眠进程的睡眠时间(p_slptime) 等。


roundrobin()

callout, 每秒运行10次(也就是说每个程序的运行时间片是10个ticks), 当CPU空闲或者当前进程不是实时进程的时候, 发送AST信号。userret()函数检查到这个信号则调mi_switch()函数抢占当前进程。从这里可以看出4BSD的进程间的抢占只发生在CPU从内核态退出到用户态的时候, 当然,sleep()函数也会发生主动的进程切换,最终也是调用mi_switch() 函数。

astpending = AST_RESCHED|AST_PENDING;

mi_switch()

执行进程切换, 最终调用由汇编实现的cpu_switch()执行与硬件相关的代码。switchticks记录了最近一次进程切换的时间, 但是似乎没有记录从idle_loop()函数发起的进程切换时间。

chooseproc()

由cpu_switch()或idle_loop()调用, 从前面提到的多级反馈队列中选择最高优先级的进程运行。