mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 11:16:47 +00:00
🆕 为AP处理器配置进程调度
This commit is contained in:
parent
82e34f271f
commit
ddbfb822c4
@ -482,8 +482,18 @@ void do_IRQ(struct pt_regs *rsp, ul number)
|
|||||||
else if (number > 0x80)
|
else if (number > 0x80)
|
||||||
|
|
||||||
{
|
{
|
||||||
printk_color(RED, BLACK, "SMP IPI [ %d ]\n", number);
|
//printk_color(RED, BLACK, "SMP IPI [ %d ]\n", number);
|
||||||
apic_local_apic_edge_ack(number);
|
apic_local_apic_edge_ack(number);
|
||||||
|
if (number == 0xc8) // 来自BSP的HPET中断消息
|
||||||
|
{
|
||||||
|
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies -= 2;
|
||||||
|
++(current_pcb->virtual_runtime);
|
||||||
|
|
||||||
|
if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0)
|
||||||
|
current_pcb->flags |= PROC_NEED_SCHED;
|
||||||
|
|
||||||
|
//printk_color(RED, BLACK, "CPU_exec_task_jiffies:%d current_pcb = %#018lx\t current_pcb->thread=%#018lx\n", sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies, (ul)current_pcb, (ul)current_pcb->thread);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -501,7 +511,7 @@ void do_IRQ(struct pt_regs *rsp, ul number)
|
|||||||
kBUG("current_pcb->preempt_count<0! pid=%d", current_pcb->pid); // should not be here
|
kBUG("current_pcb->preempt_count<0! pid=%d", current_pcb->pid); // should not be here
|
||||||
|
|
||||||
// 检测当前进程是否可被调度
|
// 检测当前进程是否可被调度
|
||||||
if (current_pcb->flags & PROC_NEED_SCHED)
|
if (current_pcb->flags & PROC_NEED_SCHED && proc_current_cpu_id == 1)
|
||||||
{
|
{
|
||||||
sched_cfs();
|
sched_cfs();
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <driver/timers/timer.h>
|
#include <driver/timers/timer.h>
|
||||||
#include <process/process.h>
|
#include <process/process.h>
|
||||||
#include <sched/sched.h>
|
#include <sched/sched.h>
|
||||||
|
#include <smp/ipi.h>
|
||||||
|
|
||||||
static struct acpi_HPET_description_table_t *hpet_table;
|
static struct acpi_HPET_description_table_t *hpet_table;
|
||||||
static uint64_t HPET_REG_BASE = 0;
|
static uint64_t HPET_REG_BASE = 0;
|
||||||
@ -50,11 +51,16 @@ hardware_intr_controller HPET_intr_controller =
|
|||||||
|
|
||||||
void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
|
void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
//printk("(HPET)");
|
// printk("(HPET)");
|
||||||
switch (param)
|
switch (param)
|
||||||
{
|
{
|
||||||
case 0: // 定时器0中断
|
case 0: // 定时器0中断
|
||||||
++timer_jiffies;
|
++timer_jiffies;
|
||||||
|
|
||||||
|
// 将HEPT中断消息转发到ap:1处理器
|
||||||
|
ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0xc8,
|
||||||
|
ICR_APIC_FIXED, ICR_No_Shorthand, true, 1);
|
||||||
|
|
||||||
// 若当前时间比定时任务的时间间隔大,则进入中断下半部
|
// 若当前时间比定时任务的时间间隔大,则进入中断下半部
|
||||||
if (container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list)->expire_jiffies <= timer_jiffies)
|
if (container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list)->expire_jiffies <= timer_jiffies)
|
||||||
set_softirq_status(TIMER_SIRQ);
|
set_softirq_status(TIMER_SIRQ);
|
||||||
@ -63,20 +69,22 @@ void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
|
|||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
--sched_cfs_ready_queue.cpu_exec_proc_jiffies;
|
--sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies;
|
||||||
++current_pcb->virtual_runtime;
|
++current_pcb->virtual_runtime;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
default:
|
default:
|
||||||
sched_cfs_ready_queue.cpu_exec_proc_jiffies -= 2;
|
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies -= 2;
|
||||||
current_pcb->virtual_runtime += 2;
|
current_pcb->virtual_runtime += 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sched_cfs_ready_queue.cpu_exec_proc_jiffies <= 0)
|
/* 由于目前只有BSP处理器会收到HPET中断,因此这里只会标记BSP处理器的进程需要调度
|
||||||
|
if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0)
|
||||||
{
|
{
|
||||||
current_pcb->flags |= PROC_NEED_SCHED;
|
current_pcb->flags |= PROC_NEED_SCHED;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -155,8 +163,6 @@ int HPET_init()
|
|||||||
// 使用I/O APIC 的IRQ2接收hpet定时器0的中断
|
// 使用I/O APIC 的IRQ2接收hpet定时器0的中断
|
||||||
apic_make_rte_entry(&entry, 34, IO_APIC_FIXED, DEST_PHYSICAL, IDLE, POLARITY_HIGH, IRR_RESET, EDGE_TRIGGER, MASKED, 0);
|
apic_make_rte_entry(&entry, 34, IO_APIC_FIXED, DEST_PHYSICAL, IDLE, POLARITY_HIGH, IRR_RESET, EDGE_TRIGGER, MASKED, 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*(uint64_t *)(HPET_REG_BASE + MAIN_CNT) = 0;
|
*(uint64_t *)(HPET_REG_BASE + MAIN_CNT) = 0;
|
||||||
io_mfence();
|
io_mfence();
|
||||||
*(uint64_t *)(HPET_REG_BASE + TIM0_CONF) = 0x004c; // 设置定时器0为周期定时,边沿触发,投递到IO APIC的2号引脚(这里有点绕,写的是8259的引脚号,但是因为禁用了8259,因此会被路由到IO APIC的2号引脚)
|
*(uint64_t *)(HPET_REG_BASE + TIM0_CONF) = 0x004c; // 设置定时器0为周期定时,边沿触发,投递到IO APIC的2号引脚(这里有点绕,写的是8259的引脚号,但是因为禁用了8259,因此会被路由到IO APIC的2号引脚)
|
||||||
@ -166,8 +172,6 @@ int HPET_init()
|
|||||||
|
|
||||||
rtc_get_cmos_time(&rtc_now);
|
rtc_get_cmos_time(&rtc_now);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
kinfo("HPET Initialized.");
|
kinfo("HPET Initialized.");
|
||||||
*(uint64_t *)(HPET_REG_BASE + GEN_CONF) = 3; // 置位旧设备中断路由兼容标志位、定时器组使能标志位
|
*(uint64_t *)(HPET_REG_BASE + GEN_CONF) = 3; // 置位旧设备中断路由兼容标志位、定时器组使能标志位
|
||||||
io_mfence();
|
io_mfence();
|
||||||
|
@ -198,7 +198,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code)
|
|||||||
|
|
||||||
__asm__ __volatile__("movq %%cr2, %0":"=r"(cr2)::"memory");
|
__asm__ __volatile__("movq %%cr2, %0":"=r"(cr2)::"memory");
|
||||||
|
|
||||||
kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx,RIP:%#018lx\n",error_code , regs->rsp , regs->rip);
|
kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx,RIP:%#018lx CPU:%d\n",error_code , regs->rsp , regs->rip, proc_current_cpu_id);
|
||||||
|
|
||||||
if(!(error_code & 0x01))
|
if(!(error_code & 0x01))
|
||||||
printk_color(RED,BLACK,"Page Not-Present,\t");
|
printk_color(RED,BLACK,"Page Not-Present,\t");
|
||||||
|
@ -132,7 +132,7 @@ void system_initialize()
|
|||||||
syscall_init();
|
syscall_init();
|
||||||
// 再初始化进程模块。顺序不能调转
|
// 再初始化进程模块。顺序不能调转
|
||||||
sched_init();
|
sched_init();
|
||||||
kdebug("sched_cfs_ready_queue.cpu_exec_proc_jiffies=%ld", sched_cfs_ready_queue.cpu_exec_proc_jiffies);
|
|
||||||
timer_init();
|
timer_init();
|
||||||
|
|
||||||
smp_init();
|
smp_init();
|
||||||
@ -146,15 +146,12 @@ void system_initialize()
|
|||||||
// test_mm();
|
// test_mm();
|
||||||
|
|
||||||
|
|
||||||
process_init();
|
//process_init();
|
||||||
|
|
||||||
HPET_init();
|
HPET_init();
|
||||||
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
printk_color(ORANGE, BLACK, "i\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//操作系统内核从这里开始执行
|
//操作系统内核从这里开始执行
|
||||||
|
@ -385,7 +385,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
|||||||
else
|
else
|
||||||
kdebug("is kernel proc.");
|
kdebug("is kernel proc.");
|
||||||
|
|
||||||
kdebug("ret_from_system_call=%#018lx", (ul)ret_from_system_call);
|
|
||||||
|
|
||||||
tsk->state = PROC_RUNNING;
|
tsk->state = PROC_RUNNING;
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include "sched.h"
|
#include "sched.h"
|
||||||
#include <common/kprint.h>
|
#include <common/kprint.h>
|
||||||
|
|
||||||
|
struct sched_queue_t sched_cfs_ready_queue[MAX_CPU_NUM]; // 就绪队列
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 从就绪队列中取出PCB
|
* @brief 从就绪队列中取出PCB
|
||||||
*
|
*
|
||||||
@ -8,16 +10,16 @@
|
|||||||
*/
|
*/
|
||||||
struct process_control_block *sched_cfs_dequeue()
|
struct process_control_block *sched_cfs_dequeue()
|
||||||
{
|
{
|
||||||
if (list_empty(&sched_cfs_ready_queue.proc_queue.list))
|
if (list_empty(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list))
|
||||||
{
|
{
|
||||||
kdebug("list empty");
|
kdebug("list empty");
|
||||||
return &initial_proc_union.pcb;
|
return &initial_proc_union.pcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue.proc_queue.list), struct process_control_block, list);
|
struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list), struct process_control_block, list);
|
||||||
|
|
||||||
list_del(&proc->list);
|
list_del(&proc->list);
|
||||||
--sched_cfs_ready_queue.count;
|
--sched_cfs_ready_queue[proc_current_cpu_id].count;
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,10 +30,10 @@ struct process_control_block *sched_cfs_dequeue()
|
|||||||
*/
|
*/
|
||||||
void sched_cfs_enqueue(struct process_control_block *pcb)
|
void sched_cfs_enqueue(struct process_control_block *pcb)
|
||||||
{
|
{
|
||||||
struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue.proc_queue.list), struct process_control_block, list);
|
struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list), struct process_control_block, list);
|
||||||
if (proc == &initial_proc_union.pcb)
|
if (proc == &initial_proc_union.pcb)
|
||||||
return;
|
return;
|
||||||
if ((list_empty(&sched_cfs_ready_queue.proc_queue.list)) == 0)
|
if ((list_empty(&sched_cfs_ready_queue[proc_current_cpu_id].proc_queue.list)) == 0)
|
||||||
{
|
{
|
||||||
while (proc->virtual_runtime < pcb->virtual_runtime)
|
while (proc->virtual_runtime < pcb->virtual_runtime)
|
||||||
{
|
{
|
||||||
@ -39,7 +41,7 @@ void sched_cfs_enqueue(struct process_control_block *pcb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
list_append(&proc->list, &pcb->list);
|
list_append(&proc->list, &pcb->list);
|
||||||
++sched_cfs_ready_queue.count;
|
++sched_cfs_ready_queue[proc_current_cpu_id].count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,17 +60,17 @@ void sched_cfs()
|
|||||||
if (current_pcb->state = PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
|
if (current_pcb->state = PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
|
||||||
sched_cfs_enqueue(current_pcb);
|
sched_cfs_enqueue(current_pcb);
|
||||||
|
|
||||||
if (sched_cfs_ready_queue.cpu_exec_proc_jiffies <= 0)
|
if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0)
|
||||||
{
|
{
|
||||||
switch (proc->priority)
|
switch (proc->priority)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
sched_cfs_ready_queue.cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue.count;
|
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue[proc_current_cpu_id].count;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
default:
|
default:
|
||||||
sched_cfs_ready_queue.cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue.count) << 2;
|
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue[proc_current_cpu_id].count) << 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,20 +81,20 @@ void sched_cfs()
|
|||||||
// kdebug("not switch.");
|
// kdebug("not switch.");
|
||||||
sched_cfs_enqueue(proc);
|
sched_cfs_enqueue(proc);
|
||||||
|
|
||||||
if (sched_cfs_ready_queue.cpu_exec_proc_jiffies <= 0)
|
if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0)
|
||||||
{
|
{
|
||||||
switch (proc->priority)
|
switch (proc->priority)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
sched_cfs_ready_queue.cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue.count;
|
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue[proc_current_cpu_id].count;
|
||||||
//sched_cfs_ready_queue.cpu_exec_proc_jiffies = 5;
|
// sched_cfs_ready_queue.cpu_exec_proc_jiffies = 5;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
default:
|
default:
|
||||||
//sched_cfs_ready_queue.cpu_exec_proc_jiffies = 5;
|
// sched_cfs_ready_queue.cpu_exec_proc_jiffies = 5;
|
||||||
|
|
||||||
sched_cfs_ready_queue.cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue.count) << 2;
|
sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue[proc_current_cpu_id].count) << 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,9 +107,13 @@ void sched_cfs()
|
|||||||
*/
|
*/
|
||||||
void sched_init()
|
void sched_init()
|
||||||
{
|
{
|
||||||
memset(&sched_cfs_ready_queue, 0, sizeof(struct sched_queue_t));
|
memset(&sched_cfs_ready_queue, 0, sizeof(struct sched_queue_t) * MAX_CPU_NUM);
|
||||||
list_init(&sched_cfs_ready_queue.proc_queue.list);
|
for (int i = 0; i < MAX_CPU_NUM; ++i)
|
||||||
sched_cfs_ready_queue.count = 1; // 因为存在IDLE进程,因此为1
|
{
|
||||||
sched_cfs_ready_queue.cpu_exec_proc_jiffies = 8;
|
|
||||||
sched_cfs_ready_queue.proc_queue.virtual_runtime = 0x7fffffffffffffff;
|
list_init(&sched_cfs_ready_queue[i].proc_queue.list);
|
||||||
|
sched_cfs_ready_queue[i].count = 1; // 因为存在IDLE进程,因此为1
|
||||||
|
sched_cfs_ready_queue[i].cpu_exec_proc_jiffies = 5;
|
||||||
|
sched_cfs_ready_queue[i].proc_queue.virtual_runtime = 0x7fffffffffffffff;
|
||||||
|
}
|
||||||
}
|
}
|
@ -3,6 +3,7 @@
|
|||||||
#include <common/glib.h>
|
#include <common/glib.h>
|
||||||
#include <process/process.h>
|
#include <process/process.h>
|
||||||
|
|
||||||
|
// @todo: 用红黑树重写cfs的队列
|
||||||
struct sched_queue_t
|
struct sched_queue_t
|
||||||
{
|
{
|
||||||
long count; // 当前队列中的数量
|
long count; // 当前队列中的数量
|
||||||
@ -10,8 +11,8 @@ struct sched_queue_t
|
|||||||
struct process_control_block proc_queue;
|
struct process_control_block proc_queue;
|
||||||
};
|
};
|
||||||
|
|
||||||
// @todo: 用红黑树重写cfs的队列
|
|
||||||
struct sched_queue_t sched_cfs_ready_queue; // 就绪队列
|
extern struct sched_queue_t sched_cfs_ready_queue[MAX_CPU_NUM]; // 就绪队列
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 调度函数
|
* @brief 调度函数
|
||||||
|
@ -34,7 +34,7 @@ void smp_init()
|
|||||||
|
|
||||||
// 设置多核IPI中断门
|
// 设置多核IPI中断门
|
||||||
for (int i = 200; i < 210; ++i)
|
for (int i = 200; i < 210; ++i)
|
||||||
set_intr_gate(i, 2, SMP_interrupt_table[i - 200]);
|
set_intr_gate(i, 0, SMP_interrupt_table[i - 200]);
|
||||||
|
|
||||||
memset((void *)SMP_IPI_desc, 0, sizeof(irq_desc_t) * SMP_IRQ_NUM);
|
memset((void *)SMP_IPI_desc, 0, sizeof(irq_desc_t) * SMP_IRQ_NUM);
|
||||||
|
|
||||||
@ -117,14 +117,41 @@ void smp_ap_start()
|
|||||||
kdebug("current cpu = %d", current_starting_cpu);
|
kdebug("current cpu = %d", current_starting_cpu);
|
||||||
|
|
||||||
apic_init_ap_core_local_apic();
|
apic_init_ap_core_local_apic();
|
||||||
|
|
||||||
|
// ============ 为ap处理器初始化IDLE进程 =============
|
||||||
|
memset(current_pcb, 0, sizeof(struct process_control_block));
|
||||||
|
|
||||||
|
current_pcb->state = PROC_RUNNING;
|
||||||
|
current_pcb->flags = PF_KTHREAD;
|
||||||
|
current_pcb->mm = &initial_mm;
|
||||||
|
|
||||||
|
list_init(¤t_pcb->list);
|
||||||
|
current_pcb->addr_limit = KERNEL_BASE_LINEAR_ADDR;
|
||||||
|
current_pcb->priority = 2;
|
||||||
|
current_pcb->virtual_runtime = 0;
|
||||||
|
|
||||||
|
current_pcb->thread = (struct thread_struct *)(current_pcb + 1); // 将线程结构体放置在pcb后方
|
||||||
|
current_pcb->thread->rbp = _stack_start;
|
||||||
|
current_pcb->thread->rsp = _stack_start;
|
||||||
|
current_pcb->thread->fs = KERNEL_DS;
|
||||||
|
current_pcb->thread->gs = KERNEL_DS;
|
||||||
|
current_pcb->cpu_id = current_starting_cpu;
|
||||||
|
|
||||||
|
initial_proc[proc_current_cpu_id] = current_pcb;
|
||||||
|
|
||||||
load_TR(10 + current_starting_cpu * 2);
|
load_TR(10 + current_starting_cpu * 2);
|
||||||
|
|
||||||
sti();
|
|
||||||
// kdebug("IDT_addr = %#018lx", phys_2_virt(IDT_Table));
|
// kdebug("IDT_addr = %#018lx", phys_2_virt(IDT_Table));
|
||||||
memset(current_pcb, 0, sizeof(struct process_control_block));
|
|
||||||
spin_unlock(&multi_core_starting_lock);
|
spin_unlock(&multi_core_starting_lock);
|
||||||
|
current_pcb->preempt_count = 0;
|
||||||
|
sti();
|
||||||
|
|
||||||
int a = 1 / 0;
|
if(proc_current_cpu_id == 1)
|
||||||
|
process_init();
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
printk_color(BLACK, WHITE, "CPU:%d IDLE process.\n", proc_current_cpu_id);
|
||||||
|
}
|
||||||
while (1) // 这里要循环hlt,原因是当收到中断后,核心会被唤醒,处理完中断之后不会自动hlt
|
while (1) // 这里要循环hlt,原因是当收到中断后,核心会被唤醒,处理完中断之后不会自动hlt
|
||||||
hlt();
|
hlt();
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user