从thread_resume(thread_create("bootstrap2", &bootstrap2, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));展开对lk中thread的分析。
- struct thread。
typedef struct thread {
int magic; // thread魔数'thrd'
struct list_node thread_list_node; // thread链表,用于将lk中的thread链接起来
/* active bits */
struct list_node queue_node; // 运行队列链表
int priority; // thread优先级
enum thread_state state; // thread状态,分为THREAD_SUSPENDED,THREAD_READY, THREAD_RUNNING, THREAD_BLOCKED, THREAD_SLEEPING, THREAD_DEATH等六种状态
int saved_critical_section_count; // 相当于一个简单的锁机制
int remaining_quantum; //
/* if blocked, a pointer to the wait queue */
struct wait_queue *blocking_wait_queue; // 等待队列
status_t wait_queue_block_ret; // 等待队列唤醒时的状态
/* architecture stuff */
struct arch_thread arch; // 比较重要,目前只保留的thread的sp(堆栈)指针
/* stack stuff */
void *stack; // 初始化时分配的堆栈空间指针
size_t stack_size; // 初始化时分配的堆栈空间大小
/* entry point */
thread_start_routine entry; // thread入口函数
void *arg; // thread入口函数的参数
/* return code */
int retcode; // thread退出时的返回值
/* thread local storage */
uint32_t tls[MAX_TLS_ENTRY]; // 线程本地存储,未实现
char name[32]; // 线程名称
} thread_t;
- thread_create()。
thread_t *thread_create(const char *name, thread_start_routine entry, void *arg, int priority, size_t stack_size)
{
thread_t *t;
t = malloc(sizeof(thread_t)); // 从lk的heap中分配thread结构体内存,lk的heap实现比较简单,但功能齐全,有时间可以看一下
if (!t)
return NULL;
init_thread_struct(t, name); // 初始化thread,做了三个动作,结构体清零,设置魔数,设置name
t->entry = entry; // 对thread入口函数指针进行赋值
t->arg = arg;
// 对thread入口函数参数进行赋值
t->priority = priority; // 设置thread优先级
t->saved_critical_section_count = 1; /* we always start inside a critical section */
t->state = THREAD_SUSPENDED; // 设置thread的当前状态为挂起
t->blocking_wait_queue = NULL; // 等待队列为空
t->wait_queue_block_ret = NO_ERROR;
/* create the stack */
t->stack = malloc(stack_size); // 为thread分配堆栈
if (!t->stack) {
free(t);
return NULL;
}
t->stack_size = stack_size; // 记录堆栈大小
/* inheirit thread local storage from the parent */
int i;
for (i=0; i < MAX_TLS_ENTRY; i++)
t->tls[i] = current_thread->tls[i]; // 未实现
/* set up the initial stack frame */
arch_thread_initialize(t); // 设置栈帧等,这个函数十分关键,因为涉及到了thread的切换
/* add it to the global thread list */
enter_critical_section();
list_add_head(&thread_list, &t->thread_list_node); // 将新生成的thread加入到lk的thread链表中
exit_critical_section();
return t;
}
struct context_switch_frame {
vaddr_t r4;
vaddr_t r5;
vaddr_t r6;
vaddr_t r7;
vaddr_t r8;
vaddr_t r9;
vaddr_t r10;