内核线程参考的是郑钢先生《操作系统真相还原》,主要是觉得这种实现线程和进程的方式非常的巧妙,另外在这方面想要创新的话,空间也是很小的。

为了编程方便,thread当中包含了进程的阻塞和唤醒以及二元信号量和锁,这些是实现互斥和同步的基础。

// thread.h
#ifndef __THREAD_H
#define __THREAD_H
#include "list.h"
#include "sync.h"typedef void thread_func(void*);enum task_status {RUNNING, READY, BLOCKED, WAITING, HANDING, DIED
};/*
_exit:pop gspop fspop espop dspopaadd esp, 2 * 4iret
*/struct mem_desc {struct list_elem tag; //用它来串成链表unsigned int start, size; // start页的起始地址,size内存的字节大小int status; // status 正在被free使用0,或者正在被used使用1,或者空闲-1
};struct mem_man {struct mem_desc* md_a;struct list free, used; // 两个链表一个是空闲,一个是使用struct lock lock;
};struct intr_stack {unsigned int gs, fs, es, ds;unsigned int edi, esi, ebp, esp_dummy;unsigned int ebx, edx, ecx, eax;unsigned int vector_no_dummy, err_code_dummy;unsigned int eip, cs, eflags, esp, ss;
};struct thread_stack {unsigned int edi, esi, ebp, esp_dummy;unsigned int ebx, edx, ecx, eax;unsigned int kernel_thread;unsigned int retaddr_dummy, func, func_arg;
};struct task {unsigned int* self_kstack;unsigned int level;unsigned short pid;enum task_status status;char name[16];unsigned char priority;unsigned char ticks;unsigned int elapsed_ticks;struct list_elem general_tag;struct list_elem all_list_tag;unsigned int* pgdir;struct mem_man user_vir;unsigned int stack_magic;
};struct task* running_thread(void);
void kernel_thread(thread_func* function, void* func_arg);
void thread_create(struct task* pthread, thread_func function,void* func_arg);
void init_thread(struct task* pthread, char* name, int prio, unsigned int level);
struct task* thread_start(char* name, int prio, thread_func function, void * func_arg, unsigned int level);
void make_main_thread(void);
void schedule(void);
void thread_init(void);
void thread_block(enum task_status stat);
void thread_unblock(struct task* pthead);struct task* main_thread;
struct list ready_list[8];
struct list* thread_ready_list;
struct list thread_all_list;
static struct list_elem* thread_tag;void ticks_to_sleep(unsigned int sleep_ticks);
void mtime_sleep(unsigned int msecond);struct lock pid_lock;#endif
// thread.c
#include "list.h"
#include "thread.h"
#include "intr_status_op.h"
#include "memory.h"
#include "string.h"
#include "debug.h"
#include "sync.h"
#include "process.h"extern void switch_to(struct task* cur, struct task* next);
extern unsigned int ticks;struct task* running_thread(void) {unsigned int esp;__asm__ __volatile__("movl %%esp, %0":"=g"(esp));return (struct task*)(esp & 0xfffff000);
}void kernel_thread(thread_func* function, void* func_arg) {intr_enable();function(func_arg);
}void thread_create(struct task* pthread, thread_func function, void* func_arg) {pthread->self_kstack -= sizeof(struct intr_stack);pthread->self_kstack -= sizeof(struct thread_stack);struct thread_stack* kthread_stack =(struct thread_stack*)pthread->self_kstack;kthread_stack->kernel_thread = (unsigned int)kernel_thread;kthread_stack->func = (unsigned int)function;kthread_stack->func_arg = (unsigned int)func_arg;kthread_stack->eax = kthread_stack->ecx = kthread_stack->edx =kthread_stack->ebx = kthread_stack->esp_dummy = kthread_stack->ebp =kthread_stack->esi = kthread_stack->edi = 0;
}unsigned short alloc_pid(void) {static unsigned int next_pid = 0;lock_acquire(&pid_lock);next_pid++;lock_release(&pid_lock);return next_pid;
}void init_thread(struct task* pthread, char* name, int prio, unsigned int level) {memset_(pthread, 0, sizeof(*pthread));pthread->pid = alloc_pid();strcpy_(pthread->name, name);if(pthread == main_thread) {pthread->status = RUNNING;} else {pthread->status = READY;}pthread->self_kstack = (unsigned int*)((unsigned int)pthread + 4096);pthread->priority = prio;pthread->ticks = prio;pthread->level = level;pthread->elapsed_ticks = 0;pthread->pgdir = NULL;pthread->stack_magic = 0x19810602;
}struct task* thread_start(char* name, int prio, thread_func function,
void * func_arg, unsigned int level) {struct task* thread = get_kernel_pages(1);init_thread(thread, name, prio, level);thread_create(thread, function, func_arg);ASSERT((level >= 0) && (level <= 7));thread_ready_list = &ready_list[thread->level];ASSERT(!elem_find(thread_ready_list, &thread->general_tag));list_append(thread_ready_list, &thread->general_tag);ASSERT(!elem_find(&thread_all_list, &thread->all_list_tag));list_append(&thread_all_list, &thread->all_list_tag);return thread;
}void make_main_thread(void) {main_thread = running_thread();init_thread(main_thread, "main", 31, 0);ASSERT(!elem_find(&thread_all_list, &main_thread->all_list_tag));list_append(&thread_all_list, &main_thread->all_list_tag);
}void schedule(void) {ASSERT((intr_get_status() == INTR_OFF));struct task* cur = running_thread();if(cur->status == RUNNING) {ASSERT(!elem_find(thread_ready_list, &cur->general_tag));list_append(thread_ready_list, &cur->general_tag);cur->ticks = cur->priority;cur->status = READY;} else {}int i;for(i = 0; i < 8; i++) {thread_ready_list = &ready_list[i];if(!list_empty(thread_ready_list)) {break;}}ASSERT(!list_empty(thread_ready_list));thread_tag = list_pop(thread_ready_list);struct task* next = elem2entry(struct task, general_tag, thread_tag);next->status = RUNNING;process_activate(next);switch_to(cur, next);
}void thread_init(void) {int i;for(i = 0; i < 8; i++) {list_init(&ready_list[i]);     }list_init(&thread_all_list);lock_init(&pid_lock);make_main_thread();
}void thread_block(enum task_status stat) {enum intr_status old_status = intr_disable();ASSERT(((stat == BLOCKED) || (stat == HANDING) || (stat == WAITING)));struct task* cur = running_thread();cur->status = stat;schedule();intr_set_status(old_status);
}void thread_unblock(struct task* pthread) {enum intr_status old_status = intr_disable();
//  ASSERT(((pthread->status == BLOCKED) ||
//          (pthread->status == HANDING) ||
//          (pthread->status == WAITING)));if(pthread->status != READY) {ASSERT(!(elem_find(thread_ready_list, &pthread->general_tag)));if(elem_find(thread_ready_list, &pthread->general_tag)) {PANIC("thread_unblock: blocked thread in ready_list\n");}list_push(thread_ready_list, &pthread->general_tag);pthread->status = READY;}intr_set_status(old_status);
}void yield(void) {struct task* cur = running_thread();enum intr_status old_status = intr_disable();ASSERT(!elem_find(thread_ready_list, &cur->general_tag));list_append(thread_ready_list, &cur->general_tag);cur->status = READY;schedule();intr_set_status(old_status);
}void ticks_to_sleep(unsigned int sleep_ticks) {unsigned int short start_ticks = ticks;while(ticks - start_ticks < sleep_ticks) {yield();}
}void mtime_sleep(unsigned int msecond) {unsigned sleep_ticks = msecond / 10 + 1;ASSERT(sleep_ticks > 0);ticks_to_sleep(sleep_ticks);
}
// sync.h
#ifndef __SYNC_H
#define __SYNC_H
#include "list.h"
#include "thread.h"struct semaphore {unsigned char value;struct list waiters;
};struct lock {struct task* holder;struct semaphore semaphore;unsigned int holder_repeat_nr;
};void sema_init(struct semaphore* psema, unsigned char value);
void lock_init(struct lock* plock);
void sema_down(struct semaphore* psema);
void sema_up(struct semaphore* psema);
void lock_acquire(struct lock* plock);
void lock_release(struct lock* plock);#endif
// sync.c
#include "memory.h"
#include "intr_status_op.h"
#include "debug.h"void sema_init(struct semaphore* psema, unsigned char value) {psema->value = value;list_init(&psema->waiters);
}void lock_init(struct lock* plock) {plock->holder = NULL;plock->holder_repeat_nr = 0;sema_init(&plock->semaphore, 1);
}void sema_down(struct semaphore* psema) {enum intr_status old_status = intr_disable();while(psema->value == 0) {ASSERT(!elem_find(&psema->waiters, &running_thread()->general_tag));if(elem_find(&psema->waiters, &running_thread()->general_tag)) {PANIC("seam_down: thread blocked has been in waiters_list\n");}list_append(&psema->waiters, &running_thread()->general_tag);thread_block(BLOCKED);}psema->value--;ASSERT(psema->value == 0);intr_set_status(old_status);
}void sema_up(struct semaphore* psema) {enum intr_status old_status = intr_disable();ASSERT(psema->value == 0);if(!list_empty(&psema->waiters)) {struct task* thread_blocked = elem2entry(struct task, general_tag,list_pop(&psema->waiters));thread_unblock(thread_blocked);}psema->value++;ASSERT(psema->value == 1);intr_set_status(old_status);
}void lock_acquire(struct lock* plock) {if(plock->holder != running_thread()) {sema_down(&plock->semaphore);plock->holder = running_thread();ASSERT(plock->holder_repeat_nr == 0);plock->holder_repeat_nr = 1;} else {plock->holder_repeat_nr++;}
}void lock_release(struct lock* plock) {ASSERT(plock->holder == running_thread());if(plock->holder_repeat_nr > 1) {plock->holder_repeat_nr--;return;}ASSERT(plock->holder_repeat_nr == 1);plock->holder = NULL;plock->holder_repeat_nr = 0;sema_up(&plock->semaphore);
}

