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

📄 icache.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include "stdinc.h"#include "dat.h"#include "fns.h"typedef struct ICache		ICache;struct ICache{	VtLock	*lock;			/* locks hash table & all associated data */	IEntry	**heads;		/* heads of all the hash chains */	int	bits;			/* bits to use for indexing heads */	u32int	size;			/* number of heads; == 1 << bits, should be < entries */	IEntry	*base;			/* all allocated hash table entries */	u32int	entries;		/* elements in base */	u32int	unused;			/* index of first unused element in base */	u32int	stolen;			/* last head from which an element was stolen */};static ICache icache;static IEntry	*icacheAlloc(IAddr *ia, u8int *score);/* * bits is the number of bits in the icache hash table * depth is the average depth * memory usage is about (1<<bits) * depth * sizeof(IEntry) + (1<<bits) * sizeof(IEntry*) */voidinitICache(int bits, int depth){	icache.lock = vtLockAlloc();	icache.bits = bits;	icache.size = 1 << bits;	icache.entries = depth * icache.size;	icache.base = MKNZ(IEntry, icache.entries);	icache.heads = MKNZ(IEntry*, icache.size);}u32inthashBits(u8int *sc, int bits){	u32int v;	v = (sc[0] << 24) | (sc[1] << 16) | (sc[2] << 8) | sc[3];	if(bits < 32)		 v >>= (32 - bits);	return v;}/*ZZZ need to think about evicting the correct IEntry,and writing back the wtime. * look up data score in the index cache * if this fails, pull it in from the disk index table, if it exists. * * must be called with the lump for this score locked */intlookupScore(u8int *score, int type, IAddr *ia, int *rac){	IEntry d, *ie, *last;	u32int h;	vtLock(stats.lock);	stats.icLookups++;	vtUnlock(stats.lock);	vtLock(icache.lock);	h = hashBits(score, icache.bits);	last = nil;	for(ie = icache.heads[h]; ie != nil; ie = ie->next){		if(ie->ia.type == type && scoreEq(ie->score, score)){			if(last != nil)				last->next = ie->next;			else				icache.heads[h] = ie->next;			vtLock(stats.lock);			stats.icHits++;			vtUnlock(stats.lock);			ie->rac = 1;			goto found;		}		last = ie;	}	vtUnlock(icache.lock);	if(!loadIEntry(mainIndex, score, type, &d))		return 0;	/*	 * no one else can load an entry for this score,	 * since we have the overall score lock.	 */	vtLock(stats.lock);	stats.icFills++;	vtUnlock(stats.lock);	vtLock(icache.lock);	ie = icacheAlloc(&d.ia, score);found:	ie->next = icache.heads[h];	icache.heads[h] = ie;	*ia = ie->ia;	*rac = ie->rac;	vtUnlock(icache.lock);	return 1;}/* * insert a new element in the hash table. */intinsertScore(u8int *score, IAddr *ia, int write){	IEntry *ie, se;	u32int h;	vtLock(stats.lock);	stats.icInserts++;	vtUnlock(stats.lock);	vtLock(icache.lock);	h = hashBits(score, icache.bits);	ie = icacheAlloc(ia, score);	ie->next = icache.heads[h];	icache.heads[h] = ie;	se = *ie;	vtUnlock(icache.lock);	if(!write)		return 1;	return storeIEntry(mainIndex, &se);}/* * allocate a index cache entry which hasn't been used in a while. * must be called with icache.lock locked * if the score is already in the table, update the entry. */static IEntry *icacheAlloc(IAddr *ia, u8int *score){	IEntry *ie, *last, *next;	u32int h;	h = hashBits(score, icache.bits);	last = nil;	for(ie = icache.heads[h]; ie != nil; ie = ie->next){		if(ie->ia.type == ia->type && scoreEq(ie->score, score)){			if(last != nil)				last->next = ie->next;			else				icache.heads[h] = ie->next;			ie->rac = 1;			return ie;		}		last = ie;	}	h = icache.unused;	if(h < icache.entries){		ie = &icache.base[h++];		icache.unused = h;		goto Found;	}	h = icache.stolen;	for(;;){		h++;		if(h >= icache.size)			h = 0;		ie = icache.heads[h];		if(ie != nil){			last = nil;			for(; next = ie->next; ie = next)				last = ie;			if(last != nil)				last->next = nil;			else				icache.heads[h] = nil;			icache.stolen = h;			goto Found;		}	}Found:	ie->ia = *ia;	scoreCp(ie->score, score);	ie->rac = 0;	return ie;}

⌨️ 快捷键说明

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