diff options
author | neal <neal> | 2008-06-24 14:35:20 +0000 |
---|---|---|
committer | neal <neal> | 2008-06-24 14:35:20 +0000 |
commit | b66325df3e8b995b52f9a21e6750f20fd526db0a (patch) | |
tree | cc5c173bad5e91ce082c264508a8ace46a1a3ea8 /libhurd-mm/anonymous.c | |
parent | 7cc0d3ed39b6cb61d897d348b7f5bd88c8294282 (diff) |
hurd/
2008-06-24 Neal H. Walfield <neal@gnu.org>
* cap.h (RM_object_discard): New define.
(object_discard): New method.
viengoos/
2008-06-24 Neal H. Walfield <neal@gnu.org>
* server.c (server_loop): Implement cap_discard.
* rm.h (rm_method_id_string): Handle the RM_object_discard case.
libhurd-mm/
2008-06-24 Neal H. Walfield <neal@gnu.org>
* madvise.c: New file.
* Makefile.am (libhurd_mm_a_SOURCES): Add madvise.c.
* pager.h (pager_advice_normal, pager_advice_random,
pager_advice_sequential, pager_advice_willneed,
pager_advice_dontneed): Define.
(pager_advise_t): New typedef.
(struct pager): Add field advise.
* anonymous.c (advise): New function.
(anonymous_pager_alloc): Set ANON->PAGER.ADVISE to it.
Diffstat (limited to 'libhurd-mm/anonymous.c')
-rw-r--r-- | libhurd-mm/anonymous.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/libhurd-mm/anonymous.c b/libhurd-mm/anonymous.c index ae6ae41..fc45a3e 100644 --- a/libhurd-mm/anonymous.c +++ b/libhurd-mm/anonymous.c @@ -432,6 +432,49 @@ destroy (struct pager *pager) hurd_slab_dealloc (&anonymous_pager_slab, anon); } +static void +advise (struct pager *pager, + uintptr_t start, uintptr_t length, uintptr_t advice) +{ + if (advice != pager_advice_dontneed) + /* This is the only advice we currently handle. */ + return; + + struct anonymous_pager *anon = (struct anonymous_pager *) pager; + + uintptr_t offset[2]; + offset[0] = start | 1; + offset[1] = length; + + hurd_btree_storage_desc_t *storage_descs; + storage_descs = (hurd_btree_storage_desc_t *) &anon->storage; + + struct storage_desc *next + = hurd_btree_storage_desc_find (storage_descs, &offset[0]); + if (next) + { + struct storage_desc *prev = hurd_btree_storage_desc_prev (next); + + int dir; + struct storage_desc *storage_desc; + for (dir = 0; dir < 2; dir ++, next = prev) + while ((storage_desc = next)) + { + next = (dir == 0 ? hurd_btree_storage_desc_next (storage_desc) + : hurd_btree_storage_desc_prev (storage_desc)); + + if (storage_desc->offset < start + || storage_desc->offset >= start + length) + break; + + error_t err; + err = rm_object_discard (anon->activity, storage_desc->storage); + if (err) + panic ("err: %d", err); + } + } +} + struct anonymous_pager * anonymous_pager_alloc (addr_t activity, void *hint, uintptr_t length, enum map_access access, @@ -459,6 +502,7 @@ anonymous_pager_alloc (addr_t activity, anon->pager.length = length; anon->pager.fault = fault; anon->pager.no_refs = destroy; + anon->pager.advise = advise; anon->activity = activity; anon->flags = flags; |