Snail OS 0.03的thread目录是内核线程相关推荐

  1. Snail OS 0.03 user是用户进程和系统调用的简单实现

    进程是操作系统中用户程序运行的基本单位,而用户进程要想使用操作系统的功能必须通过系统调用. 而进程在x86体系结构上就少不了任务状态段,所以这里也一并实现了. // tss.h #ifndef __T ...

  2. SnailOS 0.03 的intr_status_op目录就是开关中断的操作

    只不过这个开关中断的操作要回复之前的中断状态,起始实现这样的操作又很多不同的方法,这里只是照搬了郑钢先生的代码. // intr_status_op.h#ifndef __INTR_STATUS_H ...

  3. rust 手动关闭子线程_从零开始写 OS (9) —— 内核线程

    上一篇 小源:从零开始写 OS (8) -- 创建页表​zhuanlan.zhihu.com 本章代码对应 commit :de86ae6e1e8bdfe3388530f82b2081fe29e40b ...

  4. 拼一个自己的操作系统(SnailOS 0.03的实现)

    拼一个自己的操作系统 SnailOS 0.03的实现 拼一个自己的操作系统SnailOS0.03源代码-Linux文档类资源-CSDN下载 操作系统SnailOS学习拼一个自己的操作系统-Linux文 ...

  5. 【爬坑总结】elementary OS 0.4.1 Loki 下引导修复和安装搜狗输入法

     爬坑总结---elementary OS 0.4.1 Loki 下引导修复和安装搜狗输入法 最近感觉我的windows7实在是太臃肿了,所以装了个linux来写写文章.搞搞编程.网上下载了ele ...

  6. JDK5.0新特性系列---目录

    JDK5.0新特性系列---目录 JDK5.0新特性系列---1.自动装箱和拆箱 JDK5.0新特性系列---2.新的for循环 JDK5.0新特性系列---3.枚举类型 JDK5.0新特性系列--- ...

  7. matlab e 精确到,matlab中用0.618法求minf(x)=e^(-x)+x^2在区间(0,1)上的极小值,精确到0.03....

    共回答了15个问题采纳率:86.7% clc clear all; elp=0.03; tao=0.618; N=fix(log(elp)/log(tao))+1; k=1; a(k)=0; b(k) ...

  8. 直击 Elementary OS 0.3 Freya - 下载和安装指南

    直击 Elementary OS 0.3 Freya - 下载和安装指南 Elementary OS是一个以Ubuntu为基础的轻量级操作系统,广受欢迎.目前已经发行了三个版本,而第四个版本将会以即将 ...

  9. Chrome OS 0.4.220 Beta下载已发布

    备受关注的谷歌操作系统终于要发布了,广大谷歌爱好者欢欣鼓舞,迎接这一喜讯!目前放出的版本是0.4.220beta测试版本,详细下载地址如下: http://sites.google.com/site/ ...

