⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sched.c

📁 os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm
💻 C
字号:
#include "../include/kernel/sched.h"#include "../include/kernel/sys.h"#include "../include/kernel/irq.h"#include "../include/kernel/task.h"#include "../include/kernel/typedef.h"#include "../include/s3c2410/timer.h"#include "../include/s3c2410/cpu.h"#include "../include/mm/mm.h"#include "../include/kernel/gui.h"#define TASK_MEM_LIMIT	(1024*1024*32)//#define _SCHEDULE_DEBUG/* *	任务数组指针 */int volatile jiffies=0;struct task_struct* task[NR_TASKS];struct task_struct* current;unsigned int last_pid;extern struct irq_ctrl_object 	irq_ctrl_object;extern void restorer();extern void irq();#define FIRST_TASK	&task[0]#define LAST_TASK	&task[NR_TASKS-1]#define KERNEL_BASE	0x30095000#define KERNEL_LIMIT	0x30400000struct task_struct INIT_TASK={	.state		=TASK_RUNNING,	.priority	=15,	.counter	=15,	.signal		=0,	.deal_signal	=0,	.blocked	=0,		.sigaction	={0,},	.alarm		=0,	.utime		=0,	.stime		=0,	.cutime		=0,	.cstime		=0,	.start_time	=0,	.exit_code	=0,		/*	 *	任务0的代码段使用了内核的空间而数据段的虚拟地址则是0x00000000~0x01ffffff,	 *	 *	本内核中规定任务的代码段和数据段必须相同,而任务0比较特殊,他的代码段和数	 *	据段是分开的	 */	.code_segment_base	=0x30000000,	.code_segment_limit	=0x30a00000,	.data_segment_base	=0,	.data_segment_limit	=0x2000000,		.pid		=0,	.father		=0,	.cpu_registers={/* r0   */	.r0=0,/* r1   */	.r1=0,/* r2   */	.r2=0,/* r3   */	.r3=0,/* r4   */	.r4=0,/* r5   */	.r5=0,/* r6   */	.r6=0,/* r7   */	.r7=0,/* r8   */	.r8=0,/* r9   */	.r9=0,/* r10  */	.r10=0,/* r11  */	.r11=0,/* r12  */	.r12=0,/* sp   */	.sp=0x2000000-4,/* lr   */	.lr=0,/* pc   */	.pc=0,/* cpsr */	.cpsr=0,	}};union task_union init_task; void sched_init(){	int i;		for(i=0;i<NR_TASKS;i++)	{		task[i]=0;	}	last_pid=0;	jiffies	=0;		init_task.task=INIT_TASK;	task[0]=&init_task.task;	current=task[0];}void sleep_on(struct task_struct** p){	struct task_struct* tmp;		if(!p)		return;	if(current==task[0])		panic("task0 try to sleep.\n");		//进入临界区	//ENTER_CRITICAL();		//EXIT_CRITICAL();}void wake_up(struct task_struct** p){	//进入临界区	ENTER_CRITICAL();		EXIT_CRITICAL();}void save_cpu_context(unsigned int *regs){	unsigned int *p_reglist=&current->cpu_registers.r0;	int regid;	for(regid=0;regid<17;regid++)	{		p_reglist[regid]=regs[regid];	}	p_reglist[15]=regs[15]-4;}void load_cpu_context(unsigned int *regs){	unsigned int *p_reglist=&current->cpu_registers.r0;	int regid;	for(regid=0;regid<17;regid++)	{		regs[regid]=p_reglist[regid];	}	regs[15]=p_reglist[15]+4;}void switch_to_next(struct cpu_registers *regs,int nr){	if(current!=task[nr])	{		//切换任务		save_cpu_context(regs);	//保存当前任务状态		current=task[nr];	//当前任务切换为待加载的任务		set_process_id(nr);	//更改CPU的Process ID寄存器(与MVA有关)		load_cpu_context(regs); //加载新任务		/*		 *	将新任务的cpsr写入irq的spsr,中断返回的时候会把spsr的值加载到		 *	cpsr.这样才能保证每个任务运行在自己的特权级		 */		write_spsr(current->cpu_registers.cpsr);	}}/* *	任务调度函数,这个函数是支持多任务并行的关键 */int schedule(){	unsigned int max_counter=0;//当前最长时间片	int i;	int nr;	feed_dog();		/*	 *	任务调度的基本思路是这样的:从任务数组中选拥有最长间片	 *	的任务,切换运行.若所有任务的时间片都是0,说明所有任务	 *	都用完了时间片,则重新对时间片进行付值	 */	while(1)	{			//挑选出最长时间片的任务		for(i=0;i<NR_TASKS;i++)		{			//当前任务槽不为空且该任务槽的任务是运行状态的			if((task[i])&&(task[i]->state==TASK_RUNNING))			{				//该任务时间片是否大于当前最长时间片				if(task[i]->counter>max_counter)				{					max_counter=task[i]->counter;					nr=i;//获得当前最长时间片的任务号				}			}		}				//所有任务的时间片都是0,说明所有任务都用完了时间片		if(max_counter==0)		{			for(i=0;i<NR_TASKS;i++)			{				//重新分配任务的时间片				if(task[i]!=0)					task[i]->counter=task[i]->priority;			}		}		else			break;	}		return nr;//返回准备调度的任务号}//手动切换进程int switch_task(){	int next;	next=schedule();	return next;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -