The BSP can trigger timer interrupts normally, and idle keeps running (the log shows `[APIC] timer IRQ` and idle counter output).
The AP never triggers a timer interrupt; not a single `[APIC] timer IRQ` appears.
I tried adding several kernel threads, noticed that PID allocation is abnormal, and the system seems to only run the idle thread – other threads are never scheduled. Through debugging I confirmed that the test threads are enqueued (`rr_enqueue` is called), but they never get scheduled.
The initialization flow is as follows.
The BSP first executes `task_data_init` (only once):
Code: Select all
bool task_data_init(void) {
uint32_t max_cpu = bootboot->numcores;
uint64_t per_cpu_task_stopped_size = sizeof(uint32_t) + (sizeof(task_state_struct) * max_cpu);
per_cpu_task_state_ptr = kheap_alloc(per_cpu_task_stopped_size);
if (!per_cpu_task_state_ptr) return false;
for (int i = 0; i < max_cpu; i++) INIT_LIST_HEAD(&per_cpu_task_state_ptr->state[i].stopped);
id_map = dynarr_create(sizeof(struct task_struct *), TASK_ID_MAX);
if (!id_map) return false;
sched_func();
idle = task_create_idle();
TASK_PRINT("task data init success\n");
return true;
}
Then all CPUs enter `task_init`:
Code: Select all
void task_init(void) {
if (!idle) goto error;
smp_set_idle(idle);
if (sched_class_ptr && sched_class_ptr->init) sched_class_ptr->init();
clockevent_handle_t clockevent = clockevent_get(NULL);
if (!clockevent) goto error;
smp_set_clockevent(clockevent);
clockevent_set_handler(clockevent, task_clock_event_handle);
clockevent_set_mode(clockevent, CLOCKEVENT_MODE_ONESHOT);
TASK_PRINT("task init success\n");
task_set_next_timer();
task_boot_sched();
error:
TASK_PANIC("system error");
}
Log output:
Code: Select all
[BOOTKERNEL] BP CPU logical_id : 0
[BOOTKERNEL] BP CPU APIC_ID : 0
[KERNEL]ShiziOS KERNEL v0.1.0
...
[CLOCKEVENT] register clockevent : [“name” = "apic", “hz” = "100000000"]
...
[ACPI] ACPI init succeed
[IOAPIC] ioapic init success
[CLOCKEVENT] register clockevent : [“name” = "pit", “hz” = "1193182"]
[TASK]task data init success
[SMP] smp init succeed
[SMP] smp init succeed
[TASK]task init success
[IDLE] CPU 1
[TASK]task init success
[IDLE] CPU 0
[APIC] timer IRQ
[APIC] timer IRQ
…… (intermediate interrupt prints omitted)
[APIC] timer IRQ
[IDLE] CPU 0
[IDLE] count : 50
[APIC] timer IRQ
……
Here is the scheduler enqueue and pick_next code:
Code: Select all
void rr_enqueue(struct task_struct *task) {
per_cpu_sched *pcpu_sched = smp_get_sched();
list_add_tail(&task->sched.list, &pcpu_sched->run_queue);
}
struct task_struct *rr_pick_next(void) {
per_cpu_sched *pcpu_sched = smp_get_sched();
if (list_empty(&pcpu_sched->run_queue)) return smp_get_idle();
struct list_head *head = pcpu_sched->run_queue.next;
list_move_tail(head, &pcpu_sched->run_queue);
return list_entry(head, task_struct, sched.list);
}
Since the code is quite large, I'm not pasting everything here. The main parts are in `kernel/task`. Here is the repository link:
https://github.com/shizi297/ShiziOS
