浏览代码

:new: 具有中断管理功能的自旋锁

fslongjin 2 年之前
父节点
当前提交
77d4854db7
共有 3 个文件被更改,包括 70 次插入21 次删除
  1. 15 19
      kernel/common/printk.c
  2. 1 1
      kernel/common/printk.h
  3. 54 1
      kernel/process/spinlock.h

+ 15 - 19
kernel/common/printk.c

@@ -635,9 +635,9 @@ static void putchar(uint *fb, int Xsize, int x, int y, unsigned int FRcolor, uns
      * @param font 字符的bitmap
      */
 
-//#if DEBUG
+    //#if DEBUG
     uart_send(COM1, font);
-//#endif
+    //#endif
 
     unsigned char *font_ptr = font_ascii[font];
     unsigned int *addr;
@@ -664,24 +664,23 @@ static void putchar(uint *fb, int Xsize, int x, int y, unsigned int FRcolor, uns
     }
 }
 
+/**
+ * @brief 格式化打印字符串
+ *
+ * @param FRcolor 前景色
+ * @param BKcolor 背景色
+ * @param ... 格式化字符串
+ */
 int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char *fmt, ...)
 {
-    /**
-     * @brief 格式化打印字符串
-     *
-     * @param FRcolor 前景色
-     * @param BKcolor 背景色
-     * @param ... 格式化字符串
-     */
 
-    /*
-    if (get_rflags() & 0x200UL)
-        spin_lock(&printk_lock); // 不是中断处理程序调用printk,加锁
-        */
+    
+    uint64_t rflags = 0;    // 加锁后rflags存储到这里
+    spin_lock_irqsave(&printk_lock, rflags);
 
     va_list args;
     va_start(args, fmt);
-
+    char buf[4096]; // vsprintf()的缓冲区
     int len = vsprintf(buf, fmt, args);
 
     va_end(args);
@@ -734,10 +733,7 @@ int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char *fmt, ..
         }
     }
 
-    /*
-    if (get_rflags() & 0x200UL)
-        spin_unlock(&printk_lock);
-        */
+    spin_unlock_irqrestore(&printk_lock, rflags);
     return i;
 }
 
@@ -838,7 +834,7 @@ int scroll(bool direction, int pixels, bool animation)
             do_scroll(direction, delta_x);
         }
     }
-
+    
     return 0;
 }
 

+ 1 - 1
kernel/common/printk.h

@@ -52,7 +52,7 @@ struct screen_info
 
 extern unsigned char font_ascii[256][16]; //导出ascii字体的bitmap(8*16大小) ps:位于font.h中
 
-char buf[4096]; // vsprintf()的缓冲区
+
 
 /**
  * @brief 初始化printk的屏幕信息

+ 54 - 1
kernel/process/spinlock.h

@@ -76,4 +76,57 @@ long spin_trylock(spinlock_t *lock)
     if (!tmp_val)
         preempt_enable();
     return tmp_val;
-}
+}
+
+// 保存当前rflags的值到变量x内并关闭中断
+#define local_irq_save(x) __asm__ __volatile__("pushfq ; popq %0 ; cli" \
+                                               : "=g"(x)::"memory")
+// 恢复先前保存的rflags的值x
+#define local_irq_restore(x) __asm__ __volatile__("pushq %0 ; popfq" ::"g"(x) \
+                                                  : "memory")
+#define local_irq_disable() cli();
+#define local_irq_enable() sti();
+
+/**
+ * @brief 保存中断状态,关闭中断,并自旋锁加锁
+ * 
+ */
+#define spin_lock_irqsave(lock, flags) \
+    do                                 \
+    {                                  \
+        local_irq_save(flags);         \
+        spin_lock(lock);               \
+    } while (0)
+
+/**
+ * @brief 恢复rflags以及中断状态并解锁自旋锁
+ * 
+ */
+#define spin_unlock_irqrestore(lock, flags) \
+    do                                      \
+    {                                       \
+        spin_unlock(lock);                  \
+        local_irq_restore(flags);           \
+    } while (0)
+
+/**
+ * @brief 关闭中断并加锁
+ * 
+ */
+#define spin_lock_irq(lock)  \
+    do                       \
+    {                        \
+        local_irq_disable(); \
+        spin_lock(lock);     \
+    } while (0)
+
+/**
+ * @brief 解锁并开启中断
+ * 
+ */
+#define spin_unlock_irq(lock) \
+    do                        \
+    {                         \
+        spin_unlock(lock);    \
+        local_irq_enable();   \
+    } while (0)