🔧 将软中断更改为不可重入

This commit is contained in:
fslongjin
2022-07-11 10:24:35 +08:00
parent dcafbef4d4
commit f4891cc8a3
6 changed files with 72 additions and 35 deletions

View File

@ -479,9 +479,9 @@ void do_IRQ(struct pt_regs *rsp, ul number)
} }
// kdebug("before softirq"); // kdebug("before softirq");
// 检测是否有未处理的软中断 // 进入软中断处理程序
if (softirq_status != 0)
do_softirq(); do_softirq();
// kdebug("after softirq"); // kdebug("after softirq");
// 检测当前进程是否持有自旋锁,若持有自旋锁,则不进行抢占式的进程调度 // 检测当前进程是否持有自旋锁,若持有自旋锁,则不进行抢占式的进程调度
if (current_pcb->preempt_count > 0) if (current_pcb->preempt_count > 0)

View File

@ -66,7 +66,7 @@ void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
// 若当前时间比定时任务的时间间隔大,则进入中断下半部 // 若当前时间比定时任务的时间间隔大,则进入中断下半部
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((1 << TIMER_SIRQ)); raise_softirq((1 << TIMER_SIRQ));
// if (current_pcb->pid == 2) // if (current_pcb->pid == 2)
// kwarn("timer_jiffies = %ld video_refresh_expire_jiffies=%ld", timer_jiffies, video_refresh_expire_jiffies); // kwarn("timer_jiffies = %ld video_refresh_expire_jiffies=%ld", timer_jiffies, video_refresh_expire_jiffies);

View File

@ -27,22 +27,19 @@ void timer_init()
void do_timer_softirq(void *data) void do_timer_softirq(void *data)
{ {
// if(current_pcb->pid==3)
// kdebug("pid3 timer irq");
struct timer_func_list_t *tmp = container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list); struct timer_func_list_t *tmp = container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list);
while ((!list_empty(&timer_func_head.list)) && (tmp->expire_jiffies <= timer_jiffies)) while ((!list_empty(&timer_func_head.list)) && (tmp->expire_jiffies <= timer_jiffies))
{ {
if (current_pcb->pid == 2)
kdebug("pid2 timer do");
timer_func_del(tmp); timer_func_del(tmp);
tmp->func(tmp->data); tmp->func(tmp->data);
kfree(tmp); kfree(tmp);
tmp = container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list); tmp = container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list);
} }
softirq_ack(TIMER_SIRQ);
// printk_color(ORANGE, BLACK, "(HPET%ld)", timer_jiffies);
} }
/** /**

View File

@ -78,7 +78,6 @@ void video_refresh_framebuffer(void *data)
// 暂时设置一个很大的值作为屏障,防止二次进入该区域(造成#GP // 暂时设置一个很大的值作为屏障,防止二次进入该区域(造成#GP
video_refresh_expire_jiffies = timer_jiffies + 100000; video_refresh_expire_jiffies = timer_jiffies + 100000;
video_last_refresh_pid = current_pcb->pid; video_last_refresh_pid = current_pcb->pid;
softirq_ack(VIDEO_REFRESH_SIRQ);
memcpy((void *)sc_info.fb_vaddr, (void *)sc_info.double_fb_vaddr, (sc_info.length << 2)); memcpy((void *)sc_info.fb_vaddr, (void *)sc_info.double_fb_vaddr, (sc_info.length << 2));
video_refresh_expire_jiffies = cal_next_n_ms_jiffies(REFRESH_INTERVAL); video_refresh_expire_jiffies = cal_next_n_ms_jiffies(REFRESH_INTERVAL);

View File

@ -2,17 +2,52 @@
#include <common/kprint.h> #include <common/kprint.h>
#include <process/process.h> #include <process/process.h>
#include <driver/video/video.h> #include <driver/video/video.h>
uint64_t softirq_status = 0; #include <process/spinlock.h>
void set_softirq_status(uint64_t status)
static spinlock_t softirq_modify_lock; // 软中断状态status
static volatile uint64_t softirq_pending = 0;
static volatile uint64_t softirq_running = 0;
void set_softirq_pending(uint64_t status)
{ {
softirq_status |= status; softirq_pending |= status;
} }
uint64_t get_softirq_status() uint64_t get_softirq_pending()
{ {
return softirq_status; return softirq_pending;
} }
#define get_softirq_running() (softirq_running)
/**
* @brief 设置软中断运行结束
*
* @param softirq_num
*/
#define clear_softirq_running(softirq_num) \
do \
{ \
softirq_running &= (~(1 << softirq_num)); \
} while (0)
// 设置软中断的运行状态只应在do_softirq中调用此宏
#define set_softirq_running(softirq_num) \
do \
{ \
softirq_running |= (1 << softirq_num); \
} while (0)
/**
* @brief 清除软中断pending标志位
*
*/
#define softirq_ack(sirq_num) \
do \
{ \
softirq_pending &= (~(1 << sirq_num)); \
} while (0);
/** /**
* @brief 软中断注册函数 * @brief 软中断注册函数
* *
@ -44,21 +79,36 @@ void unregister_softirq(uint32_t irq_num)
void do_softirq() void do_softirq()
{ {
sti(); sti();
// video_refresh_framebuffer();
for (uint32_t i = 0; i < MAX_SOFTIRQ_NUM && softirq_status; ++i) for (uint32_t i = 0; i < MAX_SOFTIRQ_NUM && softirq_pending; ++i)
{ {
if (softirq_status & (1 << i) && softirq_vector[i].action != NULL) if (softirq_pending & (1 << i) && softirq_vector[i].action != NULL && (!(get_softirq_running() & (1 << i))))
{ {
if (spin_trylock(&softirq_modify_lock))
{
// 检测该软中断是否已经被其他进程执行
if(get_softirq_running() & (1 << i))
{
spin_unlock(&softirq_modify_lock);
continue;
}
softirq_ack(i);
set_softirq_running(i);
spin_unlock(&softirq_modify_lock);
softirq_vector[i].action(softirq_vector[i].data); softirq_vector[i].action(softirq_vector[i].data);
clear_softirq_running(i);
}
} }
} }
cli(); cli();
} }
void softirq_init() void softirq_init()
{ {
softirq_status = 0; softirq_pending = 0;
memset(softirq_vector, 0, sizeof(struct softirq_t) * MAX_SOFTIRQ_NUM); memset(softirq_vector, 0, sizeof(struct softirq_t) * MAX_SOFTIRQ_NUM);
spin_init(&softirq_modify_lock);
} }

View File

@ -24,20 +24,11 @@
#define raise_softirq(sirq_num) \ #define raise_softirq(sirq_num) \
do \ do \
{ \ { \
set_softirq_status(1 << sirq_num); \ set_softirq_pending(1 << sirq_num); \
} while (0); } while (0);
/**
* @brief 清除软中断标志位(需要软中断处理程序手动调用)
*
*/
#define softirq_ack(sirq_num) \
do \
{ \
softirq_status &= (~(1 << sirq_num)); \
} while (0);
extern uint64_t softirq_status;
struct softirq_t struct softirq_t
{ {
@ -63,8 +54,8 @@ void register_softirq(uint32_t irq_num, void (*action)(void *data), void *data);
*/ */
void unregister_softirq(uint32_t irq_num); void unregister_softirq(uint32_t irq_num);
void set_softirq_status(uint64_t status); void set_softirq_pending(uint64_t status);
uint64_t get_softirq_status(); uint64_t get_softirq_pending();
/** /**
* @brief 软中断处理程序 * @brief 软中断处理程序