gpt4 book ai didi

c - 修改 Minix 3 调度器

转载 作者:行者123 更新时间:2023-12-04 07:54:29 31 4
gpt4 key购买 nike

我最近购买了这本书以更好地了解操作系统的工作原理。我在第二章,我被困在这个问题上,我的操作系统无法使用我添加的代码启动。下面的代码在 pic_proc 函数开始时添加到 proc.c 以尝试修改调度程序。
修改。

int realtime;
clock_t recent_time[NR_TASKS + NR_PROCS];
clock_t stopwatch;

realtime = getuptime();
recent_time[proc_ptr->p_nr + NR_TASKS] = realtime - stopwatch;
stopwatch = realtime;
原始代码:
    PRIVATE void pick_proc()
{
register struct proc *rp; /* process to run */
int q; /* iterate over queues */

/* Modified Code here */

for (q=0; q < NR_SCHED_QUEUES; q++) {
if ( (rp = rdy_head[q]) != NIL_PROC) {
next_ptr = rp;
if (priv(rp)->s_flags & BILLABLE)
bill_ptr = rp;
return;
}
}
}
图书操作系统设计和实现。第 3 版 Minix 书,P219,#45。
修改 Minix 3 调度程序以跟踪每个用户进程最近有多少 CPU 时间。当没有任务或服务器要运行时,选择具有最小 CPU 份额的用户进程。
Enqueue Code
Sched part 1
Sched part 2

最佳答案

基于您的新代码 [和 pick_proc函数体],唯一可能的失败是我在上面的评论中描述的失败。
即,proc_ptr必须有效(即非 NULL)和 proc_ptr->p_nr必须在范围内以防止 UB。
什么是NR_TASKSNR_PROCS值(value)观?可以 recent_time适合堆栈?内核中的堆栈大小通常非常有限。例如,在 linux 下,您只能拥有大约 4KB 的堆栈。
所以,如果 NR_PROCS是(例如)32767,然后是 recent_time无法放入堆栈。
而且,我没有看到在堆栈上有一个独立数组的原因,因为它不会在调用后持续存在。
因此,为了帮助调试,我会添加 staticrecent_time定义
您需要添加一些调试代码以查看问题所在。
这是一个示例。调整 printf等。阿尔。适合minux内核的打印机制[假设您可以在调用代码的状态下打印]:

#ifdef DEBUG
#define dbgprt(_fmt...) \
printf(_fmt)
#else
#define dbgprt(_fmt...) \
do { } while (0)
#endif

PRIVATE void
pick_proc()
{
register struct proc *rp; /* process to run */
int q; /* iterate over queues */

/* Modified Code here */
int realtime;
static clock_t recent_time[NR_TASKS + NR_PROCS];
clock_t stopwatch;
do {
// bad pointer
dbgprt("pick_proc: proc_ptr=%p\n",proc_ptr);
if (proc_ptr == NULL)
break;

// out of range process number
dbgprt("pick_proc: p_nr=%u\n",proc_ptr->p_nr);
if (proc_ptr->p_nr >= NR_PROCS)
break;

realtime = getuptime();
dbgprt("pick_proc: realtime=%d\n",realtime);
recent_time[proc_ptr->p_nr + NR_TASKS] = realtime - stopwatch;
stopwatch = realtime;
} while (0);

for (q = 0; q < NR_SCHED_QUEUES; q++) {
if ((rp = rdy_head[q]) != NIL_PROC) {
next_ptr = rp;
if (priv(rp)->s_flags & BILLABLE)
bill_ptr = rp;
return;
}
}
}

更新:
我怎么强调 assert 的重要性都不为过。和/或 if声明来预先验证您为防止 UB 所做的任何事情。并且,调试 printf , 如:
TRACE(VF_PICKPROC,printf("hello world\n"););
顺便说一句,我拉了 minix来自github的源代码:
git 克隆 https://github.com/Stichting-MINIX-Research-Foundation/minix.git
看来您的源可能已经过时了,因为 pick_proc在那个 repo 中有更多与 SMP 相关的代码。

The NR_TASKS + NR_PROCS should be the time quanta taken from the process table. I orginally declared the Array and stopwatch in proc.h but the pic_proc function did not have access to them.


您真的想使用 struct proc 中的现有字段或者添加一些你自己的,而不是创建一个单独的数组 [按进程号索引]。

I added some screen shots of code that calls pic_proc. I think i need to modify sched and leave pic_proc alone. The array in pic_proc should be getting the time quanta from each process from the process table


是的,希望每个进程的 CPU 时间都在 struct proc .如果没有,则必须添加一个字段。我怀疑 p_user_time [和/或 p_sys_time ] 可能就是你想要的。而且,也许, p_cpu_time_left .其他可能性: p_accounting.time_in_queue .或者, p_cycles pick_proc只查看给定运行队列的头部。因此,您可能需要更改实际将给定进程插入该队列的代码。那可能是 enqueue和/或 dequeue .它们似乎尊重进程优先级 [ p_priority ] 和抢占。
我浏览了内核代码,猜测是 sched_proc可能会感兴趣。
但是,我真的认为您需要更仔细地检查内核代码,以了解哪些函数实际上将进程添加到给定的运行队列。并且,他们如何选择进程以及从哪个队列中选择。
添加进程时,它可能只是附加到尾部。该代码需要扫描队列并[假设优先级相同],根据最低 CPU 使用率插入。

关于c - 修改 Minix 3 调度器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66771100/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com