1 /* $NetBSD: pdsim.c,v 1.1 2006/10/09 12:32:46 yamt Exp $ */
4 * Copyright (c)2006 YAMAMOTO Takashi,
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
32 #if defined(SHOWQLEN) || defined(SHOWIRR)
38 struct vm_page
*pages
;
56 TAILQ_HEAD(, vm_page
) freeq
;
59 pdsim_pagealloc(struct uvm_object
*obj
, int idx
)
63 pg
= TAILQ_FIRST(&freeq
);
67 TAILQ_REMOVE(&freeq
, pg
, pageq
);
68 pg
->offset
= idx
<< PAGE_SHIFT
;
80 pdsim_pagefree(struct vm_page
*pg
)
82 struct uvm_object
*obj
;
87 if (pg
->offset
!= -1) {
88 int idx
= pg
->offset
>> PAGE_SHIFT
;
89 printf("%d %d # FREE IRR\n", idx
, irr
[idx
]);
91 #endif /* defined(SHOWFREE) */
93 uvmpdpol_pagedequeue(pg
);
95 KASSERT(pg
->uanon
== NULL
);
100 idx
= pg
->offset
>> PAGE_SHIFT
;
101 KASSERT(obj
->pages
[idx
] == pg
);
102 obj
->pages
[idx
] = NULL
;
105 TAILQ_INSERT_HEAD(&freeq
, pg
, pageq
);
109 static struct vm_page
*
110 pdsim_pagelookup(struct uvm_object
*obj
, int index
)
114 pg
= obj
->pages
[index
];
120 pdsim_pagemarkreferenced(struct vm_page
*pg
)
123 pg
->_mdflags
|= MDPG_REFERENCED
;
127 pmap_is_referenced(struct vm_page
*pg
)
130 return pg
->_mdflags
& MDPG_REFERENCED
;
134 pmap_clear_reference(struct vm_page
*pg
)
136 boolean_t referenced
= pmap_is_referenced(pg
);
138 pg
->_mdflags
&= ~MDPG_REFERENCED
;
154 pages
= calloc(n
, sizeof(*pg
));
155 for (i
= 0; i
< n
; i
++) {
163 pdsim_reclaimone(void)
168 while (uvmexp
.free
< uvmexp
.freetarg
) {
171 pg
= uvmpdpol_selectvictim();
175 uvmpdpol_balancequeue(0);
180 fault(struct uvm_object
*obj
, int index
)
184 DPRINTF("fault: %d -> ", index
);
187 if (lastacc
[index
]) {
188 irr
[index
] = ts
- lastacc
[index
];
191 stats
[index
].fault
++;
192 pg
= pdsim_pagelookup(obj
, index
);
195 pdsim_pagemarkreferenced(pg
);
197 if ((pg
->_mdflags
& MDPG_SPECULATIVE
) != 0) {
198 pg
->_mdflags
&= ~MDPG_SPECULATIVE
;
205 pg
= pdsim_pagealloc(obj
, index
);
211 #if defined(SHOWFAULT)
212 printf("%d # FLT\n", index
);
214 pdsim_pagemarkreferenced(pg
);
215 uvmpdpol_pageactivate(pg
);
216 uvmpdpol_pageactivate(pg
);
218 #if defined(READAHEAD)
219 pg
= pdsim_pagelookup(obj
, index
+ 1);
222 pg
= pdsim_pagealloc(obj
, index
+ 1);
228 pg
->_mdflags
|= MDPG_SPECULATIVE
;
229 #if defined(SHOWFAULT)
230 printf("%d # READ-AHEAD\n", index
+ 1);
233 uvmpdpol_pageenqueue(pg
);
235 #endif /* defined(READAHEAD) */
238 struct uvm_object obj
;
243 memset(&obj
, 0, sizeof(obj
));
250 ln
= fparseln(stdin
, NULL
, NULL
, NULL
, 0);
264 #if defined(SHOWQLEN)
275 for (i
= 0; i
< MAXID
; i
++) {
276 if (stats
[i
].fault
== 0) {
279 DPRINTF("[%d] %d/%d %d\n", i
,
280 stats
[i
].hit
, stats
[i
].fault
, irr
[i
]);
283 #endif /* defined(DEBUG) */
286 main(int argc
, char *argv
[])
289 setvbuf(stderr
, NULL
, _IOFBF
, 0); /* XXX */
291 pdsim_init(atoi(argv
[1]));
293 DPRINTF("io %d (%d + ra %d) / flt %d\n",
294 npagein
+ raio
, npagein
, raio
, nfault
);
295 DPRINTF("rahit / raio= %d / %d\n", rahit
, raio
);