|
|
@@ -0,0 +1,108 @@
|
|
|
+#include "list.h"
|
|
|
+#include "../../kernel/interrupt.h"
|
|
|
+
|
|
|
+// 初始化双向链表list
|
|
|
+void list_init(struct list *plist)
|
|
|
+{
|
|
|
+ plist->head.prev = NULL;
|
|
|
+ plist->head.next = &plist->tail;
|
|
|
+ plist->tail.prev = &plist->head;
|
|
|
+ plist->tail.next = NULL;
|
|
|
+}
|
|
|
+// 将链表元素elem 插入在元素before之前
|
|
|
+void list_insert_before(struct list_elem *before, struct list_elem *elem)
|
|
|
+{
|
|
|
+ enum intr_status old_status = intr_disable(); // 关中断
|
|
|
+
|
|
|
+ before->prev->next = elem; // before 暂时脱离链表
|
|
|
+
|
|
|
+ elem->prev = before->prev;
|
|
|
+ elem->next = before;
|
|
|
+
|
|
|
+ before->prev = elem; // before重新回到链表
|
|
|
+
|
|
|
+ intr_set_status(old_status); // 恢复中断
|
|
|
+}
|
|
|
+// 将元素elem添加到链表plist队首,类似栈push操作
|
|
|
+void list_push(struct list *plist, struct list_elem *elem)
|
|
|
+{
|
|
|
+ list_insert_before(plist->head.next, elem); // 在队头插入elem
|
|
|
+}
|
|
|
+void list_iterate(struct list *plist);
|
|
|
+// 添加元素到链表队尾
|
|
|
+void list_append(struct list *plist, struct list_elem *elem)
|
|
|
+{
|
|
|
+ list_insert_before(&plist->tail, elem); // 在队尾的前面插入
|
|
|
+}
|
|
|
+// 从链表中删除元素pelem
|
|
|
+void list_remove(struct list_elem *pelem)
|
|
|
+{
|
|
|
+ enum intr_status old_status = intr_disable(); // 关中断
|
|
|
+
|
|
|
+ pelem->prev->next = pelem->next;
|
|
|
+ pelem->next->prev = pelem->prev;
|
|
|
+
|
|
|
+ intr_set_status(old_status); // 恢复中断
|
|
|
+}
|
|
|
+// 将链表第一个元素弹出并返回
|
|
|
+struct list_elem *list_pop(struct list *plist)
|
|
|
+{
|
|
|
+ struct list_elem *elem = plist->head.next;
|
|
|
+ list_remove(elem);
|
|
|
+ return elem;
|
|
|
+}
|
|
|
+// 判断链表是否为空,空返回true,否则返回false
|
|
|
+bool list_empty(struct list *plist)
|
|
|
+{
|
|
|
+ return (plist->head.next == &plist->tail ? true : false);
|
|
|
+}
|
|
|
+// 返回链表长度
|
|
|
+uint32_t list_len(struct list *plist)
|
|
|
+{
|
|
|
+ struct list_elem *elem = plist->head.next;
|
|
|
+ uint32_t length = 0;
|
|
|
+ while (elem != &plist->tail)
|
|
|
+ {
|
|
|
+ length++;
|
|
|
+ elem = elem->next;
|
|
|
+ }
|
|
|
+ return length;
|
|
|
+}
|
|
|
+// 把列表plist中的每个元素elem和arg传给func,
|
|
|
+// func 判断是否符合条件
|
|
|
+// 如果找到符合条件的元素返回元素指针,否则返回NULL
|
|
|
+struct list_elem *list_traversal(struct list *plist, trav_func func, int arg)
|
|
|
+{
|
|
|
+ struct list_elem *elem = plist->head.next;
|
|
|
+
|
|
|
+ // 如果链表为空,直接返回NULL
|
|
|
+ if (list_empty(plist))
|
|
|
+ {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ while (elem != &plist->tail)
|
|
|
+ {
|
|
|
+ if (func(elem, arg))
|
|
|
+ {
|
|
|
+ // func返回true,直接返回元素指针
|
|
|
+ return elem;
|
|
|
+ }
|
|
|
+ elem = elem->next;
|
|
|
+ }
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+// 查找元素是否在链表中,成功返回true,失败返回false
|
|
|
+bool elem_find(struct list *plist, struct list_elem *obj_elem)
|
|
|
+{
|
|
|
+ struct list_elem *elem = plist->head.next;
|
|
|
+ while (elem != &plist->tail)
|
|
|
+ {
|
|
|
+ if (elem == obj_elem)
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ elem = elem->next;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|