task.c
#include "task.h"
#include "../interrupt/syscall.h"
#include "../stl/elf.h"
#include "../mem/pmm.h"
#include "../mem/vmm.h"
#include "../mem/memlayout.h"
#include "../debug/debug.h"
#include "../sync/sync.h"
#include "../file/file.h"
#include "../file/inode.h"
#define HASH_SHIFT 10
#define HASH_LIST_SIZE (1 << HASH_SHIFT)
#define pid_hashfn(x) (hash32(x, HASH_SHIFT))
/*
#define __KERNEL_EXECVE(name, binary, size) ({ \
printk("kernel_execve: pid = %d, name = \"%s\".\n", \
current->pid, name); \
kernel_execve(name, binary, (unsigned int)(size)); \
})
//#x 表示字符串操作符,即"x"
//##x##表示连接符
#define KERNEL_EXECVE(x) ({ \
extern unsigned char _binary_##x##_out_start[], \
_binary_##x##_out_size[]; \
__KERNEL_EXECVE(#x, _binary_##x##_out_start, \
_binary_##x##_out_size); \
})
#define __KERNEL_EXECVE2(x, xstart, xsize) ({ \
extern unsigned char xstart[], xsize[]; \
__KERNEL_EXECVE(#x, xstart, (unsigned int)xsize); \
})
#define KERNEL_EXECVE2(x, xstart, xsize) __KERNEL_EXECVE2(x, xstart, xsize)
*/
// 绑定PID的哈希表
static list_entry_t hash_list[HASH_LIST_SIZE];
//PID 位图初始化
pidmap_t task_pidmap={pid_max,{0}};
static unsigned int volatile last_pid=0;
//就绪进程链表
static list_entry_t ready_task_list;
//所有进程链表
static list_entry_t all_task_list;
struct task_struct *task0; //祖先进程,即进程0
struct task_struct *user_task; //第一个用户进程
//struct task_struct *task1; //由进程0 do_fork出来的进程1
struct task_struct *current; //指向当前进程
extern struct semaphore user_sema;
//MACOS下容易出现BUG
//静态全局变量设置为0值时,在运行的时候容易跑飞,所以为了避免出现BUG,在使用的时候应先定义0值
static unsigned int volatile nr_task=0; //当前所有进程数量
void forkrets(struct trapframe *tf);
extern unsigned int __trapret;
extern struct file file_table[MAX_FILE_OPEN];
extern struct segdesc gdt[];
extern unsigned int new_pdt[PAGE_DIR_SIZE] __attribute__( (aligned(VMM_PAGE_SIZE) ) );
extern unsigned int user_pt_highmem[(unsigned int)0xC0000000/
((unsigned int)PAGE_TABLE_SIZE*(unsigned int)VMM_PAGE_SIZE)]
[PAGE_TABLE_SIZE]__attribute__( (aligned(VMM_PAGE_SIZE) ) );
struct task_struct *task0,*task1;
/*
* kernel_task_init:创建第一个内核进程
*/
void kernel_task_init(void *function){
/*就绪进程链表初始化*/
list_init(&ready_task_list);
/*所有进程链表初始化*/
list_init(&all_task_list);
/*哈希链表初始化*/
for(int i=0;i<HASH_LIST_SIZE;i++){
list_init(&hash_list[i]);
}
//分配task_struct结构体
if((task0=alloc_task(KERNEL_TASK))==NULL){
printk("alloc task error!\n");
}
/* 设置task0属性 */
task0->state=STOPPED;
task0->counter=5;
task0->priority=1;
last_pid=task0->pid=0; //初始化task0的PID和last_pid
set_task_name(task0,"kernel_task");
task0->kernel_stack=(unsigned int)task0+VMM_PAGE_SIZE;
task0->cr3=LA_PA((unsigned int)new_pdt);
task0->cwd_inode_nr=0;
task0->tf = (struct trapframe *)(task0->kernel_stack)- 1;
task0->tf->tf_regs.reg_eax=0;
task0->tf->tf_regs.reg_ebp=0;
task0->tf->tf_regs.reg_ebx=0;
task0->tf->tf_regs.reg_ecx=0;
task0->tf->tf_regs.reg_edi=0;
task0->tf->tf_regs.reg_edx=0;
task0->tf->tf_regs.reg_esi=0;
task0->tf->tf_regs.reg_oesp=0;
task0->tf->tf_cs=KERNEL_CS;
task0->tf->tf_ds=task0->tf->tf_es=task0->tf->tf_fs=task0->tf->tf_ss=KERNEL_DS;
task0->tf->tf_gs=0;
task0->tf->tf_eip=0;//function; //user_space1
task0->tf->tf_eflags=(EFLGAS_IOPL_0|EFLAGS_MBS|EFLAGS_IF_1);
task0->tf->tf_esp=task0->kernel_stack-sizeof(struct trapframe);
/*设置用户的上下文*/
task0->context.eip=function;//task0->tf->tf_eip;
task0->context.esp= (unsigned int)(task0->tf);
task0->context.ebx=task0->tf->tf_regs.reg_ebx;
task0->context.edx=task0->tf->tf_regs.reg_edx;
/* 进程链表指向task0 */
//ask_list=task0->link; //待调试
//memcpy(&(task_list),&(task0->link),sizeof(list_entry_t));
//list_init(&task0->link);
//插入就绪任务链表
list_init(&task0->link);
add_link(&task0->link);
//插入所有任务链表
list_init(&task0->all_link);
add_all_link(&task0->all_link);
task0->fd_table[0]=0;
task0->fd_table[1]=1;
task0->fd_table[2]=2;
for(int i=3;i<MAX_FILE_OPEN;i++){
task0->fd_table[i]=-1;
}
/* 当前进程指向task0 */
current=task0;
//clear();
//printk("task0->counter:%08d!\n",task0->counter);
//printk("current:%08X!\n",current);
//printk("In task_init,current->counter=%08d\n",current->counter);
/* 根据PID加入哈希链表 */
add_pid_hash(task0);
wakeup_task(task0);
//这时候直接赋值,以免静态全局变量在不同编译器下跑飞
//nr_task++;
nr_task=1;
}
//设置PID位
static int set_pid_bit(int pid){
//获取PID所在的字节号
int chars=pid/8;
//获取PID所在字节的偏移位
int offset=pid%8;
//置位
set_char_bit(task_pidmap.bits[chars],offset,1);
}
//清除PID位
static int clear_pid_bit(int pid){
//获取PID所在的字节号
int chars=pid/8;
//获取PID所在字节的偏移位
int offset=pid%8;
//清零
set_char_bit(task_pidmap.bits[chars],offset,0);
}
//返回未被占用的PID号,若没有则返回-1
static int find_free_pid(){
int i=0,k=0;
while(k!=32768){
for(int j=0;j<8;j++,k++){
if((task_pidmap.bits[i]>>j)&1==0){
return k;
}
}
i++;
}
return -1;
}
//分配一个可用的PID
static int alloc_pid(){
//若无多余的PID号
if(!task_pidmap.nr_free){
return -1;
}
/*
** 一般将PID号设置为上个进程PID号+1
** 若PID号已设置到末尾,则查询位图中是否还有未被占用的PID号
*/
int pid=(pid==32767)?find_free_pid():last_pid+1;
//有效PID
if(pid>=0){
set_pid_bit(pid);
task_pidmap.nr_free--;
}
last_pid=pid;
return pid;
}
//释放一个PID
static void free_pid(int pid){
clear_pid_bit(pid);
task_pidmap.nr_free++;
}
// 设置进程名称
char *set_task_name(struct task_struct *task, const char *name) {
memset(task->name, 0, sizeof(task->name));
return memcpy(task->name, name, task_name_max);
}
// 获取进程名称
char *get_task_name(struct task_struct *task) {
static char name[task_name_max + 1];
memset(name, 0, sizeof(name));
return memcpy(name, task->name, task_name_max);
}
//将新进程插入就绪进程链表队尾
static void add_link(list_entry_t *new){
list_add_before(&ready_task_list,new);
}
//将新进程插入所有进程链表队尾
static void add_all_link(list_entry_t *new){
list_add_before(&all_task_list,new);
}
//在进程链表中删除某个进程
static void remove_link(list_entry_t *node){
list_del(node);
}
//根据PID加入到PID哈希表中
static void add_pid_hash(struct task_struct *task){
list_add(hash_list+pid_hashfn(task->pid),&(task->hash_link));
}
//根据PID删除哈希表中的节点
static void remove_pid_hash(int pid){
struct task_struct *task=find_task(pid);
list_del(&(task->hash_link));
}
//给定PID,在哈希表查找进程
static struct task_struct* find_task(int pid){
if(pid<0){
return NULL;
}
//找到哈希链表头
list_entry_t *head=&hash_list[pid_hashfn(pid)];
list_entry_t *ite=head;
//在哈希表头下的双向循环链表(不包含哈希表头)中查找PID对应的进程
while((ite=list_next(ite))!=head){
struct task_struct *task=list_to_task(ite,hash_link);
if(task->pid==pid){
return task;
}
}
//未找到
return NULL;
}
//给进程分配task_struct结构体,判断是用户进程还是内核进程
static struct task_struct* alloc_task(enum task_kind kind){
struct task_struct *task;
if(kind==KERNEL_TASK)
task=vmm_malloc(VMM_PAGE_SIZE*2,1);
else
task=vmm_malloc(VMM_PAGE_SIZE*2,2);
if(task!=NULL){
task->state=UNRUNNABLE;
task->counter=5;
task->priority=0;
task->pid=-1;
memset(&(task->name),0,sizeof(task->name));
task->kernel_stack=0;
task->cr3=new_pdt;
task->tf=NULL;
memset(&(task->context),0,sizeof(task->context));
task->magic=TASK_MAGIC;
task->cwd_inode_nr=0;
for(int i=0;i<MAX_FILE_OPEN;i++){
task->fd_table[i]=-1;
}
}
return task;
}
/* 由kernel_thread去执行function(func_arg) */
//static void kernel_thread(thread_func* function, void* func_arg) {
/* 执行function前要开中断,避免后面的时钟中断被屏蔽,而无法调度其它线程 */
// intr_enable();
// function(func_arg);
//}
// forkret -- t