]> Zhao Yanbai Git Server - kernel.git/commitdiff
初步添加 buffer 相关逻辑
authoracevest <zhaoyanbai@126.com>
Wed, 18 Oct 2023 01:35:51 +0000 (09:35 +0800)
committeracevest <zhaoyanbai@126.com>
Sat, 13 Apr 2024 08:10:32 +0000 (16:10 +0800)
15 files changed:
drivers/block.c
drivers/console.c
fs/buffer.c [new file with mode: 0644]
include/buffer.h
include/completion.h
include/disk.h
include/fs.h
include/list.h
include/semaphore.h
include/wait.h
kernel/buffer.c [deleted file]
kernel/completion.c
kernel/semaphore.c
kernel/setup.c
kernel/wait.c

index baacea91fe3a94a365d6dfc6e74138aba267c38f..674e57e8243f09d801f236fe555cee998dccb833 100644 (file)
@@ -7,22 +7,13 @@
  * ------------------------------------------------------------------------
  */
 
+#include <buffer.h>
 #include <disk.h>
 #include <fs.h>
 #include <ide.h>
 
-#define BLOCK_BUFFER_HASH_TABLE_SIZE 37
-atomic_t hash_cnt;
-blk_buffer_t *block_buffer_hash_table[BLOCK_BUFFER_HASH_TABLE_SIZE] = {
-    0,
-};
-
-int hash(dev_t dev, uint32_t block) { return ((~dev) ^ block) % BLOCK_BUFFER_HASH_TABLE_SIZE; }
-
-blk_buffer_t *get_hash_block_buffer(dev_t dev, uint32_t block, uint16_t size) {}
-
-blk_buffer_t *block_read(dev_t dev, uint32_t block) {
-    blk_buffer_t *bb = 0;
+bbuffer_t *block_read(dev_t dev, uint32_t block) {
+    bbuffer_t *bb = 0;
 
     assert(DEV_MAJOR(dev) == DEV_MAJOR_DISK);
     // assert(DEV_MINOR(dev) == 1);
@@ -51,7 +42,7 @@ void ata_read_ext2_sb() {
     const int size = offset + 1024;
     const int block = 1;
 
-    blk_buffer_t *bb = block_read(system.root_dev, block);
+    bbuffer_t *bb = block_read(system.root_dev, block);
 
     ext2_sb_t *p = (ext2_sb_t *)(bb->data + offset);
     printk("inodes count %u inodes per group %u free %u\n", p->s_inodes_count, p->s_inodes_per_group,
index c186740513ee58706dd8cbc421c503eae6f44b2c..85dcfe884e0ef6230736dcf8ff07d16c0fee1d38 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <console.h>
 #include <sched.h>
+#include <semaphore.h>
 #include <string.h>
 #include <tty.h>
 #include <wait.h>
@@ -56,13 +57,14 @@ static void cnsl_queue_init(cnsl_queue_t *cq) {
     init_wait_queue_head(&cq->wait);
 }
 
-wait_queue_head_t rdwq;
-
+// wait_queue_head_t rdwq;
+semaphore_t sem;
 void cnsl_init() {
     cnsl_queue_init(&cnsl.rd_q);
     cnsl_queue_init(&cnsl.wr_q);
     cnsl_queue_init(&cnsl.sc_q);
-    init_wait_queue_head(&rdwq);
+    // init_wait_queue_head(&rdwq);
+    semaphore_init(&sem, 0);
 }
 
 int cnsl_kbd_write(char ch) {
@@ -87,7 +89,8 @@ int cnsl_kbd_write(char ch) {
         clear(&cnsl.wr_q);
         return 0;  // TODO FIX
         while (get(&cnsl.sc_q, &ch)) put(&cnsl.rd_q, ch);
-        wake_up(&rdwq);
+        // wake_up(&rdwq);
+        up(&sem);
     }
 }
 
@@ -98,6 +101,21 @@ int cnsl_read(char *buf, size_t count) {
     int cnt = 0;
     for (cnt = 0; cnt < count;) {
         char ch;
+#if 1
+        while (true) {
+            down(&sem);
+
+            bool r = get(&cnsl.rd_q, &ch);
+            if (r) {
+                buf[cnt++] = ch;
+                if (ch == '\n') {
+                    goto end;
+                }
+            } else {
+                break;
+            }
+        }
+#else
         task_union *task = current;
         DECLARE_WAIT_QUEUE(wait, task);
         add_wait_queue(&rdwq, &wait);
@@ -121,6 +139,7 @@ int cnsl_read(char *buf, size_t count) {
 
             schedule();
         }
+#endif
     }
 
 end:
diff --git a/fs/buffer.c b/fs/buffer.c
new file mode 100644 (file)
index 0000000..a5f0777
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * ------------------------------------------------------------------------
+ *   File Name: buffer.c
+ *      Author: Zhao Yanbai
+ *              2023-06-20 19:30:33 Tuesday CST
+ * Description: 目前只支持只读,因此可以先写得简单一点
+ * ------------------------------------------------------------------------
+ */
+
+#include <buffer.h>
+#include <irq.h>
+
+#define MAX_BBUFFER_CNT 985
+
+#define BLOCK_BUFFER_HASH_TABLE_SIZE 211
+// atomic_t hash_cnt;
+list_head_t block_buffer_hash_table[BLOCK_BUFFER_HASH_TABLE_SIZE] = {
+    0,
+};
+
+int hashfn(dev_t dev, uint32_t block) { return ((dev) ^ block) % BLOCK_BUFFER_HASH_TABLE_SIZE; }
+
+typedef struct bbuffer_store {
+    int blocksize;
+    // list_head_t cache_list;
+    list_head_t free_list;
+} bbuffer_store_t;
+
+// 1024, 2048, 4096
+bbuffer_store_t store[3] = {0};
+
+kmem_cache_t *bbufer_kmem_cache = 0;
+
+bbuffer_store_t *getstore(uint32_t size) {
+    assert(size == 1024 || size == 2048 || size == 4096);
+
+    bbuffer_store_t *s = 0;
+
+    if (1024 == size) {
+        s = store + 0;
+    } else if (2048 == size) {
+        s = store + 1;
+    } else if (4096 == size) {
+        s = store + 2;
+    }
+
+    assert(0 != s);
+
+    return s;
+}
+
+bbuffer_t *get_from_hash_table(dev_t dev, uint64_t block, uint32_t size) {
+    list_head_t *p = 0;
+    uint32_t hash = hashfn(dev, block);
+    assert(hash < BLOCK_BUFFER_HASH_TABLE_SIZE);
+    list_for_each(p, block_buffer_hash_table + hash) {
+        bbuffer_t *b = list_entry(p, bbuffer_t, node);
+        if (b->dev != dev) {
+            continue;
+        }
+
+        if (b->block != block) {
+            continue;
+        }
+
+        assert(b->block_size == size);
+
+        break;
+    }
+
+    // 如果找到了就直接返回
+    if (0 != p) {
+        bbuffer_t *b = list_entry(p, bbuffer_t, node);
+        atomic_inc(&b->ref_count);
+        assert(0 != b);
+        assert(0 != b->data);
+
+        // 等待buffer的lock释放
+        // wait on b
+        return b;
+    }
+
+    return NULL;
+}
+
+bbuffer_t *getblk(dev_t dev, uint64_t block, uint32_t size) {
+    assert(size == 1024 || size == 2048 || size == 4096);
+
+    // 暂时先只支持hard disk
+    assert(DEV_MAJOR(dev) == DEV_MAJOR_DISK);
+
+    int retry = 0;
+again:
+    uint32_t iflags;
+    irq_save(iflags);
+
+    // 先尝试从hash里分配
+    bbuffer_t *b = get_from_hash_table(dev, block, size);
+    if (NULL != b) {
+        return b;
+    }
+
+    // 如果没找到,则从store的free_list里尝试找到第一个ref_count == 0 且未上锁的
+    bbuffer_store_t *s = getstore(size);
+    list_head_t *p = 0;
+    list_for_each(p, &s->free_list) {
+        bbuffer_t *t = list_entry(p, bbuffer_t, node);
+        assert(NULL != t);
+        assert(t->block_size == size);
+
+        if (t->ref_count == 0 && t->locked == 0) {
+            b = t;
+            break;
+        }
+    }
+
+    // 如果还是没有找到,则就需要等待释放出新的空间
+    if (b == NULL) {
+        irq_restore(iflags);
+        retry++;
+        // wait on free list
+        // ...
+        goto again;
+    }
+
+    // 此时b->locked不一定为0
+    // 因为可能有的进程调用了write、read后再直接调用brelse
+    // 虽然此时ref_count为0,但io操作标记的b->locked并未结束
+    // 所以需要在此等待其结束
+    while (b->locked == 1) {
+        // 此时是不用担心wake_up在这个sleep_on之前调用
+    }
+
+    // 找到了
+    b->block = block;
+    b->block_size = size;
+    b->dev = dev;
+    b->ref_count = 1;
+    b->uptodate = 0;
+
+    list_init(&b->node);
+
+    irq_restore(iflags);
+
+    return b;
+}
+
+bbuffer_t *bread(dev_t dev, uint64_t block, uint32_t size) {
+    bbuffer_t *b = getblk(dev, block, size);
+
+    return b;
+}
+
+void init_buffer() {
+    for (int i = 0; i < BLOCK_BUFFER_HASH_TABLE_SIZE; i++) {
+        list_init(block_buffer_hash_table + i);
+    }
+
+    bbufer_kmem_cache = kmem_cache_create("bbuffer", sizeof(bbuffer_t), 4);
+    if (NULL == bbufer_kmem_cache) {
+        panic("no memory for bbufer kmem cache");
+    }
+
+    printk("bbufer kmem cache %08x\n", bbufer_kmem_cache);
+    printk("SIZE %u\n", sizeof(bbuffer_t));
+
+    for (int i = 0; i < 3; i++) {
+        int blocksize = 1 << (10 + i);
+
+        store[i].blocksize = blocksize;
+        // list_init(&store[i].cache_list);
+        list_init(&store[i].free_list);
+
+        int page_left_space = 0;
+        void *data = NULL;
+        page_t *page = NULL;
+        for (int j = 0; j < MAX_BBUFFER_CNT; j++) {
+            if (page_left_space < blocksize) {
+                data = (void *)(alloc_one_page(0));
+                page = va2page(data);
+            }
+
+            bbuffer_t *b = kmem_cache_alloc(bbufer_kmem_cache, 0);
+            assert(NULL != b);
+
+            b->block = 0;
+            b->block_size = blocksize;
+            b->ref_count = 0;
+            b->data = data + j * blocksize;
+            b->dev = 0;
+            b->page = page;
+            b->uptodate = 0;
+            b->locked = 0;
+            list_init(&b->node);
+
+            assert(NULL != b->data);
+
+            list_add(&b->node, &store[i].free_list);
+
+            page_left_space -= blocksize;
+        }
+    }
+}
index fe84e139dd24f09bb99f8a32b557f1684e0bde3b..8f570cc5fa9519da3ff0029758be1646e1f5ee78 100644 (file)
@@ -8,3 +8,22 @@
  */
 
 #pragma once
+
+#include <atomic.h>
+#include <fs.h>
+#include <mm.h>
+#include <page.h>
+#include <system.h>
+
+typedef struct bbuffer {
+    uint32_t block;  // block number
+    void *data;      //
+    atomic_t ref_count;
+    dev_t dev;
+    page_t *page;
+    list_head_t node;
+    uint16_t block_size;  // block size
+    uint16_t uptodate : 1;
+    uint16_t locked : 1;
+    uint16_t dirt : 1;  // 还不支持
+} bbuffer_t;
index db085be69e2e7d3c8a544b3e1f51be07a1be2a79..291f73ae122e7439d9d1c5885a105b77f3f6642f 100644 (file)
@@ -9,6 +9,7 @@
 
 #pragma once
 
+#if 0
 #include <wait.h>
 
 typedef struct completion {
@@ -22,4 +23,5 @@ typedef struct completion {
 void wait_completion(completion_t *x);
 void init_completion(completion_t *x);
 
-void complete(completion_t *x);
\ No newline at end of file
+void complete(completion_t *x);
+#endif
index 5c3894954545a9f188f1d10fceb7d071c1db7062..751b5c9077d84ceb096585e44f0d2a4f3f016cb0 100644 (file)
@@ -26,14 +26,6 @@ typedef struct disk_request {
     void *buf;                   // 到的缓冲区
     disk_request_cmd_t command;  // 命令
     list_head_t list;
-    // // wait_queue_head_t wait;  // 等待队列
-    // // 驱动器完全有可能在进程在进程睡眠到等待队列前返回数据并执行唤醒操作
-    // // 这时等待队列上无进程,就相当于不执行任何操作
-    // // 然后进程再睡眠到等待队列上,就会造成永远无法唤醒该进程
-    // // 因此要添加一个字段,标志驱动器已经对该请求做过唤醒操作
-    // // 进程在睡眠前需要检查该字段
-    // // int done;
-    // completion_t completion;
     semaphore_t sem;
 } disk_request_t;
 
index b84216f5345414293888004ac2bbdff09478508f..7750690b24dacde030d4e649d3b007b6ab8a9db3 100644 (file)
@@ -109,14 +109,4 @@ static inline pInode find_empty_inode()
 
 typedef uint32_t dev_t;
 
-typedef struct blk_buffer {
-    uint32_t block;       // block number
-    char *data;           //
-    uint16_t block_size;  // block size
-    dev_t dev;
-    page_t *page;
-    struct blk_buffer *next;
-    struct blk_buffer *hash_next;
-} blk_buffer_t;
-
 #endif  //_FS_H
index 8ee3395673c8f17b4083545fadfd3208db714698..e995408718f56b003c859fe5751382f84fe7e5ff 100644 (file)
@@ -69,3 +69,5 @@ static inline void list_del_init(list_head_t *entry) {
 }
 
 static inline int list_empty(list_head_t *head) { return head->next == head; }
+
+static inline void list_init(list_head_t *head) { INIT_LIST_HEAD(head); }
index 7f29c1a98c9308988e1bd3888d09f5affa038e7c..27eb0094f546bf0576346d4a20ba7cd55873650a 100644 (file)
@@ -26,11 +26,13 @@ void semaphore_init(semaphore_t *s, unsigned int v);
 // down
 // 如果s->cnt > 0不会立即重新调度进程
 // 如果s->cnt == 0 会重新调度进程
-void down(semaphore_t *s);
+volatile void down(semaphore_t *s);
+
+// volatile bool try_down(semaphore_t *s);
 
 // up
 // 只会唤醒进程,但不会立即重新调度进程
-void up(semaphore_t *s);
+volatile void up(semaphore_t *s);
 
 typedef semaphore_t mutex_t;
 
index c54c0142312596d8ef232b6613eb2440aa7d0663..8f29e935d4e75cda0b18fd9ccce0b478171ef54e 100644 (file)
@@ -43,9 +43,9 @@ void del_wait_queue(wait_queue_head_t *head, wait_queue_t *wq);
 // prepare_to_wait 不会调用schedule
 void prepare_to_wait(wait_queue_head_t *head, wait_queue_t *wq, unsigned int state);
 
-void __end_wait(wait_queue_head_t *head, wait_queue_t *wq);
+void __end_wait(wait_queue_t *wq);
 
-void sleep_on(wait_queue_head_t *head);
+// void sleep_on(wait_queue_head_t *head);
 void wake_up(wait_queue_head_t *head);
 
 void schedule();
@@ -59,7 +59,7 @@ void schedule();
             }                                          \
             schedule();                                \
         }                                              \
-        __end_wait(head, &__wait);                     \
+        __end_wait(&__wait);                           \
     } while (0)
 
 #define wait_event(head, condition)          \
diff --git a/kernel/buffer.c b/kernel/buffer.c
deleted file mode 100644 (file)
index 18b7c9b..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * ------------------------------------------------------------------------
- *   File Name: buffer.c
- *      Author: Zhao Yanbai
- *              2023-06-20 19:30:33 Tuesday CST
- * Description: none
- * ------------------------------------------------------------------------
- */
-
-typedef struct buffer {
-    //
-} buffer_t;
-
-void init_buffer() {}
index f127fb5a8b1c387df5b073f75366e4da3fc9f159..d556f3192fc99c02422a932782a806d9d34e7aaa 100644 (file)
@@ -7,17 +7,22 @@
  * ------------------------------------------------------------------------
  */
 
+#if 0
 #include <completion.h>
 #include <sched.h>
 
 void wait_completion(completion_t *x) { wait_event(&x->wait, (x->done == 1)); }
 
 void complete(completion_t *x) {
+    uint32_t iflags;
+    irq_save(iflags);
     x->done = 1;
     wake_up(&x->wait);
+    irq_restore(iflags);
 }
 
 void init_completion(completion_t *x) {
     x->done = 0;
     init_wait_queue_head(&x->wait);
-}
\ No newline at end of file
+}
+#endif
index 9014f46d203f3484bb55938f7b1d9237f2e1d685..c7ff1283f9e2468055e1bfd734a9f76cd09ebe01 100644 (file)
@@ -35,6 +35,15 @@ volatile void down(semaphore_t *s) {
     irq_restore(iflags);
 }
 
+// volatile bool try_down(semaphore_t *s) {
+//     unsigned long iflags;
+//     irq_save(iflags);
+
+//     // if(s->cnt )
+
+//     irq_restore(iflags);
+// }
+
 volatile void up(semaphore_t *s) {
     unsigned long iflags;
     irq_save(iflags);
index d9475899dc9deb618890c215f4e108e12842b32f..12e2314fbcea5425c1fb3bc23169c402b30e4d17 100644 (file)
@@ -20,6 +20,7 @@
 #include <tty.h>
 
 extern void init_mm();
+extern void init_buffer();
 extern void setup_gdt();
 extern void setup_idt();
 extern void setup_gate();
@@ -55,6 +56,8 @@ void setup_kernel() {
 
     init_mm();
 
+    init_buffer();
+
     // printk("kernel: %08x - %08x\n", system.kernel_begin, system.kernel_end);
     boot_delay(DEFAULT_BOOT_DELAY_TICKS);
 
index 86ea8f24cbcae1b8f3f5f9603677a28a6ee921f2..316205e3eb2606cd3707ac09157922ab6a92c68d 100644 (file)
 
 volatile void init_wait_queue_head(wait_queue_head_t *wqh) { INIT_LIST_HEAD(&wqh->task_list); }
 
-volatile void add_wait_queue(wait_queue_head_t *head, wait_queue_t *wq) {
+volatile void prepare_to_wait(wait_queue_head_t *head, wait_queue_t *wq, unsigned int state) {
     unsigned long flags;
     irq_save(flags);
-    list_add_tail(&wq->task_list, &head->task_list);
+    if (list_empty(&wq->task_list)) {
+        list_add_tail(&wq->task_list, &head->task_list);
+    }
+    set_current_state(state);
     irq_restore(flags);
 }
 
-volatile void del_wait_queue(wait_queue_head_t *head, wait_queue_t *wq) {
+volatile void __end_wait(wait_queue_t *wq) {
+    set_current_state(TASK_READY);
     unsigned long flags;
     irq_save(flags);
-    list_del(&wq->task_list);
+    list_del_init(&wq->task_list);
     irq_restore(flags);
 }
 
-volatile void prepare_to_wait(wait_queue_head_t *head, wait_queue_t *wq, unsigned int state) {
+volatile void wake_up(wait_queue_head_t *head) {
     unsigned long flags;
+    wait_queue_t *p, *tmp;
     irq_save(flags);
-    if (list_empty(&wq->task_list)) {
-        list_add_tail(&wq->task_list, &head->task_list);
+    list_for_each_entry_safe(p, tmp, &head->task_list, task_list) {
+        list_del(&p->task_list);
+        // printk("wakeup: %s\n", p->task->name);
+        p->task->state = TASK_READY;
     }
-    set_current_state(state);
     irq_restore(flags);
 }
 
-volatile void __end_wait(wait_queue_head_t *head, wait_queue_t *wq) {
-    set_current_state(TASK_READY);
+volatile void add_wait_queue(wait_queue_head_t *head, wait_queue_t *wq) {
     unsigned long flags;
     irq_save(flags);
-    list_del_init(&wq->task_list);
+    list_add_tail(&wq->task_list, &head->task_list);
     irq_restore(flags);
 }
 
-volatile void sleep_on(wait_queue_head_t *head) {
-    DECLARE_WAIT_QUEUE(wait, current);
-
+volatile void del_wait_queue(wait_queue_head_t *head, wait_queue_t *wq) {
     unsigned long flags;
     irq_save(flags);
+    list_del(&wq->task_list);
+    irq_restore(flags);
+}
 
-    current->state = TASK_WAIT;
-    current->reason = "sleep_on";
+// volatile void sleep_on(wait_queue_head_t *head) {
+//     DECLARE_WAIT_QUEUE(wait, current);
 
-    list_add_tail(&wait.task_list, &head->task_list);
+//     unsigned long flags;
+//     irq_save(flags);
 
-    irq_restore(flags);
+//     current->state = TASK_WAIT;
+//     current->reason = "sleep_on";
 
-    schedule();
+//     list_add_tail(&wait.task_list, &head->task_list);
 
-    // wake_up操作会把wait从heat链表上删除
-    // 所以这里就不用做什么了
-}
+//     irq_restore(flags);
 
-volatile void __wake_up(wait_queue_head_t *head, int nr) {
-    unsigned long flags;
-    wait_queue_t *p, *tmp;
-    irq_save(flags);
-    list_for_each_entry_safe(p, tmp, &head->task_list, task_list) {
-        list_del(&p->task_list);
-        // printk("wakeup: %s\n", p->task->name);
-        p->task->state = TASK_READY;
-        current->reason = "wake_up";
+//     schedule();
 
-        --nr;
-        if (nr == 0) {
-            break;
-        }
-    }
-    irq_restore(flags);
+//     // wake_up操作会把wait从heat链表上删除
+//     // 所以这里就不用做什么了
+// }
 
-    // no schedule() here.
-}
+// volatile void __wake_up(wait_queue_head_t *head, int nr) {
+//     unsigned long flags;
+//     wait_queue_t *p, *tmp;
+//     irq_save(flags);
+//     list_for_each_entry_safe(p, tmp, &head->task_list, task_list) {
+//         list_del(&p->task_list);
+//         // printk("wakeup: %s\n", p->task->name);
+//         p->task->state = TASK_READY;
+//         current->reason = "wake_up";
 
-volatile void wake_up(wait_queue_head_t *head) { __wake_up(head, 1); }
+//         --nr;
+//         if (nr == 0) {
+//             break;
+//         }
+//     }
+//     irq_restore(flags);
 
-#include <irq.h>
-DECLARE_WAIT_QUEUE_HEAD(debug_wq);
-unsigned int debug_global_var = 0;
-int debug_wait_queue_get() {
-    unsigned int v = 0;
-    task_union *task = current;
-    DECLARE_WAIT_QUEUE(wait, task);
-    add_wait_queue(&debug_wq, &wait);
+//     // no schedule() here.
+// }
 
-    while (1) {
-        printd("pid %d is going to wait\n", sysc_getpid());
-        task->state = TASK_WAIT;
+// volatile void wake_up(wait_queue_head_t *head) { __wake_up(head, 1); }
 
-        disable_irq();
-        v = debug_global_var;
-        if (debug_global_var != 0) debug_global_var--;
-        enable_irq();
+// #include <irq.h>
+// DECLARE_WAIT_QUEUE_HEAD(debug_wq);
+// unsigned int debug_global_var = 0;
+// int debug_wait_queue_get() {
+//     unsigned int v = 0;
+//     task_union *task = current;
+//     DECLARE_WAIT_QUEUE(wait, task);
+//     add_wait_queue(&debug_wq, &wait);
 
-        if (v != 0) break;
+//     while (1) {
+//         printd("pid %d is going to wait\n", sysc_getpid());
+//         task->state = TASK_WAIT;
 
-        schedule();
-        printd("pid %d is running\n", sysc_getpid());
-    }
+//         disable_irq();
+//         v = debug_global_var;
+//         if (debug_global_var != 0) debug_global_var--;
+//         enable_irq();
 
-    printd("pid %d is really running\n", sysc_getpid());
-    task->state = TASK_READY;
-    del_wait_queue(&debug_wq, &wait);
+//         if (v != 0) break;
 
-    return v;
-}
+//         schedule();
+//         printd("pid %d is running\n", sysc_getpid());
+//     }
+
+//     printd("pid %d is really running\n", sysc_getpid());
+//     task->state = TASK_READY;
+//     del_wait_queue(&debug_wq, &wait);
+
+//     return v;
+// }
 
 int debug_wait_queue_put(unsigned int v) {
-    debug_global_var = v;
-    wake_up(&debug_wq);
+    // debug_global_var = v;
+    // wake_up(&debug_wq);
 }