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