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

📄 iotrack.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include "iotrack.h"#include "dat.h"#include "fns.h"#define	HIOB		31	/* a prime */#define	NIOBUF		80static Iotrack	hiob[HIOB+1];		/* hash buckets + lru list */static Iotrack	iobuf[NIOBUF];		/* the real ones */#define	UNLINK(p, nx, pr)	((p)->pr->nx = (p)->nx, (p)->nx->pr = (p)->pr)#define	LINK(h, p, nx, pr)	((p)->nx = (h)->nx, (p)->pr = (h), \				 (h)->nx->pr = (p), (h)->nx = (p))#define	HTOFRONT(h, p)	((h)->hnext != (p) && (UNLINK(p,hnext,hprev), LINK(h,p,hnext,hprev)))#define	TOFRONT(h, p)	((h)->next  != (p) && (UNLINK(p, next, prev), LINK(h,p, next, prev)))Iosect *getsect(Xfs *xf, long addr){	return getiosect(xf, addr, 1);}Iosect *getosect(Xfs *xf, long addr){	return getiosect(xf, addr, 0);}Iosect *getiosect(Xfs *xf, long addr, int rflag){	Iotrack *t;	long taddr;	int toff;	Iosect *p;	toff = addr % Sect2trk;	taddr = addr - toff;	t = getiotrack(xf, taddr);	if(rflag && (t->flags&BSTALE)){		if(tread(t) < 0){			unmlock(&t->lock);			return 0;		}		t->flags &= ~BSTALE;	}	t->ref++;	p = t->tp->p[toff];	if(p == 0){		p = newsect();		t->tp->p[toff] = p;		p->flags = t->flags&BSTALE;		p->lock.key = 0;		p->t = t;		p->iobuf = t->tp->buf[toff];	}	unmlock(&t->lock);	mlock(&p->lock);	return p;}voidputsect(Iosect *p){	Iotrack *t;	if(canmlock(&p->lock))		panic("putsect");	t = p->t;	mlock(&t->lock);	t->flags |= p->flags;	p->flags = 0;	t->ref--;	if(t->flags & BIMM){		if(t->flags & BMOD)			twrite(t);		t->flags &= ~(BMOD|BIMM);	}	unmlock(&t->lock);	unmlock(&p->lock);}Iotrack *getiotrack(Xfs *xf, long addr){	Iotrack *hp, *p;	Iotrack *mp = &hiob[HIOB];	long h;/* *	chat("iotrack %d,%d...", dev, addr); */	h = (xf->dev<<24) ^ addr;	if(h < 0)		h = ~h;	h %= HIOB;	hp = &hiob[h];loop:/* * look for it in the active list */	mlock(&hp->lock);	for(p=hp->hnext; p != hp; p=p->hnext){		if(p->addr != addr || p->xf != xf)			continue;		unmlock(&hp->lock);		mlock(&p->lock);		if(p->addr == addr && p->xf == xf)			goto out;		unmlock(&p->lock);		goto loop;	}	unmlock(&hp->lock);/* * not found * take oldest unref'd entry */	mlock(&mp->lock);	for(p=mp->prev; p != mp; p=p->prev)		if(p->ref == 0 && canmlock(&p->lock)){			if(p->ref == 0)				break;			unmlock(&p->lock);		}	unmlock(&mp->lock);	if(p == mp){		print("iotrack all ref'd\n");		goto loop;	}	if(p->flags & BMOD){		twrite(p);		p->flags &= ~(BMOD|BIMM);		unmlock(&p->lock);		goto loop;	}	purgetrack(p);	p->addr = addr;	p->xf = xf;	p->flags = BSTALE;out:	mlock(&hp->lock);	HTOFRONT(hp, p);	unmlock(&hp->lock);	mlock(&mp->lock);	TOFRONT(mp, p);	unmlock(&mp->lock);	return p;}voidpurgetrack(Iotrack *t){	int i, ref = Sect2trk;	Iosect *p;	for(i=0; i<Sect2trk; i++){		p = t->tp->p[i];		if(p == 0){			--ref;			continue;		}		if(canmlock(&p->lock)){			freesect(p);			--ref;			t->tp->p[i] = 0;		}	}	if(t->ref != ref)		panic("purgetrack");}inttwrite(Iotrack *t){	int i, ref;	chat("[twrite %ld...", t->addr);	if(t->flags & BSTALE){		for(ref=0,i=0; i<Sect2trk; i++)			if(t->tp->p[i])				++ref;		if(ref < Sect2trk){			if(tread(t) < 0){				chat("error]");				return -1;			}		}else			t->flags &= ~BSTALE;	}	if(devwrite(t->xf, t->addr, t->tp->buf, Trksize) < 0){		chat("error]");		return -1;	}	chat(" done]");	return 0;}inttread(Iotrack *t){	int i, ref = 0;	uchar buf[Sect2trk][Sectorsize];	for(i=0; i<Sect2trk; i++)		if(t->tp->p[i])			++ref;	chat("[tread %ld+%ld...", t->addr, t->xf->offset);	if(ref == 0){		if(devread(t->xf, t->addr, t->tp->buf, Trksize) < 0){			chat("error]");			return -1;		}		chat("done]");		t->flags &= ~BSTALE;		return 0;	}	if(devread(t->xf, t->addr, buf, Trksize) < 0){		chat("error]");		return -1;	}	for(i=0; i<Sect2trk; i++)		if(t->tp->p[i] == 0){			memmove(t->tp->buf[i], buf[i], Sectorsize);			chat("%d ", i);		}	chat("done]");	t->flags &= ~BSTALE;	return 0;}voidpurgebuf(Xfs *xf){	Iotrack *p;	for(p=&iobuf[0]; p<&iobuf[NIOBUF]; p++){		if(p->xf != xf)			continue;		mlock(&p->lock);		if(p->xf == xf){			if(p->flags & BMOD)				twrite(p);			p->flags = BSTALE;			purgetrack(p);		}		unmlock(&p->lock);	}}voidsync(void){	Iotrack *p;	for(p=&iobuf[0]; p<&iobuf[NIOBUF]; p++){		if(!(p->flags & BMOD))			continue;		mlock(&p->lock);		if(p->flags & BMOD){			twrite(p);			p->flags &= ~(BMOD|BIMM);		}		unmlock(&p->lock);	}}voidiotrack_init(void){	Iotrack *mp, *p;	for (mp=&hiob[0]; mp<&hiob[HIOB]; mp++)		mp->hprev = mp->hnext = mp;	mp->prev = mp->next = mp;	for (p=&iobuf[0]; p<&iobuf[NIOBUF]; p++) {		p->hprev = p->hnext = p;		p->prev = p->next = p;		TOFRONT(mp, p);		p->tp = sbrk(sizeof(Track));		memset(p->tp->p, 0, sizeof p->tp->p);	}}static MLock	freelock;static Iosect *	freelist;Iosect *newsect(void){	Iosect *p;	mlock(&freelock);	if(p = freelist)	/* assign = */		freelist = p->next;	else		p = malloc(sizeof(Iosect));	unmlock(&freelock);	p->next = 0;	return p;}voidfreesect(Iosect *p){	mlock(&freelock);	p->next = freelist;	freelist = p;	unmlock(&freelock);}

⌨️ 快捷键说明

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