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

📄 proc.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include	"u.h"#include	"lib.h"#include	"dat.h"#include	"fns.h"#include	"mem.h"struct{	Lock;	ulong	pid;} pidalloc;struct{	Lock;	User	*arena;	User	*free;} procalloc;volatile struct{	Lock;	User	*head;	User	*tail;} runq;char *statename[] =	/* BUG: generate automatically */{	[Dead]		"Dead",	[Moribund]	"Moribund",	[Zombie]	"Zombie",	[Ready]		"Ready",	[Scheding]	"Scheding",	[Running]	"Running",	[Queueing]	"Queueing",	[Sending]	"Sending",	[Recving]	"Recving",	[MMUing]	"MMUing",	[Exiting]	"Exiting",	[Inwait]	"Inwait",	[Wakeme]	"Wakeme",	[Broken]	"Broken",};staticvoidcmd_trace(int argc, char *argv[]){	int n;	n = 0;	if(argc > 1)		n = number(argv[1], n, 10);	dotrace(n);}staticvoidcmd_cpu(int argc, char *argv[]){	int i, j;	User *p;	char *text;	p = procalloc.arena;	for(i=0; i<conf.nproc; i++,p++) {		text = p->text;		if(!text)			continue;		for(j=1; j<argc; j++)			if(strcmp(argv[j], text) == 0)				goto found;		if(argc > 1)			continue;	found:		print("	%2d %.3s %9s%7W%7W%7W\n",			p->pid, text,			statename[p->state],			p->time+0, p->time+1, p->time+2);		prflush();	}}/* * Always splhi()'ed. */voidschedinit(void)		/* never returns */{	User *p;	setlabel(&m->sched);	if(u) {		m->proc = 0;		p = u;		u = 0;		if(p->state == Running)			ready(p);		p->mach = 0;	}	sched();}voidsched(void){	User *p;	void (*f)(Ureg *, ulong);	if(u) {		splhi();		if(setlabel(&u->sched)) {	/* woke up */			if(u->mach)				panic("mach non zero");			u->state = Running;			u->mach = m;			m->proc = u;			spllo();			return;		}		gotolabel(&m->sched);	}	if(f = m->intr){			/* assign = */		m->intr = 0;		(*f)(m->ureg, m->cause);	}	spllo();	p = runproc();	splhi();	u = p;	gotolabel(&p->sched);}voidready(User *p){	int s;	s = splhi();	lock(&runq);	p->rnext = 0;	if(runq.tail)		runq.tail->rnext = p;	else		runq.head = p;	runq.tail = p;	p->state = Ready;	unlock(&runq);	splx(s);}/* * Always called spllo */User*runproc(void){	User *p;	for (;;) {		while(runq.head == 0)		/* if nobody to run, */			;			/* idle with intrs enabled */		splhi();		lock(&runq);		p = runq.head;		if (p != nil && !p->mach)			break;		unlock(&runq);		spllo();	}	if(p->rnext == 0)		runq.tail = 0;	runq.head = p->rnext;	if(p->state != Ready)		print("runproc %d %s\n", p->pid, statename[p->state]);	unlock(&runq);	p->state = Scheding;	spllo();	return p;}User*newproc(void){	User *p;loop:	lock(&procalloc);	if(p = procalloc.free) {		/* assign = */		procalloc.free = p->qnext;		p->state = Zombie;		unlock(&procalloc);		p->mach = 0;		p->qnext = 0;		p->exiting = 0;		lock(&pidalloc);		p->pid = ++pidalloc.pid;		unlock(&pidalloc);		return p;	}	unlock(&procalloc);	panic("no procs");	goto loop;}voidprocinit(void){	User *p;	int i;	procalloc.free = ialloc(conf.nproc*sizeof(User), 0);	procalloc.arena = procalloc.free;	p = procalloc.free;	for(i=0; i<conf.nproc-1; i++,p++) {		p->qnext = p+1;		wakeup(&p->tsleep);	}	p->qnext = 0;	wakeup(&p->tsleep);	cmd_install("cpu", "[proc] -- process cpu time", cmd_cpu); /**/	cmd_install("trace", "[number] -- stack trace/qlocks", cmd_trace); /**/}voidsleep(Rendez *r, int (*f)(void*), void *arg){	User *p;	int s;	/*	 * spl is to allow lock to be called	 * at interrupt time. lock is mutual exclusion	 */	s = splhi();	lock(r);	/*	 * if condition happened, never mind	 */	if((*f)(arg)) {		unlock(r);		splx(s);		return;	}	/*	 * now we are committed to	 * change state and call scheduler	 */	p = r->p;	if(p)		print("double sleep %d\n", p->pid);	u->state = Wakeme;	r->p = u;	/*	 * sched does the unlock(u) when it is safe	 * it also allows to be called splhi.	 */	unlock(r);	sched();}inttfn(void *arg){	return MACHP(0)->ticks >= u->twhen || (*u->tfn)(arg);}voidtsleep(Rendez *r, int (*fn)(void*), void *arg, int ms){	Timet when;	User *f, **l;	when = MS2TK(ms)+MACHP(0)->ticks;	lock(&talarm);	/* take out of list if checkalarm didn't */	if (u == nil)		panic("tsleep: nil u");	if(u->trend) {		l = &talarm.list;		for(f = *l; f; f = f->tlink) {			if(f == u) {				*l = u->tlink;				break;			}			l = &f->tlink;		}	}	/* insert in increasing time order */	l = &talarm.list;	for(f = *l; f; f = f->tlink) {		if(f->twhen >= when)			break;		l = &f->tlink;	}	u->trend = r;	u->twhen = when;	u->tfn = fn;	u->tlink = *l;	*l = u;	unlock(&talarm);	sleep(r, tfn, arg);	u->twhen = 0;}voidwakeup(Rendez *r){	User *p;	int s;	s = splhi();	lock(r);	p = r->p;	if(p) {		r->p = 0;		if(p->state != Wakeme)			panic("wakeup: not Wakeme");		ready(p);	}	unlock(r);	splx(s);}voiddotrace(int n){	User *p;	QLock *q;	int i, j, f;	p = procalloc.arena;	for(i=0; i<conf.nproc; i++, p++) {		if(n) {			if(p->pid == n)				dumpstack(p);			continue;		}		if(q = p->has.want) {			if(q->name)				print("pid %d wants %.10s\n",					p->pid, q->name);			else				print("pid %d wants %p\n",					p->pid, q);		}		f = 0;		for(j=0; j<NHAS; j++) {			if(q = p->has.q[j]) {				if(f == 0) {					if(p->has.want == 0)						print("pid %d wants nothing\n", p->pid);					print("	has");					f = 1;				}				if(q->name)					print(" %.10s", q->name);				else					print(" %p", q);			}		}		if(f)			print("\n");	}}

⌨️ 快捷键说明

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