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

📄 misc.c

📁 这是个trace drive的Cache模拟器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Invalidate cache contents.  The operation affects the whole cache * or just 1 block, depending on m: * if m == NULL or m->size == 0, it affects the whole cache. * If prop is true, the same invalidate operation will be propagated * to other caches towards memory. * This function can be invoked directly by the subroutine-calling user, * or indirectly by passing a D4XINVAL access type to d4ref * (in which case d4ref passes prop == 1). * * NOTE: this does not copy back dirty stuff! *	you have to call d4copyback first for that. */voidd4invalidate (d4cache *c, const d4memref *m, int prop){	int stacknum;	d4stacknode *ptr;	d4pendstack *newm;	if (m != NULL)		assert (m->accesstype == D4XINVAL);	if (prop) {		newm = d4get_mref();		if (m != NULL)			newm->m = *m;		else {			newm->m.accesstype = D4XINVAL;			newm->m.address = 0;			newm->m.size = 0;	/* affect the whole cache */		}		newm->next = c->pending;		c->pending = newm;	}	if (m != NULL && m->size > 0) {		/* invalidate just one block */		d4addr blockaddr = D4ADDR2BLOCK (c, m->address);		stacknum = D4ADDR2SET (c, m->address);		ptr = d4_find (c, stacknum, blockaddr);		if (ptr != NULL)			d4_invblock (c, stacknum, ptr);		if ((c->flags & D4F_CCC) != 0 &&	/* fully assoc cache */		    (ptr = d4_find (c, c->numsets, blockaddr)) != NULL)			d4_invblock (c, c->numsets, ptr);	}	else for (stacknum=0;  stacknum < c->numsets + ((c->flags & D4F_CCC) != 0);  stacknum++) {		d4stacknode *top = c->stack[stacknum].top;		assert (top->up->valid == 0); /* all invalid nodes are at bottom; at least 1 */		for (ptr = top;  ptr->down != top;  ptr = ptr->down) {			if (ptr->valid == 0)				break;			d4_invblock (c, stacknum, ptr);		}	}	if ((c->flags & D4F_CCC) != 0)		d4_invinfcache (c, m);	if ((newm = c->pending) != NULL)		d4_dopending (c, newm);}/* * Handle invalidation for infinite cache */voidd4_invinfcache (d4cache *c, const d4memref *m){	int i;	if (m == NULL || m->size == 0) {	/* invalidate whole cache */		for (i = 0;  i < c->nranges;  i++) {			assert (c->ranges[i].bitmap != NULL);			free (c->ranges[i].bitmap);			c->ranges[i].bitmap = NULL;		}		c->nranges = 0;		c->maxranges = 0;	}	else {					/* invalidate just one block */		const unsigned int sbsize = 1 << D4VAL (c, lg2subblocksize);		const unsigned int baddr = D4ADDR2BLOCK (c, m->address);		unsigned int bitoff;	/* offset of bit in bitmap */		int hi, lo, nsb;		bitoff = (baddr & (D4_BITMAP_RSIZE-1)) / sbsize;		/* binary search for range containing our address */		hi = c->nranges-1;		lo = 0;		while (lo <= hi) {			i = lo + (hi-lo)/2;			if (c->ranges[i].addr + D4_BITMAP_RSIZE <= baddr)				lo = i + 1;		/* need to look higher */			else if (c->ranges[i].addr > baddr)				hi = i - 1;		/* need to look lower */			else {				/* found the right range */				for (nsb = c->lg2blocksize - c->lg2subblocksize;				     nsb-- > 0;				     bitoff++)					c->ranges[i].bitmap[bitoff/CHAR_BIT] &=					      ~(1<<(bitoff%CHAR_BIT));				break;			}		}	}}/* * Create custom code for d4ref and some routines it calls. * For each cache, we output macro definitions to establish constant * alternatives for key fields within d4cache, rename customizable * functions, and output an #include "ref.c". * The expectation is that the user will compile this output file * and link it with the simulator. */voidd4customize (FILE *f){	d4cache *c;	int i, n;	fprintf (f, "#if !D4CUSTOM\n"		    "#error \"D4CUSTOM not set\"\n"		    "#endif\n"		    "#include \"ref.c\"\n\n");	/* get one-time stuff */	/*	 * define d4_custom[] and d4_ncustom,	 * which can be used to find the proper customized d4ref function	 * when the customized program is started up.	 */	if (d4_allcaches == NULL) {		fprintf (stderr, "Dinero IV: d4customize called before d4new\n");		exit (9);	}	n = d4_allcaches->cacheid;	for (i = 1;  i <= n;  i++)		fprintf (f, "extern void d4_%dref (d4cache *, d4memref);\n", i);	fprintf (f, "void (*d4_custom[])(d4cache *, d4memref) = {\n\t");	for (i = 1;  i <= n;  i++)		fprintf (f, "d4_%dref%s", i, (i<n) ? ", " : "");	fprintf (f, "\n};\n");	fprintf (f, "int d4_ncustom = %d;\n", n);	/*	 * Now Generate the customized stuff for each cache.	 * Only the policy functions provided with Dinero IV are	 * customized; user-supplied policy functions are unaltered.	 * If you add new policy functions to ref.c, you need to	 * add code here too!	 */	for (c = d4_allcaches;  c != NULL;  c = c->link) {		int cid = c->cacheid;		fprintf (f, "\n");		/* Define helper used by D4VAL macro */		fprintf (f, "#undef D4_CACHEID\n"			    "#define D4_CACHEID %d\n", cid);		/*		 * Define a cache-specific macro		 * for the value of each field to be constantized,		 * and a "trigger" macro to allow its use in D4VAL.		 * In a few cases, we may #undef the trigger later		 * if we find we can't use it.		 */		fprintf (f, "#define D4_CACHE_%d_flags 0x%x\n"			    "#define D4_TRIGGER_%d_flags 1\n",			    cid, c->flags, cid);		fprintf (f, "#define D4_CACHE_%d_lg2blocksize %d\n"			    "#define D4_TRIGGER_%d_lg2blocksize 1\n",			    cid, c->lg2blocksize, cid);		fprintf (f, "#define D4_CACHE_%d_lg2subblocksize %d\n"			    "#define D4_TRIGGER_%d_lg2subblocksize 1\n",			    cid, c->lg2subblocksize, cid);		fprintf (f, "#define D4_CACHE_%d_lg2size %d\n"			    "#define D4_TRIGGER_%d_lg2size 1\n",			    cid, c->lg2size, cid);		fprintf (f, "#define D4_CACHE_%d_assoc %d\n"			    "#define D4_TRIGGER_%d_assoc 1\n",			    cid, c->assoc, cid);		fprintf (f, "#define D4_CACHE_%d_numsets %d\n"			    "#define D4_TRIGGER_%d_numsets 1\n",			    cid, c->numsets, cid);		fprintf (f, "#define D4_CACHE_%d_prefetch_abortpercent %d\n"			    "#define D4_TRIGGER_%d_prefetch_abortpercent 1\n",			    cid, c->prefetch_abortpercent, cid);		fprintf (f, "#define D4_CACHE_%d_replacementf d4_%dreplacement\n"			    "#define D4_TRIGGER_%d_replacementf 1\n",			    cid, cid, cid);		fprintf (f, "#define D4_CACHE_%d_prefetchf d4_%dprefetch\n"			    "#define D4_TRIGGER_%d_prefetchf 1\n",			    cid, cid, cid);		fprintf (f, "#define D4_CACHE_%d_wallocf d4_%dwalloc\n"			    "#define D4_TRIGGER_%d_wallocf 1\n",			    cid, cid, cid);		fprintf (f, "#define D4_CACHE_%d_wbackf d4_%dwback\n"			    "#define D4_TRIGGER_%d_wbackf 1\n",			    cid, cid, cid);		/* define macro to activate CCC computations */		fprintf (f, "#define D4_OPTS_%d_ccc %d\n", cid, (c->flags & D4F_CCC) != 0);		/*		 * For each policy function we recognize,		 * define a macro to activate it and		 * define the cache-specific policy name for it.		 * For policy functions we don't recognize,		 * turn off the trigger macro, so the call will		 * be treated in a non-customized manner, using the pointer		 * in the d4cache structure.		 */		if (c->replacementf == d4rep_lru)			fprintf (f, "#define D4_OPTS_%d_rep_lru 1\n"				    "#define D4_POLICY_%d_rep 'l'\n"				    "#undef d4rep_lru\n"				    "#define d4rep_lru d4_%dreplacement\n",				    cid, cid, cid);		else if (c->replacementf == d4rep_fifo)			fprintf (f, "#define D4_OPTS_%d_rep_fifo 1\n"				    "#define D4_POLICY_%d_rep 'f'\n"				    "#undef d4rep_fifo\n"				    "#define d4rep_fifo d4_%dreplacement\n",				    cid, cid, cid);		else if (c->replacementf == d4rep_random)			fprintf (f, "#define D4_OPTS_%d_rep_random 1\n"				    "#define D4_POLICY_%d_rep 'r'\n"				    "#undef d4rep_random\n"				    "#define d4rep_random d4_%dreplacement\n",				    cid, cid, cid);		else			fprintf (f, "#undef D4_TRIGGER_%d_replacementf\n"				    "#define D4_TRIGGER_%d_replacementf 0\n"				    "#define D4_POLICY_%d_rep 0\n"				    "#define d4_%dreplacement D4_CACHE_bogus_replacementf\n",				    cid, cid, cid, cid);		if (c->prefetchf != d4prefetch_none)			fprintf (f, "#define D4_OPTS_%d_prefetch_none 0\n", cid);		if (c->prefetchf == d4prefetch_none)			fprintf (f, "#define D4_OPTS_%d_prefetch_none 1\n"				    "#define D4_POLICY_%d_pref 'n'\n"				    "#undef d4prefetch_none\n"				    "#define d4prefetch_none d4_%dprefetch\n",				    cid, cid, cid);		else if (c->prefetchf == d4prefetch_always)			fprintf (f, "#define D4_OPTS_%d_prefetch_always 1\n"				    "#define D4_POLICY_%d_pref 'a'\n"				    "#undef d4prefetch_always\n"				    "#define d4prefetch_always d4_%dprefetch\n",				    cid, cid, cid);		else if (c->prefetchf == d4prefetch_loadforw)			fprintf (f, "#define D4_OPTS_%d_prefetch_loadforw 1\n"				    "#define D4_POLICY_%d_pref 'l'\n"				    "#undef d4prefetch_loadforw\n"				    "#define d4prefetch_loadforw d4_%dprefetch\n",				    cid, cid, cid);		else if (c->prefetchf == d4prefetch_subblock)			fprintf (f, "#define D4_OPTS_%d_prefetch_subblock 1\n"				    "#define D4_POLICY_%d_pref 's'\n"				    "#undef d4prefetch_subblock\n"				    "#define d4prefetch_subblock d4_%dprefetch\n",				    cid, cid, cid);		else if (c->prefetchf == d4prefetch_miss)			fprintf (f, "#define D4_OPTS_%d_prefetch_miss 1\n"				    "#define D4_POLICY_%d_pref 'm'\n"				    "#undef d4prefetch_miss\n"				    "#define d4prefetch_miss d4_%dprefetch\n",				    cid, cid, cid);		else if (c->prefetchf == d4prefetch_tagged)			fprintf (f, "#define D4_OPTS_%d_prefetch_tagged 1\n"				    "#define D4_POLICY_%d_pref 't'\n"				    "#undef d4prefetch_tagged\n"				    "#define d4prefetch_tagged d4_%dprefetch\n",				    cid, cid, cid);		else			fprintf (f, "#undef D4_TRIGGER_%d_prefetchf\n"				    "#define D4_TRIGGER_%d_prefetchf 0\n"				    "#define D4_POLICY_%d_pref 0\n"				    "#define d4_%dprefetch D4_CACHE_bogus_prefetchf\n",				    cid, cid, cid, cid);		if (c->wallocf == d4walloc_always)			fprintf (f, "#define D4_OPTS_%d_walloc_always 1\n"				    "#define D4_POLICY_%d_walloc 'a'\n"				    "#undef d4walloc_always\n"				    "#define d4walloc_always d4_%dwalloc\n",				    cid, cid, cid);		else if (c->wallocf == d4walloc_never)			fprintf (f, "#define D4_OPTS_%d_walloc_never 1\n"				    "#define D4_POLICY_%d_walloc 'n'\n"				    "#undef d4walloc_never\n"				    "#define d4walloc_never d4_%dwalloc\n",				    cid, cid, cid);		else if (c->wallocf == d4walloc_nofetch)			fprintf (f, "#define D4_OPTS_%d_walloc_nofetch 1\n"				    "#define D4_POLICY_%d_walloc 'f'\n"				    "#undef d4walloc_nofetch\n"				    "#define d4walloc_nofetch d4_%dwalloc\n",				    cid, cid, cid);		else			fprintf (f, "#undef D4_TRIGGER_%d_wallocf\n"				    "#define D4_TRIGGER_%d_wallocf 0\n"				    "#define D4_POLICY_%d_walloc 0\n"				    "#define d4_%dwalloc D4_CACHE_bogus_wallocf\n",				    cid, cid, cid, cid);		if (c->wbackf == d4wback_always)			fprintf (f, "#define D4_OPTS_%d_wback_always 1\n"				    "#define D4_POLICY_%d_wback 'a'\n"				    "#undef d4wback_always\n"				    "#define d4wback_always d4_%dwback\n",				    cid, cid, cid);		else if (c->wbackf == d4wback_never)			fprintf (f, "#define D4_OPTS_%d_wback_never 1\n"				    "#define D4_POLICY_%d_wback 'n'\n"				    "#undef d4wback_never\n"				    "#define d4wback_never d4_%dwback\n",				    cid, cid, cid);		else if (c->wbackf == d4wback_nofetch)			fprintf (f, "#define D4_OPTS_%d_wback_nofetch 1\n"				    "#define D4_POLICY_%d_wback 'f'\n"				    "#undef d4wback_nofetch\n"				    "#define d4wback_nofetch d4_%dwback\n",				    cid, cid, cid);		else			fprintf (f, "#undef D4_TRIGGER_%d_wbackf\n"				    "#define D4_TRIGGER_%d_wbackf 0\n"				    "#define D4_POLICY_%d_wback 0\n"				    "#define d4_%dwback D4_CACHE_bogus_wbackf\n",				    cid, cid, cid, cid);		/*		 * Other customized functions require special renaming		 */		fprintf (f, "#undef d4infcache\n");		if ((c->flags & D4F_CCC) != 0)			fprintf (f, "#define d4infcache d4_%dinfcache\n", cid);		else			fprintf (f, "#define d4infcache(c,m) 0\n");		fprintf (f, "#undef d4_splitm\n");		fprintf (f, "#define d4_splitm d4_%dsplitm\n", cid);		/*		 * Record the various customized values		 * for checking in d4setup.  The order here is significant,		 * and must match the order in which things are checked		 * in d4setup.		 */		fprintf (f, "long d4_cust_%d_vals[] = {\n", cid);		fprintf (f, "	D4_CACHE_%d_flags,\n", cid);		fprintf (f, "	D4_CACHE_%d_lg2blocksize,\n", cid);		fprintf (f, "	D4_CACHE_%d_lg2subblocksize,\n", cid);		fprintf (f, "	D4_CACHE_%d_lg2size,\n", cid);		fprintf (f, "	D4_CACHE_%d_assoc,\n", cid);		fprintf (f, "	D4_CACHE_%d_prefetch_abortpercent,\n", cid);		fprintf (f, "	D4_POLICY_%d_rep,\n", cid);		fprintf (f, "	D4_POLICY_%d_pref,\n", cid);		fprintf (f, "	D4_POLICY_%d_walloc,\n", cid);		fprintf (f, "	D4_POLICY_%d_wback\n", cid);		fprintf (f, "};\n");		/*		 * Now define the cache-specific name for d4ref		 * and include the real code		 */		fprintf (f, "#undef d4ref\n");		fprintf (f, "#define d4ref d4_%dref\n", cid);		fprintf (f, "#include \"ref.c\"\n");	}	/*	 * Now tie all the customized values up for checking in d4setup	 */	n = d4_allcaches->cacheid;	fprintf (f, "\nlong *d4_cust_vals[%d+1] = {\n\tNULL,\n", n);	for (i = 1;  i <= n;  i++)		fprintf (f, "	&d4_cust_%d_vals[0]%s\n", i, (i<n) ? "," : "");	fprintf (f, "};\n");}

⌨️ 快捷键说明

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