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

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

@ -2,17 +2,52 @@
#include <common/kprint.h>
#include <process/process.h>
#include <driver/video/video.h>
uint64_t softirq_status = 0;
void set_softirq_status(uint64_t status)
#include <process/spinlock.h>
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 软中断注册函数
*
@ -44,21 +79,36 @@ void unregister_softirq(uint32_t irq_num)
void do_softirq()
{
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))))
{
softirq_vector[i].action(softirq_vector[i].data);
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);
clear_softirq_running(i);
}
}
}
cli();
}
void softirq_init()
{
softirq_status = 0;
softirq_pending = 0;
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) \
do \
{ \
set_softirq_status(1 << sirq_num); \
set_softirq_pending(1 << sirq_num); \
} while (0);
/**
* @brief 清除软中断标志位(需要软中断处理程序手动调用)
*
*/
#define softirq_ack(sirq_num) \
do \
{ \
softirq_status &= (~(1 << sirq_num)); \
} while (0);
extern uint64_t softirq_status;
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 set_softirq_status(uint64_t status);
uint64_t get_softirq_status();
void set_softirq_pending(uint64_t status);
uint64_t get_softirq_pending();
/**
* @brief 软中断处理程序