mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
使用内核线程来刷新屏幕 (#57)
* 修改了test-idr的错误 * new: 修复切换双缓冲的时候的卡顿问题 Signed-off-by: guanjinquan <1666320330@qq.com> Co-authored-by: guanjinquan <1666320330@qq.com> Co-authored-by: fslongjin <longjin@RinGoTek.cn>
This commit is contained in:
parent
1b0c901ab2
commit
efa38a7d5d
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -144,7 +144,8 @@
|
||||
"ktest_utils.h": "c",
|
||||
"kthread.h": "c",
|
||||
"lockref.h": "c",
|
||||
"compiler_attributes.h": "c"
|
||||
"compiler_attributes.h": "c",
|
||||
"timer.h": "c"
|
||||
},
|
||||
"C_Cpp.errorSquiggles": "Enabled",
|
||||
"esbonio.sphinx.confDir": ""
|
||||
|
@ -439,7 +439,8 @@ void pci_init()
|
||||
{
|
||||
if (ptr->Status & 0x10)
|
||||
{
|
||||
kinfo("[ pci device %d ] class code = %d\tsubclass=%d\tstatus=%#010lx\tcap_pointer=%#010lx\tbar5=%#010lx", i, ptr->Class_code, ptr->SubClass, ptr->Status, ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer, ((struct pci_device_structure_general_device_t *)ptr)->BAR5);
|
||||
kinfo("[ pci device %d ] class code = %d\tsubclass=%d\tstatus=%#010lx\tcap_pointer=%#010lx\tbar5=%#010lx, vendor=%#08x, device id=%#08x", i, ptr->Class_code, ptr->SubClass, ptr->Status, ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer, ((struct pci_device_structure_general_device_t *)ptr)->BAR5,
|
||||
ptr->Vendor_ID, ptr->Device_ID);
|
||||
uint32_t tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer);
|
||||
}
|
||||
else
|
||||
|
@ -1,17 +1,17 @@
|
||||
#include "video.h"
|
||||
#include <mm/mm.h>
|
||||
#include <common/printk.h>
|
||||
#include <driver/multiboot2/multiboot2.h>
|
||||
#include <time/timer.h>
|
||||
#include <common/kprint.h>
|
||||
#include <common/kthread.h>
|
||||
#include <common/printk.h>
|
||||
#include <common/spinlock.h>
|
||||
#include <common/time.h>
|
||||
#include <driver/multiboot2/multiboot2.h>
|
||||
#include <driver/uart/uart.h>
|
||||
#include <exception/softirq.h>
|
||||
#include <mm/mm.h>
|
||||
#include <mm/slab.h>
|
||||
#include <common/spinlock.h>
|
||||
#include <exception/softirq.h>
|
||||
#include <driver/uart/uart.h>
|
||||
#include <common/time.h>
|
||||
|
||||
|
||||
#include <process/process.h>
|
||||
#include <sched/sched.h>
|
||||
#include <time/timer.h>
|
||||
|
||||
uint64_t video_refresh_expire_jiffies = 0;
|
||||
uint64_t video_last_refresh_pid = -1;
|
||||
@ -19,10 +19,11 @@ uint64_t video_last_refresh_pid = -1;
|
||||
struct scm_buffer_info_t video_frame_buffer_info = {0};
|
||||
static struct multiboot_tag_framebuffer_info_t __fb_info;
|
||||
static struct scm_buffer_info_t *video_refresh_target = NULL;
|
||||
static struct process_control_block *video_daemon_pcb = NULL;
|
||||
static spinlock_t daemon_refresh_lock;
|
||||
|
||||
#define REFRESH_INTERVAL 15UL // 启动刷新帧缓冲区任务的时间间隔
|
||||
|
||||
|
||||
/**
|
||||
* @brief VBE帧缓存区的地址重新映射
|
||||
* 将帧缓存区映射到地址SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE处
|
||||
@ -37,22 +38,53 @@ void init_frame_buffer()
|
||||
int reserved;
|
||||
|
||||
video_frame_buffer_info.vaddr = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + FRAME_BUFFER_MAPPING_OFFSET;
|
||||
mm_map_proc_page_table(global_CR3, true, video_frame_buffer_info.vaddr, __fb_info.framebuffer_addr, video_frame_buffer_info.size, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, false, true, false);
|
||||
mm_map_proc_page_table(global_CR3, true, video_frame_buffer_info.vaddr, __fb_info.framebuffer_addr,
|
||||
video_frame_buffer_info.size, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, false, true, false);
|
||||
|
||||
flush_tlb();
|
||||
kinfo("VBE frame buffer successfully Re-mapped!");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 刷新帧缓冲区
|
||||
*
|
||||
* @brief video守护进程, 按时刷新帧缓冲区
|
||||
* @param unused
|
||||
* @return int
|
||||
*/
|
||||
int video_refresh_daemon(void *unused)
|
||||
{
|
||||
// 初始化锁, 这个锁只会在daemon中使用
|
||||
spin_init(&daemon_refresh_lock);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (clock() >= video_refresh_expire_jiffies)
|
||||
{
|
||||
video_refresh_expire_jiffies = cal_next_n_ms_jiffies(REFRESH_INTERVAL << 1);
|
||||
|
||||
if (likely(video_refresh_target != NULL))
|
||||
{
|
||||
spin_lock(&daemon_refresh_lock);
|
||||
memcpy((void *)video_frame_buffer_info.vaddr, (void *)video_refresh_target->vaddr,
|
||||
video_refresh_target->size);
|
||||
spin_unlock(&daemon_refresh_lock);
|
||||
}
|
||||
}
|
||||
video_daemon_pcb->flags &= ~PROC_RUNNING;
|
||||
sched();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 唤醒video的守护进程
|
||||
*/
|
||||
void video_refresh_framebuffer(void *data)
|
||||
{
|
||||
video_refresh_expire_jiffies = cal_next_n_ms_jiffies(REFRESH_INTERVAL << 1);
|
||||
if (unlikely(video_refresh_target == NULL))
|
||||
if (unlikely(video_daemon_pcb == NULL))
|
||||
return;
|
||||
memcpy((void *)video_frame_buffer_info.vaddr, (void *)video_refresh_target->vaddr, video_refresh_target->size);
|
||||
|
||||
process_wakeup(video_daemon_pcb);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,17 +94,22 @@ void video_refresh_framebuffer(void *data)
|
||||
* true ->高级初始化:增加double buffer的支持
|
||||
* @return int
|
||||
*/
|
||||
int video_reinitialize(bool level)
|
||||
int video_reinitialize(bool level) // 这个函数会在main.c调用, 保证 video_init() 先被调用
|
||||
{
|
||||
if (level == false)
|
||||
init_frame_buffer();
|
||||
else
|
||||
{
|
||||
// 计算开始时间
|
||||
video_refresh_expire_jiffies = cal_next_n_ms_jiffies(10 * REFRESH_INTERVAL);
|
||||
|
||||
// 创建video守护进程
|
||||
video_daemon_pcb = kthread_run(&video_refresh_daemon, NULL, CLONE_FS | CLONE_SIGNAL);
|
||||
video_daemon_pcb->virtual_runtime = 0; // 特殊情况, 最高优先级, 以后再改
|
||||
|
||||
// 启用屏幕刷新软中断
|
||||
register_softirq(VIDEO_REFRESH_SIRQ, &video_refresh_framebuffer, NULL);
|
||||
|
||||
video_refresh_expire_jiffies = cal_next_n_ms_jiffies(10 * REFRESH_INTERVAL);
|
||||
|
||||
raise_softirq(VIDEO_REFRESH_SIRQ);
|
||||
}
|
||||
return 0;
|
||||
@ -88,12 +125,16 @@ int video_set_refresh_target(struct scm_buffer_info_t *buf)
|
||||
{
|
||||
|
||||
unregister_softirq(VIDEO_REFRESH_SIRQ);
|
||||
int counter = 100;
|
||||
while ((get_softirq_pending() & (1 << VIDEO_REFRESH_SIRQ)) && counter > 0)
|
||||
{
|
||||
--counter;
|
||||
usleep(1000);
|
||||
}
|
||||
// todo: 在completion实现后,在这里等待其他刷新任务完成,再进行下一步。
|
||||
|
||||
// int counter = 100;
|
||||
|
||||
// while ((get_softirq_pending() & (1 << VIDEO_REFRESH_SIRQ)) && counter > 0)
|
||||
// {
|
||||
// --counter;
|
||||
// usleep(1000);
|
||||
// }
|
||||
// kdebug("buf = %#018lx", buf);
|
||||
video_refresh_target = buf;
|
||||
register_softirq(VIDEO_REFRESH_SIRQ, &video_refresh_framebuffer, NULL);
|
||||
raise_softirq(VIDEO_REFRESH_SIRQ);
|
||||
@ -134,14 +175,17 @@ int video_init()
|
||||
video_frame_buffer_info.height = __fb_info.framebuffer_height;
|
||||
io_mfence();
|
||||
|
||||
video_frame_buffer_info.size = video_frame_buffer_info.width * video_frame_buffer_info.height * ((video_frame_buffer_info.bit_depth + 7) / 8);
|
||||
video_frame_buffer_info.size =
|
||||
video_frame_buffer_info.width * video_frame_buffer_info.height * ((video_frame_buffer_info.bit_depth + 7) / 8);
|
||||
// 先临时映射到该地址,稍后再重新映射
|
||||
video_frame_buffer_info.vaddr = 0xffff800003000000;
|
||||
mm_map_phys_addr(video_frame_buffer_info.vaddr, __fb_info.framebuffer_addr, video_frame_buffer_info.size, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, false);
|
||||
mm_map_phys_addr(video_frame_buffer_info.vaddr, __fb_info.framebuffer_addr, video_frame_buffer_info.size,
|
||||
PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, false);
|
||||
|
||||
io_mfence();
|
||||
char init_text2[] = "Video driver initialized.";
|
||||
for (int i = 0; i < sizeof(init_text2) - 1; ++i)
|
||||
uart_send(COM1, init_text2[i]);
|
||||
|
||||
return 0;
|
||||
}
|
@ -33,7 +33,7 @@ static long ktest_idr_case0(uint64_t arg0, uint64_t arg1)
|
||||
idr_init(&k_idr);
|
||||
assert(k_idr.id_free_cnt == 0);
|
||||
|
||||
assert(idr_pre_get(&k_idr, 0) == 1);
|
||||
assert(idr_pre_get(&k_idr, 0) == 0);
|
||||
assert(k_idr.id_free_cnt == IDR_FREE_MAX);
|
||||
|
||||
for (int i = 1; i < 64; i++)
|
||||
|
@ -1,12 +1,12 @@
|
||||
#include "screen_manager.h"
|
||||
#include <common/string.h>
|
||||
#include <driver/multiboot2/multiboot2.h>
|
||||
#include <common/kprint.h>
|
||||
#include <common/spinlock.h>
|
||||
#include <mm/mm.h>
|
||||
#include <mm/slab.h>
|
||||
#include <common/string.h>
|
||||
#include <driver/multiboot2/multiboot2.h>
|
||||
#include <driver/uart/uart.h>
|
||||
#include <driver/video/video.h>
|
||||
#include <mm/mm.h>
|
||||
#include <mm/slab.h>
|
||||
|
||||
extern struct scm_buffer_info_t video_frame_buffer_info;
|
||||
static struct List scm_framework_list;
|
||||
@ -234,35 +234,43 @@ int scm_enable_alloc()
|
||||
*/
|
||||
int scm_enable_double_buffer()
|
||||
{
|
||||
if (__scm_double_buffer_enabled == true)
|
||||
if (__scm_double_buffer_enabled == true) // 已经开启了双缓冲区了, 直接退出
|
||||
return 0;
|
||||
__scm_double_buffer_enabled = true;
|
||||
if (list_empty(&scm_framework_list))
|
||||
if (list_empty(&scm_framework_list)) // scm 框架链表为空
|
||||
return 0;
|
||||
|
||||
// 逐个检查已经注册了的ui框架,将其缓冲区更改为双缓冲
|
||||
struct scm_ui_framework_t *ptr = container_of(list_next(&scm_framework_list), struct scm_ui_framework_t, list);
|
||||
// 这里的ptr不需要特判空指针吗 问题1
|
||||
do
|
||||
{
|
||||
if (ptr->buf == &video_frame_buffer_info)
|
||||
{
|
||||
uart_send_str(COM1, "##init double buffer##");
|
||||
uart_send_str(COM1, "##init double buffer##\n");
|
||||
struct scm_buffer_info_t *buf = __create_buffer(SCM_BF_DB | SCM_BF_PIXEL);
|
||||
if ((uint64_t)(buf) == (uint64_t)-ENOMEM)
|
||||
return -ENOMEM;
|
||||
uart_send_str(COM1, "##to change double buffer##");
|
||||
if (ptr->ui_ops->change(buf) != 0)
|
||||
uart_send_str(COM1, "##to change double buffer##\n");
|
||||
|
||||
if (ptr->ui_ops->change(buf) != 0) // 这里的change回调函数不会是空指针吗 问题2
|
||||
{
|
||||
|
||||
__destroy_buffer(buf);
|
||||
kfree(buf);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
} while (list_next(&ptr->list) != &scm_framework_list);
|
||||
|
||||
} while (list_next(&ptr->list) != &scm_framework_list); // 枚举链表的每一个ui框架
|
||||
|
||||
|
||||
// 设置定时刷新的对象
|
||||
video_set_refresh_target(__current_framework->buf);
|
||||
// 通知显示驱动,启动双缓冲
|
||||
video_reinitialize(true);
|
||||
uart_send_str(COM1, "##initialized double buffer##");
|
||||
uart_send_str(COM1, "##initialized double buffer##\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
#include "textui.h"
|
||||
|
||||
#include "screen_manager.h"
|
||||
#include "driver/uart/uart.h"
|
||||
#include <common/string.h>
|
||||
#include <common/printk.h>
|
||||
#include "screen_manager.h"
|
||||
#include <common/atomic.h>
|
||||
#include <common/errno.h>
|
||||
#include <common/printk.h>
|
||||
#include <common/string.h>
|
||||
|
||||
struct scm_ui_framework_t textui_framework;
|
||||
static spinlock_t __window_id_lock = {1};
|
||||
@ -19,6 +19,7 @@ static struct textui_vline_chromatic_t __initial_vlines[INITIAL_VLINES] = {0};
|
||||
static struct textui_window_t __initial_window = {0}; // 初始窗口
|
||||
static struct textui_private_info_t __private_info = {0};
|
||||
static struct List __windows_list;
|
||||
static spinlock_t change_lock;
|
||||
|
||||
/**
|
||||
* @brief 初始化window对象
|
||||
@ -29,7 +30,8 @@ static struct List __windows_list;
|
||||
* @param vlines_ptr 虚拟行数组指针
|
||||
* @param cperline 每行最大的字符数
|
||||
*/
|
||||
static int __textui_init_window(struct textui_window_t *window, uint8_t flags, uint16_t vlines_num, void *vlines_ptr, uint16_t cperline)
|
||||
static int __textui_init_window(struct textui_window_t *window, uint8_t flags, uint16_t vlines_num, void *vlines_ptr,
|
||||
uint16_t cperline)
|
||||
{
|
||||
memset((window), 0, sizeof(struct textui_window_t));
|
||||
list_init(&(window)->list);
|
||||
@ -56,12 +58,12 @@ static int __textui_init_window(struct textui_window_t *window, uint8_t flags, u
|
||||
* @param vline 虚拟行对象指针
|
||||
* @param chars_ptr 字符对象数组指针
|
||||
*/
|
||||
#define __textui_init_vline(vline, chars_ptr) \
|
||||
do \
|
||||
{ \
|
||||
memset(vline, 0, sizeof(struct textui_vline_chromatic_t)); \
|
||||
(vline)->index = 0; \
|
||||
(vline)->chars = chars_ptr; \
|
||||
#define __textui_init_vline(vline, chars_ptr) \
|
||||
do \
|
||||
{ \
|
||||
memset(vline, 0, sizeof(struct textui_vline_chromatic_t)); \
|
||||
(vline)->index = 0; \
|
||||
(vline)->chars = chars_ptr; \
|
||||
} while (0)
|
||||
|
||||
int textui_install_handler(struct scm_buffer_info_t *buf)
|
||||
@ -78,7 +80,7 @@ int textui_uninstall_handler(void *args)
|
||||
|
||||
int textui_enable_handler(void *args)
|
||||
{
|
||||
uart_send_str(COM1, "textui_enable_handler");
|
||||
uart_send_str(COM1, "textui_enable_handler\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -91,16 +93,16 @@ int textui_change_handler(struct scm_buffer_info_t *buf)
|
||||
{
|
||||
memcpy((void *)buf->vaddr, (void *)(textui_framework.buf->vaddr), textui_framework.buf->size);
|
||||
textui_framework.buf = buf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct scm_ui_framework_operations_t textui_ops =
|
||||
{
|
||||
.install = &textui_install_handler,
|
||||
.uninstall = &textui_uninstall_handler,
|
||||
.change = &textui_change_handler,
|
||||
.enable = &textui_enable_handler,
|
||||
.disable = &textui_disable_handler,
|
||||
struct scm_ui_framework_operations_t textui_ops = {
|
||||
.install = &textui_install_handler,
|
||||
.uninstall = &textui_uninstall_handler,
|
||||
.change = &textui_change_handler,
|
||||
.enable = &textui_enable_handler,
|
||||
.disable = &textui_disable_handler,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -166,7 +168,8 @@ static int __textui_new_line(struct textui_window_t *window, uint16_t vline_id)
|
||||
* @param character
|
||||
* @return int
|
||||
*/
|
||||
static int __textui_putchar_window(struct textui_window_t *window, uint16_t character, uint32_t FRcolor, uint32_t BKcolor)
|
||||
static int __textui_putchar_window(struct textui_window_t *window, uint16_t character, uint32_t FRcolor,
|
||||
uint32_t BKcolor)
|
||||
{
|
||||
if (textui_is_chromatic(window->flags)) // 启用彩色字符
|
||||
{
|
||||
@ -246,7 +249,8 @@ int textui_putchar_window(struct textui_window_t *window, uint16_t character, ui
|
||||
if (window->vlines.chromatic[window->vline_operating].index <= 0)
|
||||
{
|
||||
window->vlines.chromatic[window->vline_operating].index = 0;
|
||||
memset(window->vlines.chromatic[window->vline_operating].chars, 0, sizeof(struct textui_char_chromatic_t) * window->chars_per_line);
|
||||
memset(window->vlines.chromatic[window->vline_operating].chars, 0,
|
||||
sizeof(struct textui_char_chromatic_t) * window->chars_per_line);
|
||||
--(window->vline_operating);
|
||||
if (unlikely(window->vline_operating < 0))
|
||||
window->vline_operating = window->vlines_num - 1;
|
||||
@ -295,6 +299,8 @@ int textui_putchar(uint16_t character, uint32_t FRcolor, uint32_t BKcolor)
|
||||
*/
|
||||
int textui_init()
|
||||
{
|
||||
spin_init(&change_lock);
|
||||
|
||||
spin_init(&__window_id_lock);
|
||||
__window_max_id = 0;
|
||||
list_init(&__windows_list);
|
||||
|
@ -165,7 +165,7 @@ void system_initialize()
|
||||
|
||||
process_init();
|
||||
// 启用double buffer
|
||||
scm_enable_double_buffer();
|
||||
// scm_enable_double_buffer(); // 因为时序问题, 该函数调用被移到 initial_kernel_thread
|
||||
io_mfence();
|
||||
|
||||
// fat32_init();
|
||||
|
@ -1,29 +1,29 @@
|
||||
#include "process.h"
|
||||
|
||||
#include <common/printk.h>
|
||||
#include <common/kprint.h>
|
||||
#include <common/stdio.h>
|
||||
#include <common/string.h>
|
||||
#include <common/compiler.h>
|
||||
#include <common/elf.h>
|
||||
#include <common/kprint.h>
|
||||
#include <common/kthread.h>
|
||||
#include <common/time.h>
|
||||
#include <common/printk.h>
|
||||
#include <common/spinlock.h>
|
||||
#include <common/stdio.h>
|
||||
#include <common/string.h>
|
||||
#include <common/sys/wait.h>
|
||||
#include <driver/video/video.h>
|
||||
#include <common/time.h>
|
||||
#include <common/unistd.h>
|
||||
#include <debug/bug.h>
|
||||
#include <debug/traceback/traceback.h>
|
||||
#include <driver/disk/ahci/ahci.h>
|
||||
#include <driver/usb/usb.h>
|
||||
#include <driver/video/video.h>
|
||||
#include <exception/gate.h>
|
||||
#include <filesystem/fat32/fat32.h>
|
||||
#include <filesystem/devfs/devfs.h>
|
||||
#include <filesystem/fat32/fat32.h>
|
||||
#include <filesystem/rootfs/rootfs.h>
|
||||
#include <mm/slab.h>
|
||||
#include <common/spinlock.h>
|
||||
#include <sched/sched.h>
|
||||
#include <syscall/syscall.h>
|
||||
#include <syscall/syscall_num.h>
|
||||
#include <sched/sched.h>
|
||||
#include <common/unistd.h>
|
||||
#include <debug/traceback/traceback.h>
|
||||
#include <debug/bug.h>
|
||||
#include <driver/disk/ahci/ahci.h>
|
||||
|
||||
#include <ktest/ktest.h>
|
||||
|
||||
@ -372,7 +372,7 @@ ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
|
||||
// 独立的地址空间才能使新程序正常运行
|
||||
if (current_pcb->flags & PF_VFORK)
|
||||
{
|
||||
kdebug("proc:%d creating new mem space", current_pcb->pid);
|
||||
// kdebug("proc:%d creating new mem space", current_pcb->pid);
|
||||
// 分配新的内存空间分布结构体
|
||||
struct mm_struct *new_mms = (struct mm_struct *)kmalloc(sizeof(struct mm_struct), 0);
|
||||
memset(new_mms, 0, sizeof(struct mm_struct));
|
||||
@ -479,7 +479,9 @@ exec_failed:;
|
||||
#pragma GCC optimize("O0")
|
||||
ul initial_kernel_thread(ul arg)
|
||||
{
|
||||
// kinfo("initial proc running...\targ:%#018lx", arg);
|
||||
kinfo("initial proc running...\targ:%#018lx", arg);
|
||||
|
||||
scm_enable_double_buffer();
|
||||
|
||||
ahci_init();
|
||||
fat32_init();
|
||||
@ -582,7 +584,7 @@ ul process_do_exit(ul code)
|
||||
* @return int
|
||||
*/
|
||||
|
||||
pid_t kernel_thread(int (*fn)(void*), void* arg, unsigned long flags)
|
||||
pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
|
||||
{
|
||||
struct pt_regs regs;
|
||||
barrier();
|
||||
@ -794,13 +796,16 @@ struct process_control_block *process_get_pcb(long pid)
|
||||
*/
|
||||
int process_wakeup(struct process_control_block *pcb)
|
||||
{
|
||||
// kdebug("pcb pid = %#018lx", pcb->pid);
|
||||
|
||||
BUG_ON(pcb == NULL);
|
||||
if (pcb == current_pcb || pcb == NULL)
|
||||
return -EINVAL;
|
||||
// 如果pcb正在调度队列中,则不重复加入调度队列
|
||||
if (pcb->state == PROC_RUNNING)
|
||||
if (pcb->state & PROC_RUNNING)
|
||||
return 0;
|
||||
pcb->state = PROC_RUNNING;
|
||||
|
||||
pcb->state |= PROC_RUNNING;
|
||||
sched_enqueue(pcb);
|
||||
return 0;
|
||||
}
|
||||
@ -812,7 +817,7 @@ int process_wakeup(struct process_control_block *pcb)
|
||||
*/
|
||||
int process_wakeup_immediately(struct process_control_block *pcb)
|
||||
{
|
||||
if (pcb->state == PROC_RUNNING)
|
||||
if (pcb->state & PROC_RUNNING)
|
||||
return 0;
|
||||
int retval = process_wakeup(pcb);
|
||||
if (retval != 0)
|
||||
|
@ -69,10 +69,10 @@ void sched_cfs()
|
||||
current_pcb->flags &= ~PF_NEED_SCHED;
|
||||
struct process_control_block *proc = sched_cfs_dequeue();
|
||||
// kdebug("sched_cfs_ready_queue[proc_current_cpu_id].count = %d", sched_cfs_ready_queue[proc_current_cpu_id].count);
|
||||
if (current_pcb->virtual_runtime >= proc->virtual_runtime || current_pcb->state != PROC_RUNNING) // 当前进程运行时间大于了下一进程的运行时间,进行切换
|
||||
if (current_pcb->virtual_runtime >= proc->virtual_runtime || !(current_pcb->state & PROC_RUNNING)) // 当前进程运行时间大于了下一进程的运行时间,进行切换
|
||||
{
|
||||
|
||||
if (current_pcb->state == PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
|
||||
if (current_pcb->state & PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
|
||||
sched_cfs_enqueue(current_pcb);
|
||||
// kdebug("proc->pid=%d, count=%d", proc->pid, sched_cfs_ready_queue[proc_current_cpu_id].count);
|
||||
if (sched_cfs_ready_queue[proc_current_cpu_id].cpu_exec_proc_jiffies <= 0)
|
||||
|
@ -7,9 +7,9 @@
|
||||
uint64_t volatile timer_jiffies = 0; // 系统时钟计数
|
||||
|
||||
// 计算接下来n毫秒对应的系统时间片
|
||||
#define cal_next_n_ms_jiffies(expire_ms) (timer_jiffies + 1000*expire_ms)
|
||||
#define cal_next_n_ms_jiffies(expire_ms) (timer_jiffies + 1000 * (expire_ms))
|
||||
// 计算接下来n微秒对应的系统时间片
|
||||
#define cal_next_n_us_jiffies(expire_us) (timer_jiffies + expire_us)
|
||||
#define cal_next_n_us_jiffies(expire_us) (timer_jiffies + (expire_us))
|
||||
|
||||
void timer_init();
|
||||
|
||||
@ -62,5 +62,4 @@ void timer_func_add(struct timer_func_list_t *timer_func);
|
||||
*/
|
||||
void timer_func_del(struct timer_func_list_t *timer_func);
|
||||
|
||||
|
||||
uint64_t clock();
|
||||
|
Loading…
x
Reference in New Issue
Block a user