Skip to content

Commit 960901a

Browse files
committed
置换调度队列结构
1 parent 54c47bd commit 960901a

File tree

15 files changed

+305
-62
lines changed

15 files changed

+305
-62
lines changed

src/core/cpu/cpuid.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,34 @@ void cpuid(uint32_t code, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d) {
1414
static void get_vendor_name() {
1515
int cpuid_level;
1616
static char x86_vendor_id[16] = {0};
17-
cpuid(0x00000000, (unsigned int *) &cpuid_level,
18-
(unsigned int *) &x86_vendor_id[0],
19-
(unsigned int *) &x86_vendor_id[8],
20-
(unsigned int *) &x86_vendor_id[4]);
17+
cpuid(0x00000000, (uint32_t *) &cpuid_level,
18+
(uint32_t *) &x86_vendor_id[0],
19+
(uint32_t *) &x86_vendor_id[8],
20+
(uint32_t *) &x86_vendor_id[4]);
2121
cpu.vendor = x86_vendor_id;
2222
}
2323

2424
static void get_model_name() {
25-
unsigned int *v = (unsigned int *) cpu.model_name;
25+
uint32_t *v = (uint32_t *) cpu.model_name;
2626
cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);
2727
cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
2828
cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
2929
cpu.model_name[48] = 0;
3030
}
3131

3232
static void get_cpu_address_sizes() {
33-
unsigned int eax, ebx, ecx, edx;
33+
uint32_t eax, ebx, ecx, edx;
3434
cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
35-
3635
cpu.virt_bits = (eax >> 8) & 0xff;
3736
cpu.phys_bits = eax & 0xff;
3837
}
3938

39+
bool cpuid_has_sse(){
40+
uint32_t eax, ebx, ecx, edx;
41+
cpuid(1, &eax, &ebx, &ecx, &edx);
42+
return edx & (1 << 25);
43+
}
44+
4045
cpu_t get_cpu_info() {
4146
return cpu;
4247
}

src/core/cpu/empty_interrupt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include "krlibc.h"
88
#include "io.h"
99

10-
#define INTERRUPT_HANDLE(id) void empty_handler_##id(interrupt_frame_t *frame){ UNUSED(frame); close_interrupt; send_eoi(); printk("Interrupt empty %d\n",id); update_terminal(); cpu_hlt; }
10+
#define INTERRUPT_HANDLE(id) void empty_handler_##id(interrupt_frame_t *frame){ UNUSED(frame); close_interrupt; send_eoi(); printk("Interrupt empty "#id"\n"); update_terminal(); cpu_hlt; }
1111

1212
INTERRUPT_HANDLE(0)
1313
INTERRUPT_HANDLE(1)

src/core/cpu/smp.c

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ extern bool x2apic_mode; //apic.c
1919
ticketlock apu_lock;
2020

2121
smp_cpu_t cpus[MAX_CPU];
22-
22+
uint32_t bsp_lapic_id;
2323
uint64_t cpu_count = 0;
2424

