双向链表被用于内存管理、内核线程及进程管理、定时器管理等内核管理的许多地方。
// list.h
#ifndef __LIST_H
#define __LIST_H
#include "global.h"
// 核心数据结构 双向链表
struct list_elem {
struct list_elem* prev;
struct list_elem* next;
};
struct list {
struct list_elem head;
struct list_elem tail;
};
typedef bool (function)(struct list_elem*, int arg);
void list_init(struct list* list);
void list_insert_before(struct list_elem* before, struct list_elem* elem);
void list_push(struct list* plist, struct list_elem* elem);
void list_append(struct list* plist, struct list_elem* elem);
void list_remove(struct list_elem* pelem);
struct list_elem* list_pop(struct list* plist);
bool elem_find(struct list* plist, struct list_elem* obj_elem);
struct list_elem* list_traversal(struct list* plist, function func, int arg);
unsigned int list_len(struct list* plist);
bool list_empty(struct list* plist);
#endif
// list.c
#include "list.h"
#include "intr_status_op.h"
#include "global.h"
// 核心数据结构 双向链表
void list_init(struct list* list) {
list->head.prev = NULL;
list->head.next = &list->tail;
list->tail.prev = &list->head;
list->tail.next = NULL;
}
void list_insert_before(struct list_elem* before, struct list_elem* elem) {
enum intr_status old_status = intr_disable();
before->prev->next = elem;
elem->prev = before->prev;
elem->next = before;
before->prev = elem;
intr_set_status(old_status);
}
void list_push(struct list* plist, struct list_elem* elem) {
list_insert_before(plist->head.next, elem);
}
void list_append(struct list* plist, struct list_elem* elem) {
list_insert_before(&plist->tail, elem);
}
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;
}
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;
}
struct list_elem* list_traversal(struct list* plist, function func, int arg) {
struct list_elem* elem = plist->head.next;
if(list_empty(plist)) {
return NULL;
}
while(elem != &plist->tail) {
if(func(elem, arg)) {
return elem;
}
elem = elem->next;
}
return NULL;
}
unsigned int list_len(struct list* plist) {
struct list_elem* elem = plist->head.next;
unsigned int length = 0;
while(elem != &plist->tail) {
length++;
elem = elem->next;
}
return length;
}
bool list_empty(struct list* plist) {
return (plist->head.next == &plist->tail ? true : false);
}