From: acevest Date: Sat, 20 Nov 2021 15:16:00 +0000 (+0800) Subject: TASK_RUNNING 改成 TASK_READY; 将磁盘请求放到内核任务里执行 X-Git-Url: http://zhaoyanbai.com/repos/doxygen-warnings.log?a=commitdiff_plain;h=973b5c7fbbbaf7804536d4ea69b13e4fc064ae36;p=kernel.git TASK_RUNNING 改成 TASK_READY; 将磁盘请求放到内核任务里执行 --- diff --git a/drivers/ata.c b/drivers/ata.c index 344d579..8ee4e34 100644 --- a/drivers/ata.c +++ b/drivers/ata.c @@ -7,14 +7,13 @@ * ------------------------------------------------------------------------ */ #include +#include #include #include #include #include #include #include -#include -#include extern ide_pci_controller_t ide_pci_controller; @@ -45,8 +44,50 @@ void ata_test(uint64_t nr) { // 3. 等到status的DRQ位或ERR位设置 u16 identify[256]; void ata_send_read_identify_cmd(int dev) {} -void ata_read_identify(int dev) { // 这里所用的dev是逻辑编号 ATA0、ATA1下的Master、Salve的dev分别为0,1,2,3 +void ata_read_data(int dev, int sect_cnt, void *dst) { insl(REG_DATA(dev), dst, (512 * sect_cnt) / sizeof(uint32_t)); } + +void ata_read_identify(int dev) { + outb(0x00, REG_CTL(dev)); + outb(0x00 | ((dev & 0x01) << 4), REG_DEVICE(dev)); // 根据文档P113,这里不用指定bit5, bit7,直接指示DRIVE就行 + + unsigned long flags; + irq_save(flags); + + outb(ATA_CMD_IDENTIFY, REG_CMD(dev)); + wait_on_ide(); + + irq_restore(flags); +} + +void ata_init() { + disk_request_t r; + r.buf = (void *)identify; + r.count = 1; + r.pos = 0; + r.command = DISK_REQ_IDENTIFY; + + send_disk_request(&r); + + // 第49个word的第8个bit位表示是否支持DMA + // 第83个word的第10个bit位表示是否支持LBA48,为1表示支持。 + // 第100~103个word的八个字节表示user的LBA最大值 + printk("%04x %04x %d %d\n", identify[49], 1 << 8, identify[49] & (1 << 8), (identify[49] & (1 << 8)) != 0); + if ((identify[49] & (1 << 8)) != 0) { + printk("support DMA\n"); + } + + if ((identify[83] & (1 << 10)) != 0) { + printk("support LBA48\n"); + + u64 lba = *(u64 *)(identify + 100); + printk("hard disk size: %u MB\n", (lba * 512) >> 20); + } +} + +void ata_read_identify_old(int dev) { // 这里所用的dev是逻辑编号 ATA0、ATA1下的Master、Salve的dev分别为0,1,2,3 + // void send_disk_request(); + // send_disk_request(); // DECLARE_WAIT_QUEUE_HEAD(wq_head); // DECLARE_WAIT_QUEUE(wait, current); // add_wait_queue(&wq_head, &wait); diff --git a/drivers/console.c b/drivers/console.c index e9eaf60..32860c7 100644 --- a/drivers/console.c +++ b/drivers/console.c @@ -111,7 +111,7 @@ int cnsl_read(char *buf, size_t count) { if (r) { buf[cnt++] = ch; - task->state = TASK_RUNNING; + task->state = TASK_READY; del_wait_queue(&rdwq, &wait); if (ch == '\n') goto end; diff --git a/drivers/ide.c b/drivers/ide.c index 781b28e..64fcd09 100644 --- a/drivers/ide.c +++ b/drivers/ide.c @@ -121,7 +121,7 @@ ide_intr_func_t ide_intr_func = ide_default_intr; // } // // printd("%s pid %d is really running\n", __func__, sysc_getpid()); -// task->state = TASK_RUNNING; +// task->state = TASK_READY; // del_wait_queue(&r->wait, &wait); // } @@ -537,6 +537,8 @@ void ata_read_identify(int dev); DECLARE_WAIT_QUEUE_HEAD(ide_wait_queue_head); void sleep_on_ide() { sleep_on(&ide_wait_queue_head); } + +void prepare_to_wait_on_ide() { ide_pci_controller.done = 0; } void wait_on_ide() { wait_event(&ide_wait_queue_head, ide_pci_controller.done); } extern void *mbr_buf; @@ -548,24 +550,9 @@ void ide_irq_handler(unsigned int irq, pt_regs_t *regs, void *devid) { printk("ide pci status after interrupt: %x\n", ata_pci_bus_status()); -#if 0 - unsigned int v = pci_read_config_word(pci_cmd(ide_pci_controller.pci, PCI_COMMAND)); - pci_write_config_word(v & (~PCI_COMMAND_MASTER), pci_cmd(ide_pci_controller.pci, PCI_COMMAND)); - - uint16_t *p = (uint16_t *)mbr_buf; - for (int i = 0; i < 256; i++) { - if (i % 12 == 0) { - printk("\n%03d ", i); - } - printk("%04x ", p[i]); - } -#endif - ide_pci_controller.done = 1; wake_up(&ide_wait_queue_head); - - // ide_pci_controller.task->state = TASK_RUNNING; } void ide_init() { @@ -576,15 +563,4 @@ void ide_init() { // init_pci_controller(0x0106); init_pci_controller(0x0101); - - // ide_detect(); - // return; - // ide_read_identify(); - ata_read_identify(0); - return; - - // // 还没开启中断 - // ide_read_partition(); - - // ide_printl(); } diff --git a/include/disk.h b/include/disk.h new file mode 100644 index 0000000..0321bb5 --- /dev/null +++ b/include/disk.h @@ -0,0 +1,43 @@ +/* + * ------------------------------------------------------------------------ + * File Name: disk.h + * Author: Zhao Yanbai + * 2021-11-21 22:08:16 Sunday CST + * Description: none + * ------------------------------------------------------------------------ + */ + +#pragma once + +#include +#include +#include +#include + +typedef enum { + DISK_REQ_IDENTIFY, + DISK_REQ_READ, +} disk_request_cmd_t; + +typedef struct disk_request { + uint64_t pos; // 扇区号 + uint16_t count; // 扇区数 + void *buf; // 到的缓冲区 + disk_request_cmd_t command; // 命令 + list_head_t list; + wait_queue_head_t wait; // 等待队列 + // 驱动器完全有可能在进程在进程睡眠到等待队列前返回数据并执行唤醒操作 + // 这时等待队列上无进程,就相当于不执行任何操作 + // 然后进程再睡眠到等待队列上,就会造成永远无法唤醒该进程 + // 因此要添加一个字段,标志驱动器已经对该请求做过唤醒操作 + // 进程在睡眠前需要检查该字段 + int done; +} disk_request_t; + +typedef struct { + uint32_t count; + semaphore_t sem; + list_head_t list; +} disk_request_queue_t; + +void send_disk_request(disk_request_t *r); \ No newline at end of file diff --git a/include/list.h b/include/list.h index 475e7f3..8ee3395 100644 --- a/include/list.h +++ b/include/list.h @@ -21,9 +21,6 @@ typedef struct list_head { struct list_head *prev, *next; } list_head_t; -// TODO Remove -typedef list_head_t ListHead, *pListHead; - #define LIST_HEAD_INIT(name) \ { &(name), &(name) } #define LIST_HEAD(name) list_head_t name = LIST_HEAD_INIT(name) diff --git a/include/task.h b/include/task.h index add3602..ac27a6a 100644 --- a/include/task.h +++ b/include/task.h @@ -25,7 +25,7 @@ enum { TASK_UNUSED, - TASK_RUNNING, + TASK_READY, TASK_WAIT, TASK_INITING, TASK_EXITING, diff --git a/include/types.h b/include/types.h index 769fa3c..04a3aaa 100644 --- a/include/types.h +++ b/include/types.h @@ -42,9 +42,13 @@ typedef unsigned long u32_t; typedef unsigned long long u64_t; typedef unsigned char uint8_t; +typedef char int8_t; typedef unsigned short uint16_t; +typedef short int16_t; typedef unsigned long uint32_t; +typedef long int32_t; typedef unsigned long long uint64_t; +typedef long long int64_t; typedef unsigned long pid_t; typedef unsigned long mode_t; diff --git a/kernel/clock.c b/kernel/clock.c index 8e8be8f..bca611d 100644 --- a/kernel/clock.c +++ b/kernel/clock.c @@ -34,7 +34,7 @@ void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) { p->delay_cnt -= p->delay_cnt == 0 ? 0 : 1; if (0 == p->delay_cnt) { - p->state = TASK_RUNNING; + p->state = TASK_READY; list_del(&p->pend); } } diff --git a/kernel/fork.c b/kernel/fork.c index 6291501..c367af1 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -107,7 +107,7 @@ int do_fork(pt_regs_t *regs, unsigned long flags) { list_add(&tsk->list, &all_tasks); irq_restore(iflags); - tsk->state = TASK_RUNNING; + tsk->state = TASK_READY; return (int)tsk->pid; } diff --git a/kernel/sched.c b/kernel/sched.c index 798fd76..819fa3c 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -55,7 +55,7 @@ void init_root_task() { root_task.pid = get_next_pid(); root_task.ppid = 0; - root_task.state = TASK_RUNNING; + root_task.state = TASK_READY; root_task.weight = TASK_INIT_WEIGHT; root_task.priority = 100; strcpy(root_task.name, "root"); @@ -141,7 +141,7 @@ task_union *find_task(pid_t pid) { static const char *task_state(unsigned int state) { static const char s[][16] = { - " ERROR", "RUNNING", " WAIT", "INITING", "EXITING", + " ERROR", "READY", " WAIT", " INIT", " EXIT", }; if (state >= TASK_END) { @@ -165,7 +165,7 @@ unsigned long schedule() { bool need_reset_weight = true; list_for_each_safe(pos, t, &all_tasks) { p = list_entry(pos, task_union, list); - if (p->state != TASK_RUNNING) { + if (p->state != TASK_READY) { continue; } if (p->weight < p->priority) { @@ -177,7 +177,7 @@ unsigned long schedule() { if (need_reset_weight) { list_for_each_safe(pos, t, &all_tasks) { p = list_entry(pos, task_union, list); - if (p->state != TASK_RUNNING) { + if (p->state != TASK_READY) { continue; } p->weight = 0; @@ -187,7 +187,7 @@ unsigned long schedule() { list_for_each_safe(pos, t, &all_tasks) { p = list_entry(pos, task_union, list); - if (p->state != TASK_RUNNING) { + if (p->state != TASK_READY) { continue; } @@ -218,5 +218,5 @@ unsigned long schedule() { void debug_sched() { task_union *p = list_entry(current->list.next, task_union, list); - p->state = (p->state == TASK_RUNNING) ? TASK_WAIT : TASK_RUNNING; + p->state = (p->state == TASK_READY) ? TASK_WAIT : TASK_READY; } diff --git a/kernel/semaphore.c b/kernel/semaphore.c index 4dd314a..278d339 100644 --- a/kernel/semaphore.c +++ b/kernel/semaphore.c @@ -44,7 +44,6 @@ void __down(semaphore_t *s) { void down(semaphore_t *s) { unsigned long iflags; irq_save(iflags); - if (likely(s->cnt > 0)) { s->cnt--; } else { @@ -59,16 +58,19 @@ void __up(semaphore_t *s) { list_del(&waiter->list); waiter->up = 1; - waiter->task->state = TASK_RUNNING; + waiter->task->state = TASK_READY; } void up(semaphore_t *s) { unsigned long iflags; irq_save(iflags); - if (likely(list_empty(&s->wait_list))) { + // if (likely(list_empty(&s->wait_list))) { + if (list_empty(&s->wait_list)) { + printk("++++++\n"); s->cnt++; } else { + printk("upupupuppupupup\n"); __up(s); } diff --git a/kernel/setup.c b/kernel/setup.c index 7c1991d..87d984c 100644 --- a/kernel/setup.c +++ b/kernel/setup.c @@ -89,12 +89,15 @@ void setup_kernel() { extern tty_t monitor_tty; tty_switch(&monitor_tty); + + void ide_init(); + ide_init(); } // 在开中断的情况下继续初始化的内容 void setup_under_irq() { - void ide_init(); - ide_init(); + void ata_init(); + ata_init(); return; setup_fs(); } \ No newline at end of file diff --git a/kernel/syscall.c b/kernel/syscall.c index 40a6e56..2a25a9f 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -52,7 +52,7 @@ int sysc_test() { // 下一次系统调用还可能走到这里 // 所以这里就直接判断不是RUNNING就返回 // 不再操作delay_tasks链表 - if (current->state != TASK_RUNNING) { + if (current->state != TASK_READY) { return 0; } diff --git a/kernel/task_disk.c b/kernel/task_disk.c index 9ed8f0c..3d29af2 100644 --- a/kernel/task_disk.c +++ b/kernel/task_disk.c @@ -7,73 +7,119 @@ * ------------------------------------------------------------------------ */ +#include #include -#include -#include - -#if 0 -typedef enum { - DISK_REQ_IDENTIFY, - DISK_REQ_READ, -} disk_request_cmd_t; - -typedef struct disk_request { - uint64_t pos; // 扇区号 - uint16_t count; // 扇区数 - void *buf; // 到的缓冲区 - disk_request_cmd_t command; // 命令 - wait_queue_head_t wait; // 等待队列 - // 驱动器完全有可能在进程在进程睡眠到等待队列前返回数据并执行唤醒操作 - // 这时等待队列上无进程,就相当于不执行任何操作 - // 然后进程再睡眠到等待队列上,就会造成永远无法唤醒该进程 - // 因此要添加一个字段,标志驱动器已经对该请求做过唤醒操作 - // 进程在睡眠前需要检查该字段 - int done; -} disk_request_t; - -void send_disk_request() { - disk_request_t r; - r.pos = 0; - r.count = 1; - r.buf = kmalloc(512, 0); - r.command = DISK_REQ_IDENTIFY; - INIT_LIST_HEAD(&r.wait.task_list); - r.done = 0; - - list_add_tail(&wq->task_list, &head->task_list); - // 发送命令 - //.... +disk_request_queue_t disk_request_queue; // = {.count = 0, + // .sem = SEMAPHORE_INITIALIZER(disk_request_queue.sem, 0), + // .list = LIST_HEAD_INIT(disk_request_queue.list)}; + +void disk_init() { + disk_request_queue.count = 0; + disk_request_queue.sem.cnt = 0; + INIT_LIST_HEAD(&disk_request_queue.sem.wait_list); + INIT_LIST_HEAD(&disk_request_queue.list); +} + +#if 1 +void send_disk_request(disk_request_t *r) { + if (NULL == r) { + panic("null disk request"); + } + + // 校验pos,和pos+count是否大于硬盘返回的最大LBA48 + // ... + + // 校验buffer是否跨64K + // 先不处理 + if (((uint32_t)r->buf & 0xFFFF0000) != (((uint32_t)(r->buf + r->count * 512)) & 0xFFFF0000)) { + panic("disk DMA read cross 64K"); + } + INIT_LIST_HEAD(&r->wait.task_list); + r->done = 0; + // r.pos = pos; + // r.count = count; + // r.buf = kmalloc(512, 0); + // r.command = DISK_REQ_IDENTIFY; + // INIT_LIST_HEAD(&r.wait.task_list); + // r.done = 0; + + // printk("do send disk request: %d %x %x %x\n", list_empty(&disk_request_queue.sem.wait_list), + // &disk_request_queue.sem.wait_list, disk_request_queue.sem.wait_list.next, + // disk_request_queue.sem.wait_list.prev); + + // 发送命令 unsigned long flags; irq_save(flags); - if (0 == r.done) { // 驱动器还没完成 - set_current_state(TASK_WAIT); - irq_restore(flags); - // 就算在schedule前驱动器触发中断也没有问题 - // 因为该进程已经加到等待队列上了 - // 所以它一定以唤醒该进程 - schedule(); - } else { // 驱动器已经完成 - irq_restore(flags); - } -} -#endif + list_add_tail(&r->list, &disk_request_queue.list); + irq_restore(flags); -typedef struct { - semaphore_t sem; - list_head_t list; -} disk_request_queue_t; + // 唤醒task_disk + printk("up sem\n"); + up(&disk_request_queue.sem); -disk_request_queue_t disk_request_queue = {.sem = SEMAPHORE_INITIALIZER(disk_request_queue.sem, 0), - .list = LIST_HEAD_INIT(disk_request_queue.list)}; + // 等待task_dist结束 + printk("wait event\n"); + wait_event(&r->wait, r->done != 0); + + printk("wait finished\n"); +} +#endif -int cnt = 0; void disk_task_entry() { while (1) { - printk("fuck you: %d\n", cnt); + void prepare_to_wait_on_ide(); + prepare_to_wait_on_ide(); + + printk("wait for new hard disk request\n"); down(&disk_request_queue.sem); - printk("fuck me: %d\n", cnt); - cnt++; + printk("hard disk request: %d\n", disk_request_queue.count++); + + unsigned long flags; + irq_save(flags); + + disk_request_t *r; + if (list_empty(&disk_request_queue.list)) { + } else { + r = list_first_entry(&disk_request_queue.list, disk_request_t, list); + if (NULL == r) { + panic("no disk request"); + } + + printk("disk request: pos %ld count %d cmd %d\n", r->pos, r->count, r->command); + } + + irq_restore(flags); + + if (NULL == r) { + continue; + } + + int dev = 0; + switch (r->command) { + case DISK_REQ_IDENTIFY: + assert(r->count == 1); + void ata_read_identify(int dev); + ata_read_identify(dev); + break; + + default: + break; + } + + // 等待硬盘中断 + void wait_on_ide(); + wait_on_ide(); + + // 读数据 + if (DISK_REQ_IDENTIFY == r->command) { + void ata_read_data(int dev, int sect_cnt, void *dst); + ata_read_data(dev, 1, r->buf); + } + + // 唤醒等待该请求的进程 + r->done = 1; + wake_up(&r->wait); } } diff --git a/kernel/task_root.c b/kernel/task_root.c index 77ac5df..62736a1 100644 --- a/kernel/task_root.c +++ b/kernel/task_root.c @@ -57,6 +57,10 @@ void root_task_entry() { // 所以得先清空一下键盘 inb(0x60); + // + void disk_init(); + disk_init(); + kernel_task("init", init_task_entry); kernel_task("disk", disk_task_entry); kernel_task("user", user_task_entry); diff --git a/kernel/wait.c b/kernel/wait.c index 51afc3e..f671a39 100644 --- a/kernel/wait.c +++ b/kernel/wait.c @@ -39,7 +39,7 @@ void prepare_to_wait(wait_queue_head_t *head, wait_queue_t *wq, unsigned int sta } void __end_wait(wait_queue_head_t *head, wait_queue_t *wq) { - set_current_state(TASK_RUNNING); + set_current_state(TASK_READY); unsigned long flags; irq_save(flags); list_del_init(&wq->task_list); @@ -67,8 +67,8 @@ void __wake_up(wait_queue_head_t *head, int nr) { irq_save(flags); list_for_each_entry_safe(p, tmp, &head->task_list, task_list) { list_del(&p->task_list); - printk("wakeup: %s\nread sector 0 with LBA48 and DMA", p->task->name); - p->task->state = TASK_RUNNING; + printk("wakeup: %s\n", p->task->name); + p->task->state = TASK_READY; --nr; if (nr == 0) { @@ -107,7 +107,7 @@ int debug_wait_queue_get() { } printd("pid %d is really running\n", sysc_getpid()); - task->state = TASK_RUNNING; + task->state = TASK_READY; del_wait_queue(&debug_wq, &wait); return v; @@ -143,7 +143,7 @@ int sysc_wait(unsigned long pid) { schedule(); } - task->state = TASK_RUNNING; + task->state = TASK_READY; del_wait_queue(&p->wait, &wait); return 0; diff --git a/lib/vsprintf.c b/lib/vsprintf.c index f29433a..4050771 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -4,11 +4,14 @@ // Add %012d %012x %12d %12x Support Mon, 20 Jul 2009 19:30:34 // Add %u Support Sun, 06 Jul 2014 12:07:54 // ======================================================================== +#include + #include "string.h" char *itoa(char *s, int n); char *itou(char *s, unsigned int n); char *itox(char *s, unsigned int n); +char *i64tou(char *s, int64_t n); enum { ALIGN_RIGHT, ALIGN_LEFT }; @@ -77,6 +80,14 @@ int vsprintf(char *buf, const char *fmt, char *args) { itoa(tmp, *((int *)args)); p += write_buf(p, tmp, char_fill, char_cnt, align); break; + case 'l': + fmt++; + if (*fmt == 'u' || *fmt == 'd') { // d u都当成u来处理 + i64tou(tmp, *((int64_t *)args)); + p += write_buf(p, tmp, char_fill, char_cnt, align); + args += 4; + } + break; case 's': p += write_buf(p, (const char *)*((unsigned int *)args), char_fill, char_cnt, align); break; @@ -131,6 +142,15 @@ char *itoa(char *s, int n) { } } +char *i64tou(char *s, int64_t n) { + itou(s, n >> 32); + int i = 0; + if ((n >> 32) > 0) { + i = strlen(s); + } + itou(s + i, n & 0xFFFFFFFF); +} + char *itou(char *s, unsigned int n) { char c; char *p = s; diff --git a/test_list.c b/test_list.c new file mode 100644 index 0000000..88e8746 --- /dev/null +++ b/test_list.c @@ -0,0 +1,120 @@ +#include +#include + +/* Allmost Copy From Linux */ +typedef struct list_head { + struct list_head *prev, *next; +} list_head_t; + +#define LIST_HEAD_INIT(name) \ + { &(name), &(name) } +#define LIST_HEAD(name) list_head_t name = LIST_HEAD_INIT(name) + +#define INIT_LIST_HEAD(ptr) \ + do { \ + (ptr)->next = (ptr); \ + (ptr)->prev = (ptr); \ + } while (0) + +#define list_entry(ptr, type, member) ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member))) + +#define list_first_entry(ptr, type, member) list_entry((ptr)->next, type, member) + +#define list_for_each(pos, head) for (pos = (head)->next; pos != (head); pos = pos->next) + +#define list_for_each_safe(pos, tmp, head) \ + for (pos = (head)->next, tmp = pos->next; pos != (head); pos = tmp, tmp = pos->next) + +#define list_for_each_entry_safe(pos, tmp, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member), \ + tmp = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); pos = tmp, tmp = list_entry(tmp->member.next, typeof(*tmp), member)) + +static inline void _list_add(list_head_t *pnew, list_head_t *prev, list_head_t *next) { + next->prev = pnew; + pnew->next = next; + pnew->prev = prev; + prev->next = pnew; +} + +static inline void list_add(list_head_t *pnew, list_head_t *head) { _list_add(pnew, head, head->next); } + +static inline void list_add_tail(list_head_t *pnew, list_head_t *head) { _list_add(pnew, head->prev, head); } + +static inline void _list_del(list_head_t *prev, list_head_t *next) { + next->prev = prev; + prev->next = next; +} + +static inline void list_del(list_head_t *entry) { + _list_del(entry->prev, entry->next); + entry->prev = NULL; + entry->next = NULL; +} + +static inline void list_del_init(list_head_t *entry) { + _list_del(entry->prev, entry->next); + INIT_LIST_HEAD(entry); +} + +static inline int list_empty(list_head_t *head) { return head->next == head; } + +typedef struct node { + int id; + list_head_t list; + list_head_t pend; +} node_t; + +LIST_HEAD(allH); +LIST_HEAD(pendH); + +int main() { + INIT_LIST_HEAD(&allH); + INIT_LIST_HEAD(&pendH); + + for (int i = 0; i < 10; i++) { + node_t *n = (node_t *)malloc(sizeof(node_t)); + n->id = i; + list_add(&n->list, &allH); + if (n->id % 3 == 0) { + list_add(&n->pend, &pendH); + } + } + + list_head_t *pos; + list_head_t *tmp; + node_t *p, *p1; + list_for_each_safe(pos, tmp, &allH) { + p = list_entry(pos, node_t, list); + printf("allH: %d\n", p->id); + } + + printf("-----\n"); + list_for_each_safe(pos, tmp, &pendH) { + p = list_entry(pos, node_t, pend); + printf("pendH: %d\n", p->id); + } + + // list_for_each_safe(pos, tmp, &allH) { + + // p = list_entry(pos, node_t, list); + list_for_each_entry_safe(p, p1, &pendH, pend) { + // printf("%d\n", p->id); + if (p->id == 3) { + list_del(&p->pend); + } + } + + printf("-----\n"); + + list_for_each_safe(pos, tmp, &allH) { + p = list_entry(pos, node_t, list); + printf("allH: %d\n", p->id); + } + + printf("-----\n"); + list_for_each_safe(pos, tmp, &pendH) { + p = list_entry(pos, node_t, pend); + printf("pendH: %d\n", p->id); + } +} \ No newline at end of file