2525
uint64_t cpu_num(){
@@ -118,21 +118,53 @@ void apu_entry(){
118118
sprintf(name,"CP_IDLE_CPU%lu",get_current_cpuid());
119119
memcpy(apu_idle->name, name, strlen(name));
120120
apu_idle->next = kernel_head_task;
121-
add_task(apu_idle);
121+
smp_cpu_t *cpu = get_cpu_smp(get_current_cpuid());
122+
if(cpu == NULL){
123+
return;
124+
}
125+
apu_idle->queue_index = queue_enqueue(cpu->scheduler_queue,apu_idle);
126+
if(apu_idle->queue_index == -1){
127+
logkf("Error: scheduler null %d\n",get_current_cpuid());
128+
}
122129
pivfs_update(kernel_head_task);
123130
ticket_unlock(&apu_lock);
124131
cpu_hlt;
125132
}
126133

134+
smp_cpu_t *get_cpu_smp(uint32_t processor_id){
135+
if(processor_id == bsp_lapic_id) return &cpus[MAX_CPU - 1];
136+
smp_cpu_t cpu = cpus[processor_id];
137+
if(cpu.flags == 1){
138+
return &cpus[processor_id];
139+
} else return NULL;
140+
}
141+
127142
void apu_startup(struct limine_smp_request smp_request){
128143
struct limine_smp_response *response = smp_request.response;
129144
cpu_count = response->cpu_count;
130-
for (uint64_t i = 0; i < cpu_count && i < MAX_CPU; i++){
145+
bsp_lapic_id = response->bsp_lapic_id;
146+
for (uint64_t i = 0; i < cpu_count && i < MAX_CPU - 1; i++){
131147
struct limine_smp_info *info = response->cpus[i];
132-
if(info->lapic_id == response->bsp_lapic_id) continue;
148+
if(info->lapic_id == response->bsp_lapic_id) {
149+
cpus[MAX_CPU - 1].lapic_id = response->bsp_lapic_id;
150+
cpus[MAX_CPU - 1].flags = 1;
151+
cpus[MAX_CPU - 1].scheduler_queue = queue_init();
152+
cpus[MAX_CPU - 1].iter_node = NULL;
153+
continue;
154+
}
155+
cpus[info->processor_id].scheduler_queue = queue_init();
133156
cpus[info->processor_id].lapic_id = info->lapic_id;
134157
cpus[info->processor_id].flags = 1;
158+
cpus[info->processor_id].iter_node = NULL;
135159
info->goto_address = (void*)apu_entry;
136160
}
161+
smp_cpu_t *cpu = get_cpu_smp(get_current_cpuid());
162+
if(cpu == NULL){
163+
return;
164+
}
165+
kernel_head_task->queue_index = queue_enqueue(cpu->scheduler_queue,kernel_head_task);
166+
if(kernel_head_task->queue_index == -1){
167+
logkf("Error: scheduler null %d\n",get_current_cpuid());
168+
}
137169
kinfo("%d processors have been enabled.",cpu_count);
138170
}

src/core/module.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ void module_setup() {
2525
return;
2626
}
2727

28-
for (int i = 0; i < module.response->module_count; i++) {
28+
for (size_t i = 0; i < module.response->module_count; i++) {
2929
struct limine_file *file = module.response->modules[i];
3030
logkf("Module %d: %s\n", i, file->path);
3131
if(!strcmp(file->path,"/sys/sysfont.ttf")){

src/core/task/pcb.c

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,11 @@ void kill_proc(pcb_t task){
5959
disable_scheduler(); // 终止调度器, 防止释放被杀进程时候调度到该进程发生错误
6060
free_tty(task->tty);
6161

62-
pcb_t head = kernel_head_task;
63-
pcb_t last = NULL;
64-
while (1) {
65-
if (head->pid == task->pid) {
66-
last->next = task->next;
67-
free(task);
68-
enable_scheduler();
69-
open_interrupt;
70-
ticket_unlock(&pcb_lock);
71-
return;
72-
}
73-
last = head;
74-
head = head->next;
75-
}
62+
remove_task(task);
63+
64+
enable_scheduler();
65+
open_interrupt;
66+
ticket_unlock(&pcb_lock);
7667
}
7768

7869
pcb_t found_pcb(int pid) {
@@ -146,5 +137,6 @@ void init_pcb(){
146137
memcpy(current_task->name, name, strlen(name));
147138
current_task->next = kernel_head_task;
148139
pivfs_update(kernel_head_task);
140+
149141
kinfo("Load task schedule. | KernelProcessName: %s PID: %d", current_task->name, current_task->pid);
150142
}

src/core/task/scheduler.c

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "pivfs.h"
66
#include "smp.h"
77
#include "lock.h"
8+
#include "lock_queue.h"
89

910
pcb_t current_task = NULL;
1011
pcb_t kernel_head_task = NULL;
@@ -25,15 +26,39 @@ void disable_scheduler(){
2526
is_scheduler = false;
2627
}
2728

28-
void add_task(pcb_t new_task) {
29-
if (new_task == NULL) return;
29+
int add_task(pcb_t new_task) {
30+
if (new_task == NULL) return -1;
3031
ticket_lock(&scheduler_lock);
31-
pcb_t tailt = kernel_head_task;
32-
while (tailt->next != kernel_head_task) {
33-
if (tailt->next == NULL) break;
34-
tailt = tailt->next;
32+
33+
smp_cpu_t *cpu = get_cpu_smp(get_current_cpuid());
34+
if(cpu == NULL){
35+
ticket_unlock(&scheduler_lock);
36+
return -1;
37+
}
38+
new_task->queue_index = queue_enqueue(cpu->scheduler_queue,new_task);
39+
if(new_task->queue_index == -1){
40+
logkf("Error: scheduler null %d\n",get_current_cpuid());
41+
return -1;
42+
}
43+
44+
if(new_task->pid == kernel_head_task->pid) goto ret;
45+
46+
pivfs_update(kernel_head_task);
47+
ret:
48+
ticket_unlock(&scheduler_lock);
49+
return new_task->queue_index;
50+
}
51+
52+
void remove_task(pcb_t task){
53+
if(task == NULL) return;
54+
ticket_lock(&scheduler_lock);
55+
56+
smp_cpu_t *cpu = get_cpu_smp(get_current_cpuid());
57+
if(cpu == NULL){
58+
ticket_unlock(&scheduler_lock);
59+
return;
3560
}
36-
tailt->next = new_task;
61+
queue_remove_at(cpu->scheduler_queue,task->queue_index);
3762
pivfs_update(kernel_head_task);
3863
ticket_unlock(&scheduler_lock);
3964
}
@@ -95,17 +120,28 @@ void change_proccess(registers_t *reg,pcb_t taget){
95120
}
96121

97122
/**
98-
* CP_Kernel 默认调度器 - 循环调度
99-
* TODO 只适用于单核调度所以做了进程的CPU归属判断
123+
* CP_Kernel 默认单核调度器 - 循环调度
100124
* @param reg 当前进程上下文
101125
*/
102126
void scheduler(registers_t *reg){
103127
if(is_scheduler){
104128
if(current_task != NULL){
105-
pcb_t next = current_task->next;
106-
while (next->cpu_id != get_current_cpuid()){
107-
next = next->next;
129+
smp_cpu_t *cpu = get_cpu_smp(get_current_cpuid());
130+
if (cpu->iter_node == NULL) {
131+
iter_head:
132+
cpu->iter_node = cpu->scheduler_queue->head;
133+
} else {
134+
cpu->iter_node = cpu->iter_node->next;
135+
if(cpu->iter_node == NULL) goto iter_head;
108136
}
137+
void *data = NULL;
138+
if (cpu->iter_node != NULL) {
139+
data = cpu->iter_node->data;
140+
}
141+
142+
pcb_t next = (pcb_t)data;
143+
// logkf("p: %p\n",next);
144+
109145
current_task->cpu_clock++;
110146
if(current_task->time_buf != NULL){
111147
current_task->cpu_timer += get_time(current_task->time_buf);

src/driver/iic/pca9685.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ void pca9685_write(uint8_t reg, uint8_t data){
5656
uint8_t pca9685_read(uint8_t reg){
5757
//读取兼容性
5858
UNUSED(reg);
59+
return 0;
5960
}
6061

6162
/**

src/driver/input/keyboard.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include "krlibc.h"
55
#include "io.h"
66
#include "kprint.h"
7-
#include "acpi.h"
7+
#include "smp.h"
88
#include "pcb.h"
99
#include "terminal.h"
1010

@@ -26,6 +26,12 @@ char keytable1[0x54] = { // 未按下Shift
2626
',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2727
0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', '.'};
2828

29+
static void key_callback(void *pcb_handle,void* scan_handle){
30+
pcb_t cur = (pcb_t)pcb_handle;
31+
uint8_t scancode = *((uint8_t*)scan_handle);
32+
atom_push(cur->tty->keyboard_buffer, scancode);
33+
}
34+
2935
__IRQHANDLER void keyboard_handler(interrupt_frame_t *frame) {
3036
UNUSED(frame);
3137
io_out8(0x61, 0x20);
@@ -53,14 +59,12 @@ __IRQHANDLER void keyboard_handler(interrupt_frame_t *frame) {
5359
}
5460

5561
if (scancode < 0x80) {
56-
if (kernel_head_task != NULL) {
57-
pcb_t cur = kernel_head_task;
58-
do {
59-
cur = cur->next;
60-
atom_push(cur->tty->keyboard_buffer, scancode);
61-
} while (cur->pid != kernel_head_task->pid);
62-
} else
63-
printk("Keyboard scancode: %x\n", scancode);
62+
smp_cpu_t *cpu = get_cpu_smp(get_current_cpuid());
63+
if(cpu == NULL){
64+
logkf("Error: keyboard cannot iteration scheduler queue.\n");
65+
return;
66+
}
67+
queue_iterate(cpu->scheduler_queue,key_callback,&scancode);
6468
}
6569
}
6670

src/include/cpuid.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ typedef struct {
1010
} cpu_t;
1111

1212
void init_cpuid();
13-
13+
bool cpuid_has_sse();
1414
cpu_t get_cpu_info();

src/include/lock_queue.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#pragma once
2+
3+
#include "lock.h"
4+
5+
typedef struct LockNode {
6+
void *data;
7+
struct LockNode *next;
8+
int index;
9+
} lock_node;
10+
11+
typedef struct {
12+
lock_node *head;
13+
lock_node *tail;
14+
ticketlock lock;
15+
ticketlock iter_lock;
16+
int size;
17+
int next_index;
18+
} lock_queue;
19+
20+
/**
21+
* 初始化一个有锁可迭代队列
22+
* @return 队列
23+
*/
24+
lock_queue *queue_init();
25+
26+
/**
27+
* 入队操作
28+
* @param q 队列
29+
* @param data 存储的句柄
30+
* @return 该节点的索引
31+
*/
32+
int queue_enqueue(lock_queue *q, void *data);
33+
34+
/**
35+
* 删除指定索引的节点
36+
* @param q 队列
37+
* @param index 索引
38+
* @return 被删除节点的句柄
39+
*/
40+
void *queue_remove_at(lock_queue *q, int index);
41+
42+
/**
43+
* 出队操作
44+
* @param q 队列
45+
* @return 该节点存储的句柄
46+
*/
47+
void *queue_dequeue(lock_queue *q);
48+
49+
/**
50+
* 销毁队列
51+
* @param q 队列
52+
*/
53+
void queue_destroy(lock_queue *q);
54+
55+
/**
56+
* 传入回调函数迭代指定队列
57+
* @param q 队列
58+
* @param callback 回调函数
59+
* @param argument 回调函数传入的参数
60+
*/
61+
void queue_iterate(lock_queue *q, void (*callback)(void *,void*), void* argument);

0 commit comments

Comments
 (0)