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

📄 main.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include	"all.h"#include	"mem.h"#include	"io.h"#include	"ureg.h"#include	"9p1.h"Rendez dawnrend;voidmachinit(void){	int n;	n = m->machno;	memset(m, 0, sizeof(Mach));	m->machno = n;	m->mmask = 1<<m->machno;	m->lights = 0;	active.exiting = 0;	active.machs = 1;}staticvoidconfinit(void){	conf.nmach = 1;	conf.nproc = 40;	conf.mem = meminit();	conf.sparemem = conf.mem/12;		/* 8% spare for chk etc */	conf.nalarm = 200;	conf.nuid = 1000;	conf.nserve = 15;	conf.nfile = 30000;	conf.nlgmsg = 100;	conf.nsmmsg = 500;	/*	 * if you have trouble with IDE DMA or RWM (multi-sector transfers),	 * perhaps due to old hardware, set idedma to zero in localconfinit().	 */	conf.idedma = 1;	localconfinit();	conf.nwpath = conf.nfile*8;	conf.nauth = conf.nfile/10;	conf.gidspace = conf.nuid*3;	cons.flags = 0;}/* * compute BUFSIZE*(NDBLOCK+INDPERBUF+INDPERBUF⁲+INDPERBUF⁳+INDPERBUF⁴) * while watching for overflow; in that case, return 0. */static uvlongadduvlongov(uvlong a, uvlong b){	uvlong r = a + b;	return (r < a || r < b)? 0: r;}static uvlongmuluvlongov(uvlong a, uvlong b){	uvlong r = a * b;	return (r < a || r < b)? 0: r;}static uvlongmaxsize(void){	int i;	uvlong max = NDBLOCK, ind = 1;	for (i = 0; i < NIBLOCK; i++) {		ind = muluvlongov(ind, INDPERBUF);	/* power of INDPERBUF */		if (ind == 0)			return 0;		max = adduvlongov(max, ind);		if (max == 0)			return 0;	}	return muluvlongov(max, BUFSIZE);}enum {	INDPERBUF⁲ = ((Off)INDPERBUF *INDPERBUF),	INDPERBUF⁴ = ((Off)INDPERBUF⁲*INDPERBUF⁲),};static voidprintsizes(void){	uvlong max = maxsize();	print("\tblock size = %d; ", RBUFSIZE);	if (max == 0)		print("max file size exceeds 2⁶⁴ bytes\n");	else {		uvlong offlim = 1ULL << (sizeof(Off)*8 - 1);		if (max >= offlim)			max = offlim - 1;		print("max file size = %,llud\n", (Wideoff)max);	}	print("\tINDPERBUF = %d, INDPERBUF^4 = %,lld, ", INDPERBUF,		(Wideoff)INDPERBUF⁴);	print("CEPERBK = %d\n", CEPERBK);	print("\tsizeofs: Dentry = %d, Cache = %d\n",		sizeof(Dentry), sizeof(Cache));}voidmain(void){	int i;	echo = 1;	predawn = 1;		formatinit();		machinit();		vecinit();		confinit();		lockinit();		printinit();		procinit();		clockinit();		print("\nPlan 9 %d-bit file server with %d-deep indir blks%s\n",			sizeof(Off)*8 - 1, NIBLOCK,			(conf.idedma? " and IDE DMA+RWM": ""));		printsizes();		alarminit();		mainlock.wr.name = "mainr";		mainlock.rd.name = "mainw";		reflock.name = "ref";		qlock(&reflock);		qunlock(&reflock);		serveq = newqueue(1000);		raheadq = newqueue(1000);		mbinit();		sntpinit();		otherinit();		files = ialloc(conf.nfile * sizeof(*files), 0);		for(i=0; i<conf.nfile; i++) {			qlock(&files[i]);			files[i].name = "file";			qunlock(&files[i]);		}		wpaths = ialloc(conf.nwpath * sizeof(*wpaths), 0);		uid = ialloc(conf.nuid * sizeof(*uid), 0);		gidspace = ialloc(conf.gidspace * sizeof(*gidspace), 0);		authinit();		print("iobufinit\n");		iobufinit();		arginit();		userinit(touser, 0, "ini");	predawn = 0;		wakeup(&dawnrend);		launchinit();		schedinit();}/* * read ahead processes. * read message from q and then * read the device. */intrbcmp(void *va, void *vb){	Rabuf *ra, *rb;	ra = *(Rabuf**)va;	rb = *(Rabuf**)vb;	if(rb == 0)		return 1;	if(ra == 0)		return -1;	if(ra->dev > rb->dev)		return 1;	if(ra->dev < rb->dev)		return -1;	if(ra->addr > rb->addr)		return 1;	if(ra->addr < rb->addr)		return -1;	return 0;}voidrahead(void){	Rabuf *rb[50];	Iobuf *p;	int i, n;	for (;;) {		rb[0] = recv(raheadq, 0);		for(n=1; n<nelem(rb); n++) {			if(raheadq->count <= 0)				break;			rb[n] = recv(raheadq, 0);		}		qsort(rb, n, sizeof(rb[0]), rbcmp);		for(i=0; i<n; i++) {			if(rb[i] == 0)				continue;			p = getbuf(rb[i]->dev, rb[i]->addr, Bread);			if(p)				putbuf(p);			lock(&rabuflock);			rb[i]->link = rabuffree;			rabuffree = rb[i];			unlock(&rabuflock);		}	}}/* * main filesystem server loop. * entered by many processes. * they wait for message buffers and * then process them. */voidserve(void){	int i;	Chan *cp;	Msgbuf *mb;	for (;;) {		qlock(&reflock);		mb = recv(serveq, 0);		cp = mb->chan;		rlock(&cp->reflock);		qunlock(&reflock);		rlock(&mainlock);		if(cp->protocol == nil){			/* do we recognise the protocol in this packet? */			for(i = 0; fsprotocol[i] != nil; i++)				if(fsprotocol[i](mb) != 0) {					cp->protocol = fsprotocol[i];					break;				}			if(cp->protocol == nil){				print("no protocol for message\n");				for(i = 0; i < 12; i++)					print(" %2.2uX", mb->data[i]);				print("\n");			}		}		else			cp->protocol(mb);		mbfree(mb);		runlock(&mainlock);		runlock(&cp->reflock);	}}voidinit0(void){	m->proc = u;	u->state = Running;	u->mach = m;	spllo();	(*u->start)();}void*getarg(void){	return u->arg;}enum {	Keydelay = 5*60,	/* seconds to wait for key press */};voidexit(void){	long timeleft;	u = 0;	lock(&active);	active.machs &= ~(1<<m->machno);	active.exiting = 1;	unlock(&active);	if(!predawn)		spllo();	print("cpu %d exiting\n", m->machno);	while(active.machs)		delay(1);	print("halted at %T.\n", time());	print("press the Enter key to reboot sooner than %d mins.\n",		Keydelay/60);	delay(500);		/* time to drain print q */	splhi();	/* reboot after delay (for debugging) or at newline */	for (timeleft = Keydelay; timeleft > 0; timeleft--)		if (rawchar(1) == '\n')			break;	spllo();	delay(500);		/* time to drain echo q */	print("rebooting...\n");	delay(500);		/* time to drain print q */	splhi();	consreset();	firmware();}/* * 1 sec timer * process+alarm+rendez+rwlock */static	Rendez	sec;staticvoidcallsec(Alarm *a, void *arg){	User *u = arg;	cancel(a);	wakeup(&u->tsleep);}voidwaitsec(int msec){	alarm(msec, callsec, u);	sleep(&u->tsleep, no, 0);}#define	DUMPTIME	5	/* 5 am */#define	WEEKMASK	0	/* every day (1=sun, 2=mon, 4=tue, etc.) *//* * calculate the next dump time. * minimum delay is 100 minutes. */Timetnextdump(Timet t){	Timet nddate = nextime(t+MINUTE(100), DUMPTIME, WEEKMASK);	if(!conf.nodump)		print("next dump at %T\n", nddate);	return nddate;}/* * process to copy dump blocks from * cache to worm. it runs flat out when * it gets work, but only looks for * work every 10 seconds. */voidwormcopy(void){	int f, dorecalc = 1;	Timet dt, t = 0, nddate = 0, ntoytime = 0;	Filsys *fs;	for (;;) {		if (dorecalc) {			dorecalc = 0;			t = time();			nddate = nextdump(t);		/* chatters */			ntoytime = time();		}		dt = time() - t;		if(dt < 0 || dt > MINUTE(100)) {			if(dt < 0)				print("time went back\n");			else				print("time jumped ahead\n");			dorecalc = 1;			continue;		}		t += dt;		f = 0;		if(t > ntoytime) {			dt = time() - rtctime();			if(dt < 0)				dt = -dt;			if(dt > 10)				print("rtc time more than 10 seconds out\n");			else if(dt > 1)				settime(rtctime());			ntoytime = time() + HOUR(1);		} else if(/* !f && */ t > nddate) { /* !f is always true here */			if(!conf.nodump) {				print("automatic dump %T\n", t);				for(fs=filsys; fs->name; fs++)					if(fs->dev->type == Devcw)						cfsdump(fs);			}			dorecalc = 1;		} else {			rlock(&mainlock);			for(fs=filsys; fs->name; fs++)				if(fs->dev->type == Devcw)					f |= dumpblock(fs->dev);			runlock(&mainlock);			if(0 && f == 0)				f = 0;		/* f = dowcp(); */			if(!f)				waitsec(10000);			wormprobe();		}	}}/* * process to synch blocks * it puts out a block/cache-line every second * it waits 10 seconds if caught up. * in both cases, it takes about 10 seconds * to get up-to-date. */voidsynccopy(void){	int f;	for (;;) {		rlock(&mainlock);		f = syncblock();		runlock(&mainlock);		if(!f)			waitsec(10000);		else			waitsec(1000);		/* pokewcp();	*/	}}

⌨️ 快捷键说明

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