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

📄 sched.cc

📁 南京航空航天大学开发的一个类Unix和Linux的操作系统,好不好看看就知道了,
💻 CC
字号:
#include <lib/root.h>#include <lib/gcc.h>#include <lib/ostream.h>#include <init/ctor.h>#include <asm/seg.h>#include <asm/irq.h>#include <mm/allockm.h>#include "sched.h"#include "signal.h"static int needresched;static ulong nlongjump;#define NRUNTASKQ 32static ulong mask;static runtaskq_t runtaskq[NRUNTASKQ];task_t * curr; /* current task */static softirq_t * timersoftirq;extern void timersoftisr(void * obj);static void timerisr(void * obj, int irqno);__ctor(PRIKERN,SUBANY,scheduler){	construct(runtaskq, NRUNTASKQ);	allocirq(timerisr, NULL, CLKIRQ);	irqon(CLKIRQ);	timersoftirq = allocsoftirq(timersoftisr, NULL);}void dumpsched(ostream_t * os){	os->write("passed tick = %d, context switch = %d\n", passedtick, nlongjump);}static void checkmask(){#if DEBUG	psw_t psw;	psw.save(), cli();	assert(mask);	for (int i = 0; i < NRUNTASKQ; i++) {		if ((mask >> i) & 1) {			assert(!runtaskq[i].empty());		} else {			assert(runtaskq[i].empty());		}	}	psw.restore();#endif}/* interruptible task will be waked up at the time it receive a signal */static void checkwait(){#if DEBUG	task_t * task;	foreach (task, alltaskq)		if (task->state == TWAIT)			assert(!task->hassig());#endif}static void timerisr(void * obj, int irqno){	timersoftirq->request();	passedtick++;	if (curr->state != TRUN)		return;	/* uspace(r->eip) ? curr->utick++ : curr->stick++; */	if (curr->counter == 0) {		needresched = 1;		return;	}	curr->setcounter(curr->counter - 1);	needresched = 1; /* unnecessary */	return;}void task_t::enqrun(){	assert(between(0, counter, NRUNTASKQ));	runtaskq[counter].enqtail(this);	mask |= 1 << counter;}void task_t::deqrun(){	assert(between(0, counter, NRUNTASKQ));	assert(runtaskq[counter].index(this) >= 0);	unlinkrun();	if (runtaskq[counter].empty())		mask &= ~(1 << counter);}void task_t::setcounter(int newval){	psw_t psw;	if (state != TRUN) {		counter = newval;		return;	}	psw.save(), cli();	deqrun();	counter = newval;	enqrun();	psw.restore();}static task_t * find(){	task_t * task;	int idx;	checkwait();	checkmask();repeat:	asm ("bsrl %1,%0":"=r"(idx):"r"(mask));	if (!idx) { /* all the running task eat up their time quota */		foreach (task, alltaskq) {			int newval = task->priority + (task->counter << 1);			if (newval >= NRUNTASKQ)				newval = NRUNTASKQ - 1;			if (task == &idletask)				newval = 1;			task->setcounter(newval);		}		goto repeat;	}	task = runtaskq[idx].head();	allege(task->state == TRUN);	return task;}extern int sig;void sched(){	task_t * target;	cli();	target = find();	needresched = 0;	if ((curr->state == TRUN) && (curr->counter == target->counter)) {		sti();		return;	}	tss_t * from = &curr->tss, * to = &target->tss;	curr = target;	nlongjump++, longjump(from, to);	if (curr == lastusedmath)		asm volatile ("clts");	sti();}void prempt(){	if (needresched)		sched();}/* called during interrupt */void task_t::wakeup(){	if ((state != TSLEEP) && (state != TWAIT))		return;	psw_t psw;	psw.save(), cli();	unlinkrun();	state = TRUN;	enqrun();	if (counter >= curr->counter + 2)		needresched = 1;	psw.restore();}static void sigalarm(void * obj){	((task_t*)obj)->post(SIGALRM);}asmlinkage int sysalarm(int seconds){	if (seconds == 0) {		curr->alarm.stop();		return 0;	}	if (curr->alarm.active())		return 0;	curr->alarm.init(timetotick(seconds), sigalarm, curr);	curr->alarm.start();	return 0;}asmlinkage int sysnice(int inc){	if (inc < 0 && !suser())		return EPERM; 	if (between(0, curr->priority - inc, NRUNTASKQ))		curr->priority -= inc;	curr->setcounter(0);	return 0;}

⌨️ 快捷键说明

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