mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-10 20:36:48 +00:00
🔧 更新了键盘驱动程序,使其适配vfs
This commit is contained in:
parent
464837eb1a
commit
832c0c7e5c
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -98,7 +98,8 @@
|
|||||||
"ipi.h": "c",
|
"ipi.h": "c",
|
||||||
"arch.h": "c",
|
"arch.h": "c",
|
||||||
"elf.h": "c",
|
"elf.h": "c",
|
||||||
"stdio.h": "c"
|
"stdio.h": "c",
|
||||||
|
"wait_queue.h": "c"
|
||||||
},
|
},
|
||||||
"C_Cpp.errorSquiggles": "Enabled",
|
"C_Cpp.errorSquiggles": "Enabled",
|
||||||
"esbonio.sphinx.confDir": ""
|
"esbonio.sphinx.confDir": ""
|
||||||
|
@ -18,7 +18,7 @@ LD_LIST := head.o
|
|||||||
OBJ_LIST := head.o
|
OBJ_LIST := head.o
|
||||||
|
|
||||||
|
|
||||||
kernel_subdirs := common driver
|
kernel_subdirs := common driver process
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -33,9 +33,7 @@ entry.o: exception/entry.S
|
|||||||
gcc -E exception/entry.S > exception/entry.s
|
gcc -E exception/entry.S > exception/entry.s
|
||||||
as $(ASFLAGS) -o exception/entry.o exception/entry.s
|
as $(ASFLAGS) -o exception/entry.o exception/entry.s
|
||||||
|
|
||||||
procs.o: process/proc.S
|
|
||||||
gcc -E process/proc.S > process/proc.s
|
|
||||||
as $(ASFLAGS) -o process/procs.o process/proc.s
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -62,8 +60,6 @@ mm.o: mm/mm.c
|
|||||||
slab.o: mm/slab.c
|
slab.o: mm/slab.c
|
||||||
gcc $(CFLAGS) -c mm/slab.c -o mm/slab.o
|
gcc $(CFLAGS) -c mm/slab.c -o mm/slab.o
|
||||||
|
|
||||||
process.o: process/process.c
|
|
||||||
gcc $(CFLAGS) -c process/process.c -o process/process.o
|
|
||||||
|
|
||||||
sched.o: sched/sched.c
|
sched.o: sched/sched.c
|
||||||
gcc $(CFLAGS) -c sched/sched.c -o sched/sched.o
|
gcc $(CFLAGS) -c sched/sched.c -o sched/sched.o
|
||||||
@ -150,15 +146,15 @@ uart.o: driver/uart/uart.c
|
|||||||
|
|
||||||
all: kernel
|
all: kernel
|
||||||
|
|
||||||
ld -b elf64-x86-64 -z muldefs -o kernel head.o main.o $(shell find . -name "*.o") -T link.lds
|
ld -b elf64-x86-64 -z muldefs -o kernel head.o main.o $(shell find . -name "*.o") -T link.lds
|
||||||
objcopy -I elf64-x86-64 -O elf64-x86-64 -R ".comment" -R ".eh_frame" kernel ../bin/kernel/kernel.elf
|
objcopy -I elf64-x86-64 -O elf64-x86-64 -R ".comment" -R ".eh_frame" kernel ../bin/kernel/kernel.elf
|
||||||
|
|
||||||
kernel: head.o entry.o procs.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o sched.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o smp.o apu_boot.o rtc.o HPET.o softirq.o timer.o fat32.o MBR.o VFS.o $(OBJ_LIST)
|
kernel: head.o entry.o main.o printk.o trap.o mm.o slab.o irq.o pic.o sched.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o smp.o apu_boot.o rtc.o HPET.o softirq.o timer.o fat32.o MBR.o VFS.o $(OBJ_LIST)
|
||||||
|
|
||||||
@list='$(kernel_subdirs)'; for subdir in $$list; do \
|
@list='$(kernel_subdirs)'; for subdir in $$list; do \
|
||||||
echo "make all in $$subdir";\
|
echo "make all in $$subdir";\
|
||||||
cd $$subdir;\
|
cd $$subdir;\
|
||||||
$(MAKE) all CFLAGS="$(CFLAGS)";\
|
$(MAKE) all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)";\
|
||||||
cd ..;\
|
cd ..;\
|
||||||
done
|
done
|
||||||
|
|
||||||
|
@ -11,8 +11,6 @@
|
|||||||
#include <common/miniLibc/stddef.h>
|
#include <common/miniLibc/stddef.h>
|
||||||
#include <arch/arch.h>
|
#include <arch/arch.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define sti() __asm__ __volatile__("sti\n\t" :: \
|
#define sti() __asm__ __volatile__("sti\n\t" :: \
|
||||||
: "memory") //开启外部中断
|
: "memory") //开启外部中断
|
||||||
#define cli() __asm__ __volatile__("cli\n\t" :: \
|
#define cli() __asm__ __volatile__("cli\n\t" :: \
|
||||||
@ -105,24 +103,24 @@ static inline void list_add(struct List *entry, struct List *node)
|
|||||||
entry->next = node;
|
entry->next = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 将node添加到给定的list的结尾(也就是当前节点的前面)
|
||||||
|
* @param entry 列表的入口
|
||||||
|
* @param node 待添加的节点
|
||||||
|
*/
|
||||||
static inline void list_append(struct List *entry, struct List *node)
|
static inline void list_append(struct List *entry, struct List *node)
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @brief 将node添加到给定的list的结尾(也就是当前节点的前面)
|
|
||||||
* @param entry 列表的入口
|
|
||||||
* @param node 待添加的节点
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct List *tail = entry->prev;
|
struct List *tail = entry->prev;
|
||||||
list_add(tail, node);
|
list_add(tail, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 从列表中删除节点
|
||||||
|
* @param entry 待删除的节点
|
||||||
|
*/
|
||||||
static inline void list_del(struct List *entry)
|
static inline void list_del(struct List *entry)
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @brief 从列表中删除节点
|
|
||||||
* @param entry 待删除的节点
|
|
||||||
*/
|
|
||||||
|
|
||||||
entry->next->prev = entry->prev;
|
entry->next->prev = entry->prev;
|
||||||
entry->prev->next = entry->next;
|
entry->prev->next = entry->next;
|
||||||
|
@ -465,7 +465,8 @@ static struct ahci_request_packet_t *ahci_make_request(long cmd, uint64_t base_a
|
|||||||
void ahci_end_request()
|
void ahci_end_request()
|
||||||
{
|
{
|
||||||
ahci_req_queue.in_service->wait_queue.pcb->state = PROC_RUNNING;
|
ahci_req_queue.in_service->wait_queue.pcb->state = PROC_RUNNING;
|
||||||
ahci_req_queue.in_service->wait_queue.pcb->flags |= PF_NEED_SCHED;
|
// ahci_req_queue.in_service->wait_queue.pcb->flags |= PF_NEED_SCHED;
|
||||||
|
// current_pcb->flags |= PF_NEED_SCHED;
|
||||||
kfree((uint64_t *)ahci_req_queue.in_service);
|
kfree((uint64_t *)ahci_req_queue.in_service);
|
||||||
ahci_req_queue.in_service = NULL;
|
ahci_req_queue.in_service = NULL;
|
||||||
|
|
||||||
|
@ -3,14 +3,32 @@
|
|||||||
#include "../../mm/mm.h"
|
#include "../../mm/mm.h"
|
||||||
#include "../../mm/slab.h"
|
#include "../../mm/slab.h"
|
||||||
#include "../../common/printk.h"
|
#include "../../common/printk.h"
|
||||||
|
#include <filesystem/VFS/VFS.h>
|
||||||
|
#include <process/wait_queue.h>
|
||||||
|
|
||||||
|
// 键盘输入缓冲区
|
||||||
static struct ps2_keyboard_input_buffer *kb_buf_ptr = NULL;
|
static struct ps2_keyboard_input_buffer *kb_buf_ptr = NULL;
|
||||||
|
// 缓冲区等待队列
|
||||||
|
static wait_queue_node_t ps2_keyboard_wait_queue;
|
||||||
|
|
||||||
// 功能键标志变量
|
// 功能键标志变量
|
||||||
static bool shift_l, shift_r, ctrl_l, ctrl_r, alt_l, alt_r;
|
static bool shift_l, shift_r, ctrl_l, ctrl_r, alt_l, alt_r;
|
||||||
static bool gui_l, gui_r, apps, insert, home, pgup, del, end, pgdn, arrow_u, arrow_l, arrow_d, arrow_r;
|
static bool gui_l, gui_r, apps, insert, home, pgup, del, end, pgdn, arrow_u, arrow_l, arrow_d, arrow_r;
|
||||||
static bool kp_forward_slash, kp_en;
|
static bool kp_forward_slash, kp_en;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 重置ps2键盘输入缓冲区
|
||||||
|
*
|
||||||
|
* @param kbp 缓冲区对象指针
|
||||||
|
*/
|
||||||
|
static void ps2_keyboard_reset_buffer(struct ps2_keyboard_input_buffer *kbp)
|
||||||
|
{
|
||||||
|
kbp->ptr_head = kb_buf_ptr->buffer;
|
||||||
|
kbp->ptr_tail = kb_buf_ptr->buffer;
|
||||||
|
kbp->count = 0;
|
||||||
|
// 清空输入缓冲区
|
||||||
|
memset(kbp->buffer, 0, ps2_keyboard_buffer_size);
|
||||||
|
}
|
||||||
struct apic_IO_APIC_RTE_entry entry;
|
struct apic_IO_APIC_RTE_entry entry;
|
||||||
|
|
||||||
hardware_intr_controller ps2_keyboard_intr_controller =
|
hardware_intr_controller ps2_keyboard_intr_controller =
|
||||||
@ -23,6 +41,120 @@ hardware_intr_controller ps2_keyboard_intr_controller =
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 打开键盘文件
|
||||||
|
*
|
||||||
|
* @param inode 所在的inode
|
||||||
|
* @param filp 文件指针
|
||||||
|
* @return long
|
||||||
|
*/
|
||||||
|
long ps2_keyboard_open(struct vfs_index_node_t *inode, struct vfs_file_t *filp)
|
||||||
|
{
|
||||||
|
filp->private_data = (void *)kb_buf_ptr;
|
||||||
|
ps2_keyboard_reset_buffer(kb_buf_ptr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 关闭键盘文件
|
||||||
|
*
|
||||||
|
* @param inode 所在的inode
|
||||||
|
* @param filp 文件指针
|
||||||
|
* @return long
|
||||||
|
*/
|
||||||
|
long ps2_keyboard_close(struct vfs_index_node_t *inode, struct vfs_file_t *filp)
|
||||||
|
{
|
||||||
|
filp->private_data = NULL;
|
||||||
|
ps2_keyboard_reset_buffer(kb_buf_ptr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 键盘io控制接口
|
||||||
|
*
|
||||||
|
* @param inode 所在的inode
|
||||||
|
* @param filp 键盘文件指针
|
||||||
|
* @param cmd 命令
|
||||||
|
* @param arg 参数
|
||||||
|
* @return long
|
||||||
|
*/
|
||||||
|
long ps2_keyboard_ioctl(struct vfs_index_node_t *inode, struct vfs_file_t *filp, uint64_t cmd, uint64_t arg)
|
||||||
|
{
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case KEYBOARD_CMD_RESET_BUFFER:
|
||||||
|
ps2_keyboard_reset_buffer(kb_buf_ptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 读取键盘文件的操作接口
|
||||||
|
*
|
||||||
|
* @param filp 文件指针
|
||||||
|
* @param buf 输出缓冲区
|
||||||
|
* @param count 要读取的字节数
|
||||||
|
* @param position 读取的位置
|
||||||
|
* @return long 读取的字节数
|
||||||
|
*/
|
||||||
|
long ps2_keyboard_read(struct vfs_file_t *filp, char *buf, int64_t count, long *position)
|
||||||
|
{
|
||||||
|
// 缓冲区为空则等待
|
||||||
|
if (kb_buf_ptr->count == 0)
|
||||||
|
wait_queue_sleep_on(&ps2_keyboard_wait_queue);
|
||||||
|
|
||||||
|
long counter = kb_buf_ptr->count >= count ? count : kb_buf_ptr->count;
|
||||||
|
|
||||||
|
uint8_t *tail = kb_buf_ptr->ptr_tail;
|
||||||
|
|
||||||
|
// 要读取的部分没有越过缓冲区末尾
|
||||||
|
if (counter <= (kb_buf_ptr->buffer + ps2_keyboard_buffer_size - tail))
|
||||||
|
{
|
||||||
|
copy_to_user(buf, tail, counter);
|
||||||
|
kb_buf_ptr->ptr_tail += counter;
|
||||||
|
}
|
||||||
|
else // 要读取的部分越过了缓冲区的末尾,进行循环
|
||||||
|
{
|
||||||
|
uint64_t tmp = (kb_buf_ptr->buffer + ps2_keyboard_buffer_size - tail);
|
||||||
|
copy_to_user(buf, tail, tmp);
|
||||||
|
copy_to_user(buf, kb_buf_ptr->ptr_head, counter - tmp);
|
||||||
|
kb_buf_ptr->ptr_tail = kb_buf_ptr->ptr_head + (counter - tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
kb_buf_ptr->count -= counter;
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 键盘文件写入接口(无作用,空)
|
||||||
|
*
|
||||||
|
* @param filp
|
||||||
|
* @param buf
|
||||||
|
* @param count
|
||||||
|
* @param position
|
||||||
|
* @return long
|
||||||
|
*/
|
||||||
|
long ps2_keyboard_write(struct vfs_file_t *filp, char *buf, int64_t count, long *position)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief ps2键盘驱动的虚拟文件接口
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct vfs_file_operations_t ps2_keyboard_fops =
|
||||||
|
{
|
||||||
|
.open = ps2_keyboard_open,
|
||||||
|
.close = ps2_keyboard_close,
|
||||||
|
.ioctl = ps2_keyboard_ioctl,
|
||||||
|
.read = ps2_keyboard_read,
|
||||||
|
.write = ps2_keyboard_write,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 键盘中断处理函数(中断上半部)
|
* @brief 键盘中断处理函数(中断上半部)
|
||||||
* 将数据存入缓冲区
|
* 将数据存入缓冲区
|
||||||
@ -49,6 +181,8 @@ void ps2_keyboard_handler(ul irq_num, ul param, struct pt_regs *regs)
|
|||||||
*kb_buf_ptr->ptr_head = x;
|
*kb_buf_ptr->ptr_head = x;
|
||||||
++(kb_buf_ptr->count);
|
++(kb_buf_ptr->count);
|
||||||
++(kb_buf_ptr->ptr_head);
|
++(kb_buf_ptr->ptr_head);
|
||||||
|
|
||||||
|
wait_queue_wakeup(&ps2_keyboard_wait_queue, PROC_UNINTERRUPTIBLE);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @brief 初始化键盘驱动程序的函数
|
* @brief 初始化键盘驱动程序的函数
|
||||||
@ -56,7 +190,7 @@ void ps2_keyboard_handler(ul irq_num, ul param, struct pt_regs *regs)
|
|||||||
*/
|
*/
|
||||||
void ps2_keyboard_init()
|
void ps2_keyboard_init()
|
||||||
{
|
{
|
||||||
|
|
||||||
// ======= 初始化键盘循环队列缓冲区 ===========
|
// ======= 初始化键盘循环队列缓冲区 ===========
|
||||||
|
|
||||||
// 申请键盘循环队列缓冲区的内存
|
// 申请键盘循环队列缓冲区的内存
|
||||||
@ -102,6 +236,8 @@ void ps2_keyboard_init()
|
|||||||
alt_l = false;
|
alt_l = false;
|
||||||
alt_r = false;
|
alt_r = false;
|
||||||
|
|
||||||
|
wait_queue_init(&ps2_keyboard_wait_queue, NULL);
|
||||||
|
|
||||||
// 注册中断处理程序
|
// 注册中断处理程序
|
||||||
irq_register(PS2_KEYBOARD_INTR_VECTOR, &entry, &ps2_keyboard_handler, (ul)kb_buf_ptr, &ps2_keyboard_intr_controller, "ps/2 keyboard");
|
irq_register(PS2_KEYBOARD_INTR_VECTOR, &entry, &ps2_keyboard_handler, (ul)kb_buf_ptr, &ps2_keyboard_intr_controller, "ps/2 keyboard");
|
||||||
kdebug("kb registered.");
|
kdebug("kb registered.");
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
// 定义键盘循环队列缓冲区大小为100bytes
|
// 定义键盘循环队列缓冲区大小为100bytes
|
||||||
#define ps2_keyboard_buffer_size 100
|
#define ps2_keyboard_buffer_size 100
|
||||||
|
|
||||||
|
#define KEYBOARD_CMD_RESET_BUFFER 1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 键盘循环队列缓冲区结构体
|
* @brief 键盘循环队列缓冲区结构体
|
||||||
*
|
*
|
||||||
|
@ -87,7 +87,7 @@ int video_init(bool level)
|
|||||||
if (level)
|
if (level)
|
||||||
{
|
{
|
||||||
// 启用双缓冲后,使能printk滚动动画
|
// 启用双缓冲后,使能printk滚动动画
|
||||||
printk_enable_animation();
|
// printk_enable_animation();
|
||||||
// 初始化第一个屏幕刷新任务
|
// 初始化第一个屏幕刷新任务
|
||||||
struct timer_func_list_t *tmp = (struct timer_func_list_t *)kmalloc(sizeof(struct timer_func_list_t), 0);
|
struct timer_func_list_t *tmp = (struct timer_func_list_t *)kmalloc(sizeof(struct timer_func_list_t), 0);
|
||||||
timer_func_init(tmp, &video_refresh_framebuffer, NULL, REFRESH_INTERVAL);
|
timer_func_init(tmp, &video_refresh_framebuffer, NULL, REFRESH_INTERVAL);
|
||||||
|
16
kernel/process/Makefile
Normal file
16
kernel/process/Makefile
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
all: procs.o process.o wait_queue.o
|
||||||
|
|
||||||
|
CFLAGS += -I .
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
procs.o: proc.S
|
||||||
|
gcc -E proc.S > proc.s
|
||||||
|
as $(ASFLAGS) -o procs.o proc.s
|
||||||
|
|
||||||
|
process.o: process.c
|
||||||
|
gcc $(CFLAGS) -c process.c -o process.o
|
||||||
|
|
||||||
|
wait_queue.o: wait_queue.c
|
||||||
|
gcc $(CFLAGS) -c wait_queue.c -o wait_queue.o
|
@ -18,12 +18,7 @@ long process_global_pid = 1; // 系统中最大的pid
|
|||||||
extern void system_call(void);
|
extern void system_call(void);
|
||||||
extern void kernel_thread_func(void);
|
extern void kernel_thread_func(void);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 将进程加入到调度器的就绪队列中
|
|
||||||
*
|
|
||||||
* @param pcb 进程的pcb
|
|
||||||
*/
|
|
||||||
static inline void process_wakeup(struct process_control_block *pcb);
|
|
||||||
|
|
||||||
ul _stack_start; // initial proc的栈基地址(虚拟地址)
|
ul _stack_start; // initial proc的栈基地址(虚拟地址)
|
||||||
struct mm_struct initial_mm = {0};
|
struct mm_struct initial_mm = {0};
|
||||||
@ -820,10 +815,12 @@ struct process_control_block *process_get_pcb(long pid)
|
|||||||
*
|
*
|
||||||
* @param pcb 进程的pcb
|
* @param pcb 进程的pcb
|
||||||
*/
|
*/
|
||||||
static inline void process_wakeup(struct process_control_block *pcb)
|
void process_wakeup(struct process_control_block *pcb)
|
||||||
{
|
{
|
||||||
pcb->state = PROC_RUNNING;
|
pcb->state = PROC_RUNNING;
|
||||||
sched_cfs_enqueue(pcb);
|
sched_cfs_enqueue(pcb);
|
||||||
|
// 将当前进程标志为需要调度,缩短新进程被wakeup的时间
|
||||||
|
current_pcb->flags |= PF_NEED_SCHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -273,6 +273,13 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
|||||||
*/
|
*/
|
||||||
struct process_control_block *process_get_pcb(long pid);
|
struct process_control_block *process_get_pcb(long pid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 将进程加入到调度器的就绪队列中
|
||||||
|
*
|
||||||
|
* @param pcb 进程的pcb
|
||||||
|
*/
|
||||||
|
void process_wakeup(struct process_control_block *pcb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 切换页表
|
* @brief 切换页表
|
||||||
* @param prev 前一个进程的pcb
|
* @param prev 前一个进程的pcb
|
||||||
|
@ -14,28 +14,8 @@
|
|||||||
|
|
||||||
#include <process/process.h>
|
#include <process/process.h>
|
||||||
#include <sched/sched.h>
|
#include <sched/sched.h>
|
||||||
|
#include "wait_queue.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 信号量的等待队列
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
struct List wait_list;
|
|
||||||
struct process_control_block *pcb;
|
|
||||||
} wait_queue_node_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 初始化信号量的等待队列
|
|
||||||
*
|
|
||||||
* @param wait_queue 等待队列
|
|
||||||
* @param pcb pcb
|
|
||||||
*/
|
|
||||||
void wait_queue_init(wait_queue_node_t *wait_queue, struct process_control_block *pcb)
|
|
||||||
{
|
|
||||||
list_init(&wait_queue->wait_list);
|
|
||||||
wait_queue->pcb = pcb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 信号量的结构体
|
* @brief 信号量的结构体
|
||||||
@ -97,5 +77,7 @@ void semaphore_up(semaphore_t *sema)
|
|||||||
|
|
||||||
wq->pcb->state = PROC_RUNNING;
|
wq->pcb->state = PROC_RUNNING;
|
||||||
sched_cfs_enqueue(wq->pcb);
|
sched_cfs_enqueue(wq->pcb);
|
||||||
|
// 当前进程缺少需要的资源,立即标为需要被调度
|
||||||
|
current_pcb->flags |= PF_NEED_SCHED;
|
||||||
}
|
}
|
||||||
}
|
}
|
65
kernel/process/wait_queue.c
Normal file
65
kernel/process/wait_queue.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#include "wait_queue.h"
|
||||||
|
#include <sched/sched.h>
|
||||||
|
#include <process/process.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化等待队列
|
||||||
|
*
|
||||||
|
* @param wait_queue 等待队列
|
||||||
|
* @param pcb pcb
|
||||||
|
*/
|
||||||
|
void wait_queue_init(wait_queue_node_t *wait_queue, struct process_control_block *pcb)
|
||||||
|
{
|
||||||
|
list_init(&wait_queue->wait_list);
|
||||||
|
wait_queue->pcb = pcb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 在等待队列上进行等待
|
||||||
|
*
|
||||||
|
* @param wait_queue_head 队列头指针
|
||||||
|
*/
|
||||||
|
void wait_queue_sleep_on(wait_queue_node_t *wait_queue_head)
|
||||||
|
{
|
||||||
|
wait_queue_node_t wait;
|
||||||
|
wait_queue_init(&wait, current_pcb);
|
||||||
|
current_pcb->state = PROC_UNINTERRUPTIBLE;
|
||||||
|
list_append(&wait_queue_head->wait_list, &wait.wait_list);
|
||||||
|
|
||||||
|
sched_cfs();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 在等待队列上进行等待(允许中断)
|
||||||
|
*
|
||||||
|
* @param wait_queue_head 队列头指针
|
||||||
|
*/
|
||||||
|
void wait_queue_sleep_on_interriptible(wait_queue_node_t * wait_queue_head)
|
||||||
|
{
|
||||||
|
wait_queue_node_t wait;
|
||||||
|
wait_queue_init(&wait, current_pcb);
|
||||||
|
current_pcb->state = PROC_INTERRUPTIBLE;
|
||||||
|
list_append(&wait_queue_head->wait_list, &wait.wait_list);
|
||||||
|
|
||||||
|
sched_cfs();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 唤醒在等待队列的头部的进程
|
||||||
|
*
|
||||||
|
* @param wait_queue_head
|
||||||
|
* @param state
|
||||||
|
*/
|
||||||
|
void wait_queue_wakeup(wait_queue_node_t * wait_queue_head, int64_t state)
|
||||||
|
{
|
||||||
|
if(list_empty(&wait_queue_head->wait_list))
|
||||||
|
return;
|
||||||
|
wait_queue_node_t * wait = container_of(list_next(&wait_queue_head->wait_list), wait_queue_node_t, wait_list);
|
||||||
|
|
||||||
|
// 符合唤醒条件
|
||||||
|
if(wait->pcb->state & state)
|
||||||
|
{
|
||||||
|
list_del(&wait->wait_list);
|
||||||
|
process_wakeup(wait->pcb);
|
||||||
|
}
|
||||||
|
}
|
42
kernel/process/wait_queue.h
Normal file
42
kernel/process/wait_queue.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <common/glib.h>
|
||||||
|
#include <process/process.h>
|
||||||
|
/**
|
||||||
|
* @brief 信号量的等待队列
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
struct List wait_list;
|
||||||
|
struct process_control_block *pcb;
|
||||||
|
} wait_queue_node_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化等待队列
|
||||||
|
*
|
||||||
|
* @param wait_queue 等待队列
|
||||||
|
* @param pcb pcb
|
||||||
|
*/
|
||||||
|
void wait_queue_init(wait_queue_node_t *wait_queue, struct process_control_block *pcb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 在等待队列上进行等待
|
||||||
|
*
|
||||||
|
* @param wait_queue_head 队列头指针
|
||||||
|
*/
|
||||||
|
void wait_queue_sleep_on(wait_queue_node_t * wait_queue_head);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 在等待队列上进行等待(允许中断)
|
||||||
|
*
|
||||||
|
* @param wait_queue_head 队列头指针
|
||||||
|
*/
|
||||||
|
void wait_queue_sleep_on_interriptible(wait_queue_node_t * wait_queue_head);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 唤醒在等待队列的头部的进程
|
||||||
|
*
|
||||||
|
* @param wait_queue_head 队列头
|
||||||
|
* @param state 要唤醒的进程的状态
|
||||||
|
*/
|
||||||
|
void wait_queue_wakeup(wait_queue_node_t * wait_queue_head, int64_t state);
|
Loading…
x
Reference in New Issue
Block a user