summaryrefslogtreecommitdiff
path: root/viengoos/activity.c
diff options
context:
space:
mode:
authorneal <neal>2008-01-04 15:48:04 +0000
committerneal <neal>2008-01-04 15:48:04 +0000
commit4ecdfe1b47c4b27b47c6b41bdcd0c8d2b17917e1 (patch)
treef22ab423a47680741f8e25eca2a28cdb111f0298 /viengoos/activity.c
parent60a852e0afb70f213f5d7cd9f08bd9e7de9d354b (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.c167
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); }));