xref: /netbsd-src/regress/sys/uvm/pdsim/lirs.c (revision cf17315fe8829cb035f07ea043c16b2c82c574ea)
1*cf17315fSyamt /*	$NetBSD: lirs.c,v 1.3 2006/10/09 12:43:32 yamt Exp $	*/
2dbdfc1f6Syamt 
3dbdfc1f6Syamt /*-
4dbdfc1f6Syamt  * Copyright (c)2005 YAMAMOTO Takashi,
5dbdfc1f6Syamt  * All rights reserved.
6dbdfc1f6Syamt  *
7dbdfc1f6Syamt  * Redistribution and use in source and binary forms, with or without
8dbdfc1f6Syamt  * modification, are permitted provided that the following conditions
9dbdfc1f6Syamt  * are met:
10dbdfc1f6Syamt  * 1. Redistributions of source code must retain the above copyright
11dbdfc1f6Syamt  *    notice, this list of conditions and the following disclaimer.
12dbdfc1f6Syamt  * 2. Redistributions in binary form must reproduce the above copyright
13dbdfc1f6Syamt  *    notice, this list of conditions and the following disclaimer in the
14dbdfc1f6Syamt  *    documentation and/or other materials provided with the distribution.
15dbdfc1f6Syamt  *
16dbdfc1f6Syamt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17dbdfc1f6Syamt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18dbdfc1f6Syamt  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19dbdfc1f6Syamt  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20dbdfc1f6Syamt  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21dbdfc1f6Syamt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22dbdfc1f6Syamt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23dbdfc1f6Syamt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24dbdfc1f6Syamt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25dbdfc1f6Syamt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26dbdfc1f6Syamt  * SUCH DAMAGE.
27dbdfc1f6Syamt  */
28dbdfc1f6Syamt 
29dbdfc1f6Syamt #include <sys/queue.h>
30dbdfc1f6Syamt 
31dbdfc1f6Syamt #include <assert.h>
32dbdfc1f6Syamt #include <stdio.h>
33dbdfc1f6Syamt #include <stdlib.h>
34dd099bf0Syamt #include <string.h>
35dbdfc1f6Syamt 
36dbdfc1f6Syamt #if defined(DEBUG)
37dbdfc1f6Syamt #define	DFPRINTF(...)	fprintf(__VA_ARGS__)
38dbdfc1f6Syamt #else
39dbdfc1f6Syamt #define	DFPRINTF(...)	/* nothing */
40dbdfc1f6Syamt #endif
41dbdfc1f6Syamt 
42dbdfc1f6Syamt #define	MAXID	102400
43dbdfc1f6Syamt 
44dbdfc1f6Syamt struct buf {
45dbdfc1f6Syamt 	TAILQ_ENTRY(buf) b_s;
46dbdfc1f6Syamt 	TAILQ_ENTRY(buf) b_q;
47dbdfc1f6Syamt 	int b_type;
48dbdfc1f6Syamt #define	B_L	1
49dbdfc1f6Syamt #define	B_H	2
50dbdfc1f6Syamt #define	B_R	4
51dbdfc1f6Syamt 	int b_flags;
52dbdfc1f6Syamt #define B_S	8
53dbdfc1f6Syamt 	int b_irr;
54dbdfc1f6Syamt 	int b_lastts;
55dbdfc1f6Syamt };
56dbdfc1f6Syamt 
57dbdfc1f6Syamt struct buf bufs[MAXID];
58dbdfc1f6Syamt 
59dbdfc1f6Syamt TAILQ_HEAD(, buf) q_q;
60dbdfc1f6Syamt TAILQ_HEAD(, buf) q_s;
61dbdfc1f6Syamt 
62dbdfc1f6Syamt int nlirs_max = 2;
63dbdfc1f6Syamt int nbufs_max = 3;
64dbdfc1f6Syamt int nlirs;
65dbdfc1f6Syamt int nbufs;
66dbdfc1f6Syamt 
67dbdfc1f6Syamt void buf_print(struct buf *, char *);
68dbdfc1f6Syamt 
69dbdfc1f6Syamt void
buf_print(struct buf * bp,char * s)70dbdfc1f6Syamt buf_print(struct buf *bp, char *s)
71dbdfc1f6Syamt {
72dbdfc1f6Syamt 
73dbdfc1f6Syamt 	DFPRINTF(stderr, "%d(%s,%s,%d)%s", (bp - bufs),
74dbdfc1f6Syamt 	    (bp->b_type == B_L) ? "L" :
75dbdfc1f6Syamt 	    (bp->b_type == (B_H | B_R)) ? "HR" :
76dbdfc1f6Syamt 	    (bp->b_type == B_H) ? "H" :
77dbdfc1f6Syamt 	    (bp->b_type == 0) ? "free" :
78dbdfc1f6Syamt 	    "unknown",
79dbdfc1f6Syamt 	    (bp->b_flags & B_S) ? "S" : "",
80dbdfc1f6Syamt 	    bp->b_irr,
81dbdfc1f6Syamt 	    s);
82dbdfc1f6Syamt }
83dbdfc1f6Syamt 
84dbdfc1f6Syamt void
dump()85dbdfc1f6Syamt dump()
86dbdfc1f6Syamt {
87dbdfc1f6Syamt #if defined(DEBUG)
88dbdfc1f6Syamt 	struct buf *bp;
89dbdfc1f6Syamt 	int i;
90dbdfc1f6Syamt 
91dbdfc1f6Syamt 	DFPRINTF(stderr, "S: ");
92dbdfc1f6Syamt 	TAILQ_FOREACH(bp, &q_s, b_s) {
93dbdfc1f6Syamt 		buf_print(bp, " ");
94dbdfc1f6Syamt 	}
95dbdfc1f6Syamt 	DFPRINTF(stderr, "\n");
96dbdfc1f6Syamt 
97dbdfc1f6Syamt 	DFPRINTF(stderr, "Q: ");
98dbdfc1f6Syamt 	TAILQ_FOREACH(bp, &q_q, b_q) {
99dbdfc1f6Syamt 		buf_print(bp, " ");
100dbdfc1f6Syamt 	}
101dbdfc1f6Syamt 	DFPRINTF(stderr, "\n");
102dbdfc1f6Syamt 
103dbdfc1f6Syamt #if 0
104dbdfc1f6Syamt 	for (i = 0; i < 256; i++) {
105dbdfc1f6Syamt 
106dbdfc1f6Syamt 		bp = &bufs[i];
107dbdfc1f6Syamt 		if (bufs->b_type == 0) {
108dbdfc1f6Syamt 			continue;
109dbdfc1f6Syamt 		}
110dbdfc1f6Syamt 	}
111dbdfc1f6Syamt #endif
112dbdfc1f6Syamt 
113dbdfc1f6Syamt 	DFPRINTF(stderr, "nlirs=%d, nbufs=%d\n", nlirs, nbufs);
114dbdfc1f6Syamt #endif /* defined(DEBUG) */
115dbdfc1f6Syamt }
116dbdfc1f6Syamt 
117dbdfc1f6Syamt void
reclaim()118dbdfc1f6Syamt reclaim()
119dbdfc1f6Syamt {
120dbdfc1f6Syamt 	struct buf *bp;
121dbdfc1f6Syamt 
122dbdfc1f6Syamt 	if (nbufs <= nbufs_max) {
123dbdfc1f6Syamt 		return;
124dbdfc1f6Syamt 	}
125dbdfc1f6Syamt 
126dbdfc1f6Syamt 	bp = TAILQ_FIRST(&q_q);
127dbdfc1f6Syamt 	buf_print(bp, ": reclaim\n");
128*cf17315fSyamt 	assert(bp->b_type == (B_H | B_R));
129dbdfc1f6Syamt 	TAILQ_REMOVE(&q_q, bp, b_q);
130dbdfc1f6Syamt 	bp->b_type &= ~B_R;
131dbdfc1f6Syamt 	nbufs--;
132dbdfc1f6Syamt }
133dbdfc1f6Syamt 
134dbdfc1f6Syamt void
prune()135dbdfc1f6Syamt prune()
136dbdfc1f6Syamt {
137dbdfc1f6Syamt 
138dbdfc1f6Syamt 	while (1) {
139dbdfc1f6Syamt 		struct buf *bp;
140dbdfc1f6Syamt 
141dbdfc1f6Syamt 		bp = TAILQ_FIRST(&q_s);
142dbdfc1f6Syamt 		if (bp->b_type == B_L) {
143dbdfc1f6Syamt 			break;
144dbdfc1f6Syamt 		}
145dbdfc1f6Syamt 		buf_print(bp, ": prune\n");
146dbdfc1f6Syamt 		TAILQ_REMOVE(&q_s, bp, b_s);
147dbdfc1f6Syamt 		assert(bp->b_flags & B_S);
148dbdfc1f6Syamt 		bp->b_flags &= ~B_S;
149dbdfc1f6Syamt 		if ((bp->b_type & B_R) == 0) {
150dbdfc1f6Syamt 			bp->b_type &= ~B_H;
151dbdfc1f6Syamt 		}
152dbdfc1f6Syamt 	}
153dbdfc1f6Syamt }
154dbdfc1f6Syamt 
155dbdfc1f6Syamt void
reclaim_l()156dbdfc1f6Syamt reclaim_l()
157dbdfc1f6Syamt {
158dbdfc1f6Syamt 	struct buf *bp;
159dbdfc1f6Syamt 
160dbdfc1f6Syamt 	if (nlirs <= nlirs_max) {
161dbdfc1f6Syamt 		return;
162dbdfc1f6Syamt 	}
163dbdfc1f6Syamt 
164dbdfc1f6Syamt 	bp = TAILQ_FIRST(&q_s);
165dbdfc1f6Syamt 	buf_print(bp, ": reclaim_l\n");
166dbdfc1f6Syamt 	assert(bp->b_type == B_L);
167dbdfc1f6Syamt 	assert(bp->b_flags & B_S);
168dbdfc1f6Syamt 	bp->b_type = B_H | B_R;
169dbdfc1f6Syamt 	bp->b_flags &= ~B_S;
170dbdfc1f6Syamt 	TAILQ_REMOVE(&q_s, bp, b_s);
171dbdfc1f6Syamt 	TAILQ_INSERT_TAIL(&q_q, bp, b_q);
172dbdfc1f6Syamt 	nlirs--;
173dbdfc1f6Syamt 	prune();
174dbdfc1f6Syamt }
175dbdfc1f6Syamt 
176dbdfc1f6Syamt void
init(int n)177dbdfc1f6Syamt init(int n)
178dbdfc1f6Syamt {
179dbdfc1f6Syamt 
180dbdfc1f6Syamt 	TAILQ_INIT(&q_q);
181dbdfc1f6Syamt 	TAILQ_INIT(&q_s);
182dbdfc1f6Syamt 	memset(&bufs, 0, sizeof(bufs));
183dbdfc1f6Syamt 	nbufs_max = n;
184dbdfc1f6Syamt #if 0
185dbdfc1f6Syamt 	nlirs_max = nbufs_max * 2 / 3;
186dbdfc1f6Syamt #else
187dbdfc1f6Syamt 	nlirs_max = nbufs_max * 90 / 100;
188dbdfc1f6Syamt #endif
189dbdfc1f6Syamt }
190dbdfc1f6Syamt 
191dbdfc1f6Syamt struct object {int dummy;};
192dbdfc1f6Syamt int ts = 1;
193dbdfc1f6Syamt 
194dbdfc1f6Syamt void
fault(struct object * dummy,int i)195dbdfc1f6Syamt fault(struct object *dummy, int i)
196dbdfc1f6Syamt {
197dbdfc1f6Syamt 	struct buf *bp;
198dbdfc1f6Syamt 
199dbdfc1f6Syamt 	DFPRINTF(stderr, "----------\n");
200dbdfc1f6Syamt 	dump();
201dbdfc1f6Syamt 
202dbdfc1f6Syamt 	DFPRINTF(stderr, "---------- ts %d\n", ts);
203dbdfc1f6Syamt 
204dbdfc1f6Syamt 	bp = &bufs[i];
205dbdfc1f6Syamt 	buf_print(bp, ": access\n");
206dbdfc1f6Syamt 	if (bp->b_type == 0) {
207dbdfc1f6Syamt 		bp->b_irr = -1;
208dbdfc1f6Syamt 	} else {
209dbdfc1f6Syamt 		bp->b_irr = ts - bp->b_lastts - 1;
210dbdfc1f6Syamt 	}
211dbdfc1f6Syamt 	bp->b_lastts = ts;
212dbdfc1f6Syamt 
213dbdfc1f6Syamt 	if (bp->b_type == B_L) {
214dbdfc1f6Syamt 		assert(bp->b_flags & B_S);
215dbdfc1f6Syamt 		TAILQ_REMOVE(&q_s, bp, b_s);
216dbdfc1f6Syamt 		TAILQ_INSERT_TAIL(&q_s, bp, b_s);
217dbdfc1f6Syamt 		prune();
218dbdfc1f6Syamt 		goto done;
219dbdfc1f6Syamt 	}
220dbdfc1f6Syamt 	if (bp->b_type == (B_H | B_R)) {
221dbdfc1f6Syamt 		if (bp->b_flags & B_S) {
222dbdfc1f6Syamt 			TAILQ_REMOVE(&q_s, bp, b_s);
223dbdfc1f6Syamt 			TAILQ_REMOVE(&q_q, bp, b_q);
224dbdfc1f6Syamt 			bp->b_type = B_L;
225dbdfc1f6Syamt 			nlirs++;
226dbdfc1f6Syamt 			reclaim_l();
227dbdfc1f6Syamt 		} else {
228dbdfc1f6Syamt 			TAILQ_REMOVE(&q_q, bp, b_q);
229dbdfc1f6Syamt 			TAILQ_INSERT_TAIL(&q_q, bp, b_q);
230dbdfc1f6Syamt 		}
231dbdfc1f6Syamt 		TAILQ_INSERT_TAIL(&q_s, bp, b_s);
232dbdfc1f6Syamt 		bp->b_flags |= B_S;
233dbdfc1f6Syamt 		goto done;
234dbdfc1f6Syamt 	}
235dbdfc1f6Syamt 	nbufs++;
236dbdfc1f6Syamt 	reclaim();
237dbdfc1f6Syamt 	if ((bp->b_flags & (B_R | B_L)) == 0) {
238dbdfc1f6Syamt 		printf("%d\n", i);
239dbdfc1f6Syamt 	}
240dbdfc1f6Syamt 	if (bp->b_type == 0) {
241dbdfc1f6Syamt 		buf_print(bp, ": new\n");
242dbdfc1f6Syamt 		if (nlirs < nlirs_max) {
243dbdfc1f6Syamt 			bp->b_type = B_L;
244dbdfc1f6Syamt 			TAILQ_INSERT_TAIL(&q_s, bp, b_s);
245dbdfc1f6Syamt 			bp->b_flags |= B_S;
246dbdfc1f6Syamt 			nlirs++;
247dbdfc1f6Syamt 		} else {
248dbdfc1f6Syamt 			bp->b_type = B_H;
249dbdfc1f6Syamt 		}
250dbdfc1f6Syamt 	}
251dbdfc1f6Syamt 	if (bp->b_type == B_H) {
252dbdfc1f6Syamt 		if (bp->b_flags & B_S) {
253dbdfc1f6Syamt 			TAILQ_REMOVE(&q_s, bp, b_s);
254dbdfc1f6Syamt 			bp->b_type = B_L;
255dbdfc1f6Syamt 			nlirs++;
256dbdfc1f6Syamt 			reclaim_l();
257dbdfc1f6Syamt 		} else {
258dbdfc1f6Syamt 			bp->b_type |= B_R;
259dbdfc1f6Syamt 			TAILQ_INSERT_TAIL(&q_q, bp, b_q);
260dbdfc1f6Syamt 		}
261dbdfc1f6Syamt 		TAILQ_INSERT_TAIL(&q_s, bp, b_s);
262dbdfc1f6Syamt 		bp->b_flags |= B_S;
263dbdfc1f6Syamt 	}
264dbdfc1f6Syamt done:
265dbdfc1f6Syamt 	ts++;
266dbdfc1f6Syamt }
267dbdfc1f6Syamt 
268dbdfc1f6Syamt void
test(void)269dbdfc1f6Syamt test(void)
270dbdfc1f6Syamt {
271dbdfc1f6Syamt 	struct object obj;
272dbdfc1f6Syamt 	memset(&obj, 0, sizeof(obj));
273dbdfc1f6Syamt 	char *ln;
274dbdfc1f6Syamt 
275dbdfc1f6Syamt 	for (;; free(ln)) {
276dbdfc1f6Syamt 		int i;
277dbdfc1f6Syamt 		int ch;
278dbdfc1f6Syamt 
279dbdfc1f6Syamt 		ln = fparseln(stdin, NULL, NULL, NULL, 0);
280dbdfc1f6Syamt 		if (ln == NULL) {
281dbdfc1f6Syamt 			break;
282dbdfc1f6Syamt 		}
283dbdfc1f6Syamt 		ch = *ln;
284dbdfc1f6Syamt 		if (ch == '\0') {
285dbdfc1f6Syamt 			break;
286dbdfc1f6Syamt 		}
287dbdfc1f6Syamt #if 1
288dbdfc1f6Syamt 		if (ch == 'd') {
289dbdfc1f6Syamt 			dump();
290dbdfc1f6Syamt 			continue;
291dbdfc1f6Syamt 		}
292dbdfc1f6Syamt #endif
293dbdfc1f6Syamt 		i = atoi(ln);
294dbdfc1f6Syamt 		fault(&obj, i);
295dbdfc1f6Syamt 	}
296dbdfc1f6Syamt }
297dbdfc1f6Syamt 
298dbdfc1f6Syamt int
main(int argc,char * argv[])299dbdfc1f6Syamt main(int argc, char *argv[])
300dbdfc1f6Syamt {
301dbdfc1f6Syamt 
302dbdfc1f6Syamt 	init(atoi(argv[1]));
303dbdfc1f6Syamt 	test();
304dbdfc1f6Syamt 	exit(0);
305dbdfc1f6Syamt }
306