最新文章

  1. SharePoint运行状况分析器有关磁盘空间不足的警告
  2. 全1的向量与行向量或列向量相乘,实质上是作行复制或列复制!
  3. Jmeter之HTTP Request Defaults
  4. 在.Net中进行跨线程的控件操作(上篇:Control.Invoke)
  5. HTML学习笔记05-文本格式化
  6. Django 之 modelForm (edit.html页面的编写)
  7. 华为hg-526拨号加路由破解简介
  8. 全局索引 前缀索引_面试系列 索引种类与优化
  9. 强连通分量[trajan]
  10. C语言程序设计题解pdf,C语言程序设计题解与上机指导.pdf
  11. 单GPU实现20Hz决策,最新基于序列生成模型的高效轨迹规划方法
  12. 最小化GUI安装oracle,最小化安装OEL6.5和配置
  13. android10全面屏手势 操作图,丨系统设计丨ZUI 10加入更多全面屏手势
  14. 色相 色调_如何使用色相调光器开关控制飞利浦色相灯
  15. 树莓派的GPIO端口详解
  16. Ada 程序设计语言(The Ada Programming Language)[第一集]
  17. 定时闹钟功能(带铃声 可延时)
  18. JS输出100以内的素数
  19. 10天学会ASP打包下载
  20. java 忽略大小写

热门文章

  1. python ppt提取其中几页另存为新的ppt
  2. 大厚度耐磨钢NM450和NM500钢板技术条件
  3. CSV文件导入数据库的三种方法
  4. python自动化库_Python操作自动化库PyAutoGUI的方法
  5. 如何搭建普罗米修斯 Prometheus
  6. Windows7 64位环境下Python-igraph环境配置
  7. Rhino可以用python脚本吗?
  8. UVA 11817 Tunnelling the Earth --球面距离公式
  9. 【创建微服务】创建微服务并使用人人开源代码生成器生成基本代码
  10. 使用人人开源的代码生成器生成开发代码