|
这是我们的os试验课程,要求修改调度算法,我想实现一种较为低级的fair-share算法,主要思想是将进程按用户分组,初始化时每个用户分得同样的时间片,在每次调度时算出当前优先的用户,在选择runlist中的进程时只考虑优先用户的进程.另外,我考虑root用户由于特殊地位,其将不参与用户之间的公平调度.具体实现见下:
linux 2.4.20/include/linux/sched.h########################################
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;
unsigned long user_ticks; /*这时我添加的,用来纪录当前用户的时间片*/
####################################################################
linux 2.4.20/kernel/user.c###############################################
struct user_struct root_user = {
__count: ATOMIC_INIT(1),
processes: ATOMIC_INIT(1),
files: ATOMIC_INIT(0),
user_ticks: -1 /*root用户不参与公平调度,将其user_ticks初 *始化为-1 */
};
struct user_struct * alloc_uid(uid_t uid)
{
………………………………………
if (!up) {
struct user_struct *new;
new = kmem_cache_alloc(uid_cachep, SLAB_KERNEL);
if (!new)
return NULL;
new->uid = uid;
atomic_set(&new->__count, 1);
atomic_set(&new->processes, 0);
atomic_set(&new->files, 0);
new->user_ticks = 50; /*每个用户初始化为50*/
…………………………………………
}
####################################################################
linux 2.4.20/kernel/sched.c##############################################
/*这是我添加的函数,功能是返回除root用户外最优用户的uid*/
static inline int pick_user(struct user_struct *root)
{
int max_ticks, uid;
struct user_struct *next;
max_ticks = root->user_ticks;
uid = root->uid;
if (root->next != NULL) {
repick: for (next = root->next ; next != root ; next = next->next) {
if (next->user_ticks > max_ticks) {
uid = next->uid;
max_ticks = next->user_ticks;
}
}
if (max_ticks <= 0) {
for (next = root->next ; next != root ; next = next->next)
next->user_ticks = 50;
root->user_ticks = -1;
goto repick;
}
}
return uid;
}
asmlinkage void schedule(void)
{
static unsigned long lastcount; /*静态局部变量用来纪录上次运行进程的counter值*/
…………………………………………
need_resched_back:
prev = current;
this_cpu = prev->processor;
if (prev->uid != root_user.uid)
prev->user->user_ticks -= lastcount - prev->counter ; /*若上次运行的进程不是root用户所属进程(即是参与公平调度的进程),则其用户时间片减去该进程所消耗的时间*/
…………………………………………
repeat_schedule:
/*
* Default process to select..
*/
next = idle_task(this_cpu);
c = -1000;
int prior_user_id = pick_user(&root_user);/*调用pick_user返回优先用户id*/
list_for_each(tmp, &runqueue_head) {
p = list_entry(tmp, struct task_struct, run_list);
if (can_schedule(p, this_cpu)) {
int weight = goodness(p, this_cpu, prev->active_mm);
/*若p进程uid不是优先用户id并且不是root用户id,则continue;跳过weight和c的比较,上面有一个条件符合该进程就参与此次调度*/
if ((p->uid != prior_user_id) && (p->uid != root_user.uid)) continue;
if (weight > c)
c = weight, next = p;
}
}
lastcount = next->counter; /*记下取得运行权的进程当前的counter*/
…………………………………………
}
#####################################################################
以上编译通过,系统的初始化也顺利,可是在启动sm-client时却停住了,而前面的sentmail 正常.我关掉sentmail后所有服务都启动了,包括proftpd,xfs等非root用户进程,可是这次又卡在了xwindows上,具体症状是:字符界面一闪而过,然后一阵黑屏,接着又是字符界面一闪,再次黑屏,如此循环.
本人接触linux不足一月,内核代码看得太朦胧,而且仅限于调度算法相关的部分,以上的代码可能比较幼稚简单,但是我觉得运行应该是通过的,我对kde初始化涉及到的一些进程的情况一无所知,所以实在不知道问题出在什么地方,请各位高手帮忙看看,多谢了.
:help |
|