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

📄 sched.c

📁 最早的linux操作系统源代码(3)
💻 C
字号:
/* * 'sched.c' is the main kernel file. It contains scheduling primitives * (sleep_on, wakeup, schedule etc) as well as a number of simple system * call functions (type getpid(), which just extracts a field from * current-task */#include <linux/sched.h>#include <linux/kernel.h>#include <signal.h>#include <linux/sys.h>#include <asm/system.h>#include <asm/io.h>#include <asm/segment.h>#define LATCH (1193180/HZ)extern void mem_use(void);extern int timer_interrupt(void);extern int system_call(void);extern int my_call(void);union task_union {	struct task_struct task;	char stack[PAGE_SIZE];};static union task_union init_task = {INIT_TASK,};long volatile jiffies=0;long startup_time=0;struct task_struct *current = &(init_task.task), *last_task_used_math = NULL;struct task_struct * task[NR_TASKS] = {&(init_task.task), };long user_stack [ PAGE_SIZE>>2 ] ;struct {	long * a;	short b;	} stack_start = { & user_stack [PAGE_SIZE>>2] , 0x10 };/* *  'math_state_restore()' saves the current math information in the * old math state array, and gets the new ones from the current task */void math_state_restore(){	if (last_task_used_math)		__asm__("fnsave %0"::"m" (last_task_used_math->tss.i387));	if (current->used_math)		__asm__("frstor %0"::"m" (current->tss.i387));	else {		__asm__("fninit"::);		current->used_math=1;	}	last_task_used_math=current;}/* *  'schedule()' is the scheduler function. This is GOOD CODE! There * probably won't be any reason to change this, as it should work well * in all circumstances (ie gives IO-bound processes good response etc). * The one thing you might take a look at is the signal-handler code here. * *   NOTE!!  Task 0 is the 'idle' task, which gets called when no other * tasks can run. It can not be killed, and it cannot sleep. The 'state' * information in task[0] is never used. */void schedule(void){	int i,next,c;	struct task_struct ** p;/* check alarm, wake up any interruptible tasks that have got a signal */	for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)		if (*p) {			if ((*p)->alarm && (*p)->alarm < jiffies) {					(*p)->signal |= (1<<(SIGALRM-1));					(*p)->alarm = 0;				}			if ((*p)->signal && (*p)->state==TASK_INTERRUPTIBLE)				(*p)->state=TASK_RUNNING;		}/* this is the scheduler proper: */	while (1) {		c = -1;		next = 0;		i = NR_TASKS;		p = &task[NR_TASKS];		while (--i) {			if (!*--p)				continue;			if ((*p)->state == TASK_RUNNING && (*p)->counter > c)				c = (*p)->counter, next = i;		}		if (c) break;		for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)			if (*p)				(*p)->counter = ((*p)->counter >> 1) +						(*p)->priority;	}	switch_to(next);}int sys_pause(void){	current->state = TASK_INTERRUPTIBLE;	schedule();	return 0;}void sleep_on(struct task_struct **p){	struct task_struct *tmp;	if (!p)		return;	if (current == &(init_task.task))		panic("task[0] trying to sleep");	tmp = *p;	*p = current;	current->state = TASK_UNINTERRUPTIBLE;	schedule();	if (tmp)		tmp->state=0;}void interruptible_sleep_on(struct task_struct **p){	struct task_struct *tmp;	if (!p)		return;	if (current == &(init_task.task))		panic("task[0] trying to sleep");	tmp=*p;	*p=current;repeat:	current->state = TASK_INTERRUPTIBLE;	schedule();	if (*p && *p != current) {		(**p).state=0;		goto repeat;	}	*p=NULL;	if (tmp)		tmp->state=0;}void wake_up(struct task_struct **p){	if (p && *p) {		(**p).state=0;		*p=NULL;	}}void do_timer(long cpl){	if (cpl)		current->utime++;	else		current->stime++;	if ((--current->counter)>0) return;	current->counter=0;	if (!cpl) return;	schedule();}int sys_alarm(long seconds){	current->alarm = (seconds>0)?(jiffies+HZ*seconds):0;	return seconds;}int sys_getpid(void){	return current->pid;}int sys_getppid(void){	return current->father;}int sys_getuid(void){	return current->uid;}int sys_geteuid(void){	return current->euid;}int sys_getgid(void){	return current->gid;}int sys_getegid(void){	return current->egid;}int sys_nice(long increment){	if (current->priority-increment>0)		current->priority -= increment;	return 0;}int sys_signal(long signal,long addr,long restorer){	long i;	switch (signal) {		case SIGHUP: case SIGINT: case SIGQUIT: case SIGILL:		case SIGTRAP: case SIGABRT: case SIGFPE: case SIGUSR1:		case SIGSEGV: case SIGUSR2: case SIGPIPE: case SIGALRM:		case SIGCHLD:			i=(long) current->sig_fn[signal-1];			current->sig_fn[signal-1] = (fn_ptr) addr;			current->sig_restorer = (fn_ptr) restorer;			return i;		default: return -1;	}}void sched_init(void){	int i;	struct desc_struct * p;	set_tss_desc(gdt+FIRST_TSS_ENTRY,&(init_task.task.tss));	set_ldt_desc(gdt+FIRST_LDT_ENTRY,&(init_task.task.ldt));	p = gdt+2+FIRST_TSS_ENTRY;	for(i=1;i<NR_TASKS;i++) {		task[i] = NULL;		p->a=p->b=0;		p++;		p->a=p->b=0;		p++;	}	ltr(0);	lldt(0);	outb_p(0x36,0x43);		/* binary, mode 3, LSB/MSB, ch 0 */	outb_p(LATCH & 0xff , 0x40);	/* LSB */	outb(LATCH >> 8 , 0x40);	/* MSB */	set_intr_gate(0x20,&timer_interrupt);	outb(inb_p(0x21)&~0x01,0x21);	set_system_gate(0x80,&system_call);	set_system_gate(0x40,&my_call);}

⌨️ 快捷键说明

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