目录
一、写在前面
本期分析的代码为threads文件夹下的源代码文件,threads中包含了描述内核线程的类、线程的调度器、线程上下文切换的实现以及进程同步的各种工具,在第一节主要分析list.h/cc与thread.h/cc
通过本节的分析,我们能够进一步了解nachos的内在运行逻辑,也能体会到在操作系统这门课程中学到的理论概念在编程实践中的应用.
二、源码分析
1、调度列表:List
class ListElement {
public:
ListElement(void *itemPtr, int sortKey); // initialize a list element
ListElement *next; // next element on list,
// NULL if this is the last
int key; // priority, for a sorted list
void *item; // pointer to item on the list
};
// The following class defines a "list" -- a singly linked list of
// list elements, each of which points to a single item on the list.
//
// By using the "Sorted" functions, the list can be kept in sorted
// in increasing order by "key" in ListElement.
class List {
public:
List(); // initialize the list
~List(); // de-allocate the list
void Prepend(void *item); // Put item at the beginning of the list
void Append(void *item); // Put item at the end of the list
void *Remove(); // Take item off the front of the list
void Mapcar(VoidFunctionPtr func); // Apply "func" to every element
// on the list
bool IsEmpty(); // is the list empty?
// Routines to put/get items on/off list in order (sorted by key)
void SortedInsert(void *item, int sortKey); // Put item into list
void *SortedRemove(int *keyPtr); // Remove first item from list
private:
ListElement *first; // Head of the list, NULL if list is empty
ListElement *last; // Last element of list
};
首先来看List类的头文件List.h,在头文件中我们发现List提供的方法有如下:
- Append:向列表尾部追加一个元素
- Prepend:插入元素至列表头部
- Mapcar:将列表中各元素通过给定的函数进行映射
- SortedInsert:按照给定的排序依据进行插入
- Remove:移除并返回头部的元素
- SortedRemove:移除并返回头部的元素,将传入指针keyPtr指向的整型值设为该元素的排序权值
- IsEmpty:判断列表是否为空
除此之外,我们发现其中还定义了ListElement类,其数据成员有指向ListElemennt对象的指针、用于排序的权值,和保存数据用的void指针.由此可见,List的实现为链式表.
ListElement::ListElement(void *itemPtr, int sortKey)
{
item = itemPtr;
key = sortKey;
next = NULL; // assume we'll put it at the end of the list
}
List::List()
{
first = last = NULL;
}
List::~List()
{
while (Remove() != NULL)
; // delete all the list elements
}
void
List::Append(void *item)
{
ListElement *element = new ListElement(item, 0);
if (IsEmpty()) { // list is empty
first = element;
last = element;
} else { // else put it after last
last->next = element;
last = element;
}
}
void
List::Prepend(void *item)
{
ListElement *element = new ListElement(item, 0);