diff options
author | neal <neal> | 2008-01-04 15:48:04 +0000 |
---|---|---|
committer | neal <neal> | 2008-01-04 15:48:04 +0000 |
commit | 4ecdfe1b47c4b27b47c6b41bdcd0c8d2b17917e1 (patch) | |
tree | f22ab423a47680741f8e25eca2a28cdb111f0298 /viengoos/activity.c | |
parent | 60a852e0afb70f213f5d7cd9f08bd9e7de9d354b (diff) |
2008-01-04 Neal H. Walfield <neal@gnu.org>
* activity.h (struct activity): Add fields eviction_clean and
eviction_dirty. Improve comments.
(activity_charge): Change asserts to account for unsignedness.
* activity.c (activity_destroy): Move all objects owned by VICTIM
to its parent.
(activity_deprepare): Add additional asserts.
(do_activity_dump): Don't assert that ACTIVITY->FRAMES_LOCAL is
the sum of the items on ACTIVITY's LRU lists.
* object.h (struct object_desc): Add fields eviction_candidate,
live, laundry_node and available_node. Make priority_node a union
with activity_node, which replaces activity_lru. Remove field
global_lru.
(object_activity_lru): Rename this list class...
(activity_lru): ... to this. Update users.
(object_global_lru): Don't generate this list class.
(eviction): Generate new list class.
(available): Likewise.
(laundry): Likewise.
(global_active): Remove declaration.
(global_inactive_dirty): Likewise.
(global_inactive_clean): Likewise.
(disowned): Likewise.
(laundry): New declaration.
(available): Likewise.
(memory_object_destroy): Likewise.
(object_desc_disown_simple): Remove declaration.
(object_disown_simple): Remove function.
(object_desc_disown): Likewise.
(object_disown): Likewise.
(object_desc_claim): Take additional parameter update_accounting.
Update users.
(object_claim): Likewise.
(object_desc_unmap): New function.
(object_age): Likewise.
(objects_folio_offset): Likewise.
(objects_folio): Likewise.
(object_free): Implement in terms of the above two functions.
* object.c (global_active): Remove variable.
(global_inactive_dirty): Likewise.
(global_inactive_clean): Likewise.
(disowned): Likewise.
(laundry): New variable.
(available): Likewise.
(memory_object_alloc): Initialize ODESC to 0. Call
object_desc_claim to attach it to the relevant lists. Assert that
ODESC->LIVE is 0. Set ODESC->LIVE to 1.
(memory_object_destroy): Remove static qualifier. Require that
LRU_LOCK be held on entry. Update users. Use object_desc_claim
to disconnect DESC from any lists to which it is attached. Don't
call memory_frame_free, that is now the caller's responsibility.
Update users. Set DESC->LIVE to 0.
(folio_free): Don't disown the folio header.
(folio_object_alloc): Call memory_frame_free to really free the
memory.
(object_desc_disown_simple): Remove function.
(object_desc_disown_): Likewise.
(object_desc_claim): Take additional parameter update_accounting.
If true, update the relevant activities' accounting information.
Update connect and disconnect code. Only add an object to one of
the priority tree and the lru lists, but not both.
* viengoos.c (system_task_load): After allocating the
root activity, have the root activity claim it and FOLIO.
* ager.c: Include "zalloc.h".
(AGE_DELTA): Don't define.
(ager_loop): Rewrite to walk the object descriptors sequentially
rather than following a linked list. Update object list
connection and disconnection code.
* pager.h: New file.
* pager.c: Likewise.
* Makefile.am (viengoos_SOURCES): Add pager.h and pager.c.
* memory.h (struct activity): Add forward.
(memory_frame_allocate): Take additional parameter activity.
Return a uintptr_t instead of an l4_word_t. Update users.
* memory.c: Include "pager.h" and "activity.h".
(memory_grab): Always get base page sized pages.
(memory_frame_allocate): Take additional parameter activity.
Return a uintptr_t instead of an l4_word_t. If zalloc fails,
check AVAILABLE_LIST. If nothing is applicable, call
pager_collect and try again.
* t-environment.h (pager_collect): New function.
Diffstat (limited to 'viengoos/activity.c')
-rw-r--r-- | viengoos/activity.c | 167 |
1 files changed, 123 insertions, 44 deletions
diff --git a/viengoos/activity.c b/viengoos/activity.c index f02b128..2838a92 100644 --- a/viengoos/activity.c +++ b/viengoos/activity.c @@ -114,47 +114,123 @@ activity_destroy (struct activity *activity, struct activity *victim) object_free (activity, o); } - /* Disown all allocated memory objects. */ - ss_mutex_lock (&lru_lock); - struct object_desc *desc; - int count = 0; - while ((desc = object_activity_lru_list_head (&victim->active))) - { - object_desc_disown_simple (desc); - count ++; - } - while ((desc = object_activity_lru_list_head (&victim->inactive_clean))) - { - object_desc_disown_simple (desc); - count ++; - } - while ((desc = object_activity_lru_list_head (&victim->inactive_dirty))) - { - object_desc_disown_simple (desc); - count ++; - } - ss_mutex_unlock (&lru_lock); + /* VICTIM->PARENT inherits all of VICTIM's objects. */ + { + ss_mutex_lock (&lru_lock); + + struct object_desc *desc; + int count = 0; + + /* Make ACTIVE objects inactive. */ + while ((desc = activity_lru_list_head (&victim->active))) + { + assert (! desc->eviction_candidate); + assert (desc->activity == victim); + + activity_lru_list_unlink (&victim->active, desc); + + if (desc->dirty && ! desc->policy.discardable) + activity_lru_list_queue (&victim->parent->inactive_dirty, desc); + else + activity_lru_list_queue (&victim->parent->inactive_clean, desc); + + desc->activity = victim->parent; + count ++; + } + + struct object_desc *next = hurd_btree_priorities_first (&victim->priorities); + while ((desc = next)) + { + assert (! desc->eviction_candidate); + assert (desc->activity == victim); - activity_charge (victim, -count); + next = hurd_btree_priorities_next (desc); - do_debug (1) - if (victim->frames_total != 0) + if (desc->dirty && ! desc->policy.discardable) + activity_lru_list_queue (&victim->parent->inactive_dirty, desc); + else + activity_lru_list_queue (&victim->parent->inactive_clean, desc); + + desc->activity = victim->parent; + count ++; + } +#ifndef NDEBUG + hurd_btree_priorities_tree_init (&victim->priorities); +#endif + + /* Move inactive objects to the head of VICTIM->PARENT's appropriate + inactive list (thereby making them the first eviction + candidates). */ + for (desc = activity_lru_list_head (&victim->inactive_clean); + desc; desc = activity_lru_list_next (desc)) { - debug (0, "activity (%llx)->frames_total = %d", - object_to_object_desc ((struct object *) victim)->oid, - victim->frames_total); - activity_dump (root_activity); - - struct object_desc *desc; - ss_mutex_lock (&lru_lock); - for (desc = object_activity_lru_list_head (&victim->active); - desc; desc = object_activity_lru_list_next (desc)) - debug (0, " %llx: %s", desc->oid, cap_type_string (desc->type)); - ss_mutex_unlock (&lru_lock); + assert (! desc->eviction_candidate); + assert (desc->activity == victim); + assert (! desc->dirty || desc->policy.discardable); + assert (! list_node_attached (&desc->laundry_node)); + + desc->activity = victim->parent; + count ++; } - assert (victim->frames_total == 0); - assert (victim->frames_local == 0); - assert (victim->folio_count == 0); + activity_lru_list_join (&victim->parent->inactive_clean, + &victim->inactive_clean); + + for (desc = activity_lru_list_head (&victim->inactive_dirty); + desc; desc = activity_lru_list_next (desc)) + { + assert (! desc->eviction_candidate); + assert (desc->activity == victim); + assert (desc->dirty && ! desc->policy.discardable); + + desc->activity = victim->parent; + count ++; + } + activity_lru_list_join (&victim->parent->inactive_dirty, + &victim->inactive_dirty); + + + /* And move all of VICTIM's eviction candidates to VICTIM->PARENT's + eviction lists. */ + while ((desc = eviction_list_head (&victim->eviction_clean))) + { + assert (desc->eviction_candidate); + assert (desc->activity == victim); + assert (! list_node_attached (&desc->laundry_node)); + assert (! desc->dirty || desc->policy.discardable); + + desc->activity = victim->parent; + } + eviction_list_join (&victim->parent->eviction_clean, + &victim->eviction_clean); + + while ((desc = eviction_list_head (&victim->eviction_dirty))) + { + assert (desc->eviction_candidate); + assert (desc->activity == victim); + assert (list_node_attached (&desc->laundry_node)); + assert (desc->dirty && !desc->policy.discardable); + + desc->activity = victim->parent; + } + eviction_list_join (&victim->parent->eviction_dirty, + &victim->eviction_dirty); + + ss_mutex_unlock (&lru_lock); + + /* Adjust the counting information. */ + do_debug (1) + if (victim->frames_total != count || victim->frames_local != count) + { + debug (0, "activity (%llx), total = %d, local: %d, count: %d", + object_to_object_desc ((struct object *) victim)->oid, + victim->frames_total, victim->frames_local, count); + activity_dump (root_activity); + } + assert (count == victim->frames_local); + assert (count == victim->frames_total); + victim->frames_local = victim->frames_total = 0; + victim->parent->frames_local += count; + } activity_deprepare (activity, victim); @@ -216,9 +292,14 @@ activity_prepare (struct activity *principal, struct activity *activity) void activity_deprepare (struct activity *principal, struct activity *victim) { - /* If we have any in-memory children, then we can't be paged - out. */ + /* If we have any in-memory children or frames, then we can't be + paged out. */ assert (! victim->children); + assert (! activity_lru_list_count (&victim->active)); + assert (! activity_lru_list_count (&victim->inactive_clean)); + assert (! activity_lru_list_count (&victim->inactive_dirty)); + assert (! eviction_list_count (&victim->eviction_clean)); + assert (! eviction_list_count (&victim->eviction_dirty)); /* Unlink from parent's children list. */ assert (victim->parent); @@ -242,9 +323,9 @@ do_activity_dump (struct activity *activity, int indent) memset (indent_string, ' ', indent); indent_string[indent] = 0; - int active = object_activity_lru_list_count (&activity->active); - int dirty = object_activity_lru_list_count (&activity->inactive_dirty); - int clean = object_activity_lru_list_count (&activity->inactive_clean); + int active = activity_lru_list_count (&activity->active); + int dirty = activity_lru_list_count (&activity->inactive_dirty); + int clean = activity_lru_list_count (&activity->inactive_clean); printf ("%s %llx: %d frames (active: %d, dirty: %d, clean: %d) " "(total frames: %d)\n", @@ -253,8 +334,6 @@ do_activity_dump (struct activity *activity, int indent) activity->frames_local, active, dirty, clean, activity->frames_total); - assert (active + dirty + clean == activity->frames_local); - struct activity *child; activity_for_each_child (activity, child, ({ do_activity_dump (child, indent + 1); })); |