临界资源保护
实现方法
- 禁用中断
__attribute__((used)) static inline uint32_t read_eflags (void){
uint32_t eflags;
ASM_V("pushfntpop %%eax":"=a"(eflags));
return eflags;
}
__attribute__((used)) static inline void write_eflags (uint32_t eflags){
ASM_V("push %%eaxntpopf"::"a"(eflags));
}
EFLAGS的位9是IF位, 为1的时候开启中断, 0屏蔽中断
//临界区管理
irq_state_t irq_enter_protection (void){
//记录一下之前的中断是开启的还是关闭的
irq_state_t state = read_eflags();
state |= EFLAGS_IF;
irq_disable_global服务器托管网();
return state;
}
void irq_leave_protection (irq_state_t state){
//恢复之前的IF状态
state |= read_eflags();
write_eflags(state);
}
实际使用
//打印的时候串口是一个临界资源
void log_printf(const char * fmt, ...){
char str_buf[128];
va_list args;
//格式化处理
kernel_memset(str_buf, '', sizeof(str_buf));
va_start(args, fmt);
kernel_vsprintf(str_buf, fmt, args);
va_end(args);
const char *p = str_buf;
irq_state_t state = irq_enter_protection(); //进入临界
while(*p != '')
{
//等待串口忙标志
while((inb(COM1_PORT+ 5) & (16))== 0);
outb(COM1_PORT, *p++);
}
//自动换行
outb(COM1_PORT, 'r');
outb(COM1_PORT, 'n');
irq_leave_服务器托管网protection(state);//退出临界区
}
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net