finish exec4.7-9
This commit is contained in:
parent
4e78127811
commit
64e90d6037
@ -13,4 +13,4 @@ define add-symbol-file-auto
|
||||
end
|
||||
|
||||
add-symbol-file-auto ./build/kernel.img
|
||||
add-symbol-file-auto ./user/build/ramdisk/testpf.bin
|
||||
add-symbol-file-auto ./user/build/ramdisk/yield_single.bin
|
||||
|
@ -80,6 +80,11 @@ void handle_entry_c(int type, u64 esr, u64 address)
|
||||
case ESR_EL1_EC_DABT_CEL:
|
||||
do_page_fault(esr, address);
|
||||
break;
|
||||
case ESR_EL1_EC_IABT_LEL:
|
||||
// 线程退出
|
||||
if (address == 0x0) {
|
||||
sys_exit(0);
|
||||
}
|
||||
default:
|
||||
kdebug("Unsupported Exception ESR %lx\n", esr);
|
||||
break;
|
||||
|
@ -51,7 +51,34 @@ struct thread idle_threads[PLAT_CPU_NUM];
|
||||
*/
|
||||
int rr_sched_enqueue(struct thread *thread)
|
||||
{
|
||||
s32 dest_core;
|
||||
|
||||
if (thread == NULL || thread->thread_ctx == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 空闲线程
|
||||
if (thread->thread_ctx->type == TYPE_IDLE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 已经进入就绪队列
|
||||
if (thread->thread_ctx->state == TS_READY) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 选择目标核心
|
||||
dest_core = thread->thread_ctx->affinity;
|
||||
if (dest_core == NO_AFF) {
|
||||
dest_core = smp_get_cpu_id();
|
||||
}
|
||||
|
||||
// 入队尾
|
||||
list_append(&thread->ready_queue_node, &rr_ready_queue[dest_core]);
|
||||
thread->thread_ctx->state = TS_READY;
|
||||
thread->thread_ctx->cpuid = dest_core;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -62,7 +89,25 @@ int rr_sched_enqueue(struct thread *thread)
|
||||
*/
|
||||
int rr_sched_dequeue(struct thread *thread)
|
||||
{
|
||||
if (thread == NULL || thread->thread_ctx == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 空闲线程
|
||||
if (thread->thread_ctx->type == TYPE_IDLE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 状态判断
|
||||
if (thread->thread_ctx->state != TS_READY) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 出队
|
||||
list_del(&thread->ready_queue_node);
|
||||
thread->thread_ctx->state = TS_INTER;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -78,7 +123,25 @@ int rr_sched_dequeue(struct thread *thread)
|
||||
*/
|
||||
struct thread *rr_sched_choose_thread(void)
|
||||
{
|
||||
struct thread *result;
|
||||
struct list_head *queue = &rr_ready_queue[smp_get_cpu_id()];
|
||||
|
||||
// 队列空
|
||||
if (list_empty(queue)) {
|
||||
return &idle_threads[smp_get_cpu_id()];
|
||||
}
|
||||
|
||||
// 选择队首,注意准备队列指针并不是 thread 的开头
|
||||
result = (struct thread *) (queue->next - 1);
|
||||
|
||||
// 出队
|
||||
if (rr_sched_dequeue(result) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kdebug("[RR] Cpu #%d Select thread %lx, sp = %lx\n",
|
||||
smp_get_cpu_id(), result->thread_ctx, result->thread_ctx->ec.reg[SP_EL0]);
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void rr_sched_refill_budget(struct thread *target, u32 budget)
|
||||
@ -99,7 +162,25 @@ static inline void rr_sched_refill_budget(struct thread *target, u32 budget)
|
||||
*/
|
||||
int rr_sched(void)
|
||||
{
|
||||
struct thread *dest_thread;
|
||||
|
||||
// 若当前有运行进程,放入队列
|
||||
if (current_thread != NULL && current_thread->thread_ctx != NULL
|
||||
&& current_thread->thread_ctx->type != TYPE_IDLE) {
|
||||
rr_sched_enqueue(current_thread);
|
||||
kdebug("[RR] Cpu #%d yield thread %lx to queue\n", smp_get_cpu_id(), current_thread->thread_ctx);
|
||||
}
|
||||
|
||||
// 选择新线程
|
||||
dest_thread = rr_sched_choose_thread();
|
||||
if (dest_thread == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 准备调度
|
||||
switch_to_thread(dest_thread);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -140,6 +140,8 @@ u64 switch_context(void)
|
||||
*/
|
||||
void sys_yield(void)
|
||||
{
|
||||
sched();
|
||||
eret_to_thread(switch_context());
|
||||
}
|
||||
|
||||
int sched_init(struct sched_ops *sched_ops)
|
||||
|
@ -45,7 +45,7 @@ u32 sys_getc(void)
|
||||
*/
|
||||
u32 sys_get_cpu_id(void)
|
||||
{
|
||||
return -1;
|
||||
return smp_get_cpu_id();
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
@ -57,6 +57,11 @@ u32 sys_get_cpu_id(void)
|
||||
*/
|
||||
const void *syscall_table[NR_SYSCALL] = {
|
||||
[0 ... NR_SYSCALL - 1] = sys_debug,
|
||||
[SYS_putc] = sys_putc,
|
||||
[SYS_exit] = sys_exit,
|
||||
[SYS_create_pmo] = sys_create_pmo,
|
||||
[SYS_map_pmo] = sys_map_pmo,
|
||||
[SYS_handle_brk] = sys_handle_brk,
|
||||
/* lab3 syscalls finished */
|
||||
|
||||
[SYS_getc] = sys_getc,
|
||||
|
16
note.org
16
note.org
@ -145,6 +145,10 @@ ELF Section、Segment 两个概念。
|
||||
|
||||
其实连对齐都不用,直接就干上去也行,反正之前页表的时候已经处理了没对齐的情况。
|
||||
|
||||
一定注意对齐!竟然在后面实验翻车了,段开头是有可能非 4k 对齐的,复制要加上偏移。
|
||||
|
||||
alloc_section = (char *) phys_to_virt(pmo->start) + (p_vaddr & (PAGE_SIZE - 1));
|
||||
|
||||
**** 初始化线程上下文
|
||||
|
||||
照着文字写就行,初始化 TCB
|
||||
@ -195,3 +199,15 @@ boot 阶段的栈是独立的。函数也没调用几个,我猜测可能是 el
|
||||
*** 练习6
|
||||
|
||||
原因是 unlock_kernel 后才进行从栈恢复,而且函数退出时内核栈还是空的,所以 unlock 的时候无所谓。
|
||||
|
||||
*** 练习7
|
||||
|
||||
虽然没提,但是其实状态设置、控制很重要。以及 BUG 异步输出基本和乱码一样,希望加个打印锁……
|
||||
|
||||
还有一个重点就是 ready_queue 不是结构体开头,所以不可以直接转成 thread *。
|
||||
|
||||
sys_yield 要注意必须手动调用切换上下文,不然不会有效果。因为默认的 exception_return 不考虑 current_thread。
|
||||
|
||||
*** 练习8
|
||||
|
||||
否则将无法再次在该核上进行调度。
|
||||
|
Loading…
x
Reference in New Issue
Block a user