summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@gnu.org>2008-11-04 16:25:13 +0100
committerNeal H. Walfield <neal@gnu.org>2008-11-04 16:25:13 +0100
commit908dbd86b3c431456df7a7d1f6b69f6e2830e0af (patch)
tree1aa0b65e8f9a8b6b98fdc281cd4c30a4e9ddd904
parentb3c92f167f20f1267c6b4ec83f1b6b6edd2ba85a (diff)
In the activity structure, use a pair of lists per priority level.
2008-11-04 Neal H. Walfield <neal@gnu.org> * activity.h (struct activity): Replace fields active, inactive, priorities and priorities_count with fields frames_ and frames. Update users. * object.h (activity_lru): Rename from this... (activity): ... to this. Update users. * activity.c (activity_destroy): When moving frames claimed by a child to its parent's lowest priority level, update each frame's respective priority. (activity_prepare) [! NDEBUG]: Initialize priority levels.
-rw-r--r--viengoos/ChangeLog12
-rw-r--r--viengoos/activity.c157
-rw-r--r--viengoos/activity.h40
-rw-r--r--viengoos/ager.c32
-rw-r--r--viengoos/object.c209
-rw-r--r--viengoos/object.h6
-rw-r--r--viengoos/pager.c196
7 files changed, 305 insertions, 347 deletions
diff --git a/viengoos/ChangeLog b/viengoos/ChangeLog
index 47185bc..5604614 100644
--- a/viengoos/ChangeLog
+++ b/viengoos/ChangeLog
@@ -1,3 +1,15 @@
+2008-11-04 Neal H. Walfield <neal@gnu.org>
+
+ * activity.h (struct activity): Replace fields active, inactive,
+ priorities and priorities_count with fields frames_ and frames.
+ Update users.
+ * object.h (activity_lru): Rename from this...
+ (activity): ... to this. Update users.
+ * activity.c (activity_destroy): When moving frames claimed by a
+ child to its parent's lowest priority level, update each frame's
+ respective priority.
+ (activity_prepare) [! NDEBUG]: Initialize priority levels.
+
2008-11-03 Neal H. Walfield <neal@gnu.org>
* viengoos.c (main): Use s_printf, not debug, to print the
diff --git a/viengoos/activity.c b/viengoos/activity.c
index 2f1fe18..12a4320 100644
--- a/viengoos/activity.c
+++ b/viengoos/activity.c
@@ -140,68 +140,50 @@ activity_destroy (struct activity *activity, struct activity *victim)
int count = 0;
/* Make ACTIVE objects inactive. */
- for (desc = activity_lru_list_head (&victim->active);
- desc; desc = activity_lru_list_next (desc))
+ int i;
+ for (i = OBJECT_PRIORITY_MIN; i <= OBJECT_PRIORITY_MAX; i ++)
{
- assert (! desc->eviction_candidate);
- assert (desc->activity == victim);
- assert (! list_node_attached (&desc->laundry_node));
- assert (desc->age);
-
- desc->age = 0;
- desc->activity = victim->parent;
- count ++;
+ for (desc = activity_list_head (&victim->frames[i].active);
+ desc; desc = activity_list_next (desc))
+ {
+ assert (! desc->eviction_candidate);
+ assert (desc->activity == victim);
+ assert (! list_node_attached (&desc->laundry_node));
+ assert (desc->age);
+ assert (desc->policy.priority == i);
+
+ desc->age = 0;
+ desc->policy.priority = OBJECT_PRIORITY_MIN;
+ desc->activity = victim->parent;
+ count ++;
+ }
+ activity_list_join
+ (&victim->parent->frames[OBJECT_PRIORITY_MIN].inactive,
+ &victim->frames[i].active);
}
- activity_lru_list_join (&victim->parent->inactive,
- &victim->active);
-
- struct object_desc *next
- = hurd_btree_priorities_first (&victim->priorities);
- while ((desc = next))
- {
- assert (! desc->eviction_candidate);
- assert (desc->activity == victim);
- assert (desc->policy.priority != OBJECT_PRIORITY_LRU);
-
- next = hurd_btree_priorities_next (desc);
-
- desc->age = 0;
- desc->activity = victim->parent;
-
-#ifndef NDEBUG
- /* We don't detach it from the tree as we destroy the tree in
- its entirety. But, the insert code expects the fields to
- be zero'd. */
- memset (&desc->priority_node, 0, sizeof (desc->priority_node));
-#endif
-
- void *ret = hurd_btree_priorities_insert (&victim->parent->priorities,
- desc);
- assert (! ret);
- victim->parent->priorities_count ++;
-
- 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);
- desc; desc = activity_lru_list_next (desc))
+ for (i = OBJECT_PRIORITY_MIN; i <= OBJECT_PRIORITY_MAX; i ++)
{
- assert (! desc->eviction_candidate);
- assert (desc->activity == victim);
- assert (! list_node_attached (&desc->laundry_node));
- assert (! desc->age);
-
- desc->activity = victim->parent;
- count ++;
+ for (desc = activity_list_head (&victim->frames[i].inactive);
+ desc; desc = activity_list_next (desc))
+ {
+ assert (! desc->eviction_candidate);
+ assert (desc->activity == victim);
+ assert (! list_node_attached (&desc->laundry_node));
+ assert (! desc->age);
+ assert (desc->policy.priority == i);
+
+ desc->activity = victim->parent;
+ desc->policy.priority = OBJECT_PRIORITY_MIN;
+ count ++;
+ }
+ activity_list_join
+ (&victim->parent->frames[OBJECT_PRIORITY_MIN].inactive,
+ &victim->frames[i].inactive);
}
- activity_lru_list_join (&victim->parent->inactive,
- &victim->inactive);
/* And move all of VICTIM's eviction candidates to VICTIM->PARENT's
@@ -323,12 +305,54 @@ activity_prepare (struct activity *principal, struct activity *activity)
activity, last);
}
+#ifndef NDEBUG
activity_children_list_init (&activity->children, "activity->children");
- activity_lru_list_init (&activity->active, "active");
- activity_lru_list_init (&activity->inactive, "inactive");
+ static const char *names[OBJECT_PRIORITY_LEVELS]
+ = { "inactive-64", "inactive-63", "inactive-62", "inactive-61",
+ "inactive-60", "inactive-59", "inactive-58", "inactive-57",
+ "inactive-56", "inactive-55", "inactive-54", "inactive-53",
+ "inactive-52", "inactive-51", "inactive-50", "inactive-49",
+ "inactive-48", "inactive-47", "inactive-46", "inactive-45",
+ "inactive-44", "inactive-43", "inactive-42", "inactive-41",
+ "inactive-40", "inactive-39", "inactive-38", "inactive-37",
+ "inactive-36", "inactive-35", "inactive-34", "inactive-33",
+ "inactive-32", "inactive-31", "inactive-30", "inactive-29",
+ "inactive-28", "inactive-27", "inactive-26", "inactive-25",
+ "inactive-24", "inactive-23", "inactive-22", "inactive-21",
+ "inactive-20", "inactive-19", "inactive-18", "inactive-17",
+ "inactive-16", "inactive-15", "inactive-14", "inactive-13",
+ "inactive-12", "inactive-11", "inactive-10", "inactive-9",
+ "inactive-8", "inactive-7", "inactive-6", "inactive-5",
+ "inactive-4", "inactive-3", "inactive-2", "inactive-1",
+ "inactive0", "inactive1", "inactive2", "inactive3",
+ "inactive4", "inactive5", "inactive6", "inactive7",
+ "inactive8", "inactive9", "inactive10", "inactive11",
+ "inactive12", "inactive13", "inactive14", "inactive15",
+ "inactive16", "inactive17", "inactive18", "inactive19",
+ "inactive20", "inactive21", "inactive22", "inactive23",
+ "inactive24", "inactive25", "inactive26", "inactive27",
+ "inactive28", "inactive29", "inactive30", "inactive31",
+ "inactive32", "inactive33", "inactive34", "inactive35",
+ "inactive36", "inactive37", "inactive38", "inactive39",
+ "inactive40", "inactive41", "inactive42", "inactive43",
+ "inactive44", "inactive45", "inactive46", "inactive47",
+ "inactive48", "inactive49", "inactive50", "inactive51",
+ "inactive52", "inactive53", "inactive54", "inactive55",
+ "inactive56", "inactive57", "inactive58", "inactive59",
+ "inactive60", "inactive61", "inactive62", "inactive63" };
+
+ int i;
+ for (i = OBJECT_PRIORITY_MIN; i <= OBJECT_PRIORITY_MAX; i ++)
+ {
+ activity_list_init (&activity->frames[i].active,
+ &names[i - OBJECT_PRIORITY_MIN][2]);
+ activity_list_init (&activity->frames[i].inactive,
+ names[i - OBJECT_PRIORITY_MIN]);
+ }
eviction_list_init (&activity->eviction_clean, "evict clean");
eviction_list_init (&activity->eviction_dirty, "evict dirty");
+#endif
}
void
@@ -337,8 +361,12 @@ activity_deprepare (struct activity *principal, struct activity *victim)
/* If we have any in-memory children or frames, then we can't be
paged out. */
assert (! activity_children_list_head (&victim->children));
- assert (! activity_lru_list_count (&victim->active));
- assert (! activity_lru_list_count (&victim->inactive));
+ int i;
+ for (i = OBJECT_PRIORITY_MIN; i <= OBJECT_PRIORITY_MAX; i ++)
+ {
+ assert (! activity_list_count (&victim->frames[i].active));
+ assert (! activity_list_count (&victim->frames[i].inactive));
+ }
assert (! eviction_list_count (&victim->eviction_clean));
assert (! eviction_list_count (&victim->eviction_dirty));
@@ -408,8 +436,15 @@ do_activity_dump (struct activity *activity, int indent)
memset (indent_string, ' ', indent);
indent_string[indent] = 0;
- int active = activity_lru_list_count (&activity->active);
- int inactive = activity_lru_list_count (&activity->inactive);
+ int active = 0;
+ int inactive = 0;
+
+ int i;
+ for (i = OBJECT_PRIORITY_MIN; i <= OBJECT_PRIORITY_MAX; i ++)
+ {
+ active += activity_list_count (&activity->frames[i].active);
+ inactive += activity_list_count (&activity->frames[i].inactive);
+ }
int clean = eviction_list_count (&activity->eviction_clean);
int dirty = eviction_list_count (&activity->eviction_dirty);
@@ -442,7 +477,7 @@ activity_dump (struct activity *activity)
zalloc_memory + available_list_count (&available),
(100 * (zalloc_memory + available_list_count (&available))) /
memory_total,
- eviction_list_count (&laundry));
+ laundry_list_count (&laundry));
do_activity_dump (activity, 0);
}
}
diff --git a/viengoos/activity.h b/viengoos/activity.h
index 8ffcc94..983395a 100644
--- a/viengoos/activity.h
+++ b/viengoos/activity.h
@@ -70,17 +70,19 @@ struct activity
struct activity_children_list children;
struct list_node sibling;
- /* Objects claimed by this activity whose priority is
- OBJECT_PRIORITY_LRU and for which DESC->EVICTION_CANDIDATE is
- false. */
- struct activity_lru_list active;
- struct activity_lru_list inactive;
-
- /* Objects claimed by this activity whose priority is not
- OBJECT_PRIORITY_LRU and for which DESC->EVICTION_CANDIDATE is
- false. Keyed by priority. */
- hurd_btree_priorities_t priorities;
- int priorities_count;
+ /* Objects claimed by this activity for which
+ DESC->EVICTION_CANDIDATE is false. As priority is signed, to
+ avoid having to adjust the index, we play a small trick. */
+ struct
+ {
+ struct activity_list active;
+ struct activity_list inactive;
+ } frames_[-OBJECT_PRIORITY_MIN];
+ struct
+ {
+ struct activity_list active;
+ struct activity_list inactive;
+ } frames[OBJECT_PRIORITY_MAX + 1];
/* Objects that are owned by this activity and have been selected
for eviction (DESC->EVICTION_CANDIDATE is true). These objects
@@ -90,17 +92,15 @@ struct activity
struct eviction_list eviction_dirty;
/* Number of frames allocated to this activity not counting
- children. This includes all frames allocated on the PRIORITY
- tree and the ACTIVE, INACTIVE and EVICTION_DIRTY lists (but not
- the EVICTION_CLEAN list, as it is elements on it are immediately
- reclaimable). */
+ children. This includes all frames allocated on the ACTIVE,
+ INACTIVE and EVICTION_DIRTY lists (but not the EVICTION_CLEAN
+ list, as it is elements on it are immediately reclaimable). */
uint32_t frames_local;
/* Number of frames allocated to this activity (including children).
- This is the sum of the number of objects on the PRIORITY tree,
- and the ACTIVE, INACTIVE and EVICTION_DIRTY lists plus the number
- of frames allocated to each child. This does not include the
- number of frames on the eviction_clean and eviction_dirty
- lists. */
+ This is the sum of the number of objects on the ACTIVE, INACTIVE
+ and EVICTION_DIRTY lists plus the number of frames allocated to
+ each child. This does not include the number of frames on the
+ eviction_clean and eviction_dirty lists. */
uint32_t frames_total;
/* Dirty frames that are pending eviction. */
diff --git a/viengoos/ager.c b/viengoos/ager.c
index f413388..65cbf43 100644
--- a/viengoos/ager.c
+++ b/viengoos/ager.c
@@ -605,8 +605,7 @@ ager_loop (void)
object_age (desc, referenced);
- if (! object_active (desc)
- && desc->policy.priority == OBJECT_PRIORITY_LRU)
+ if (! object_active (desc))
/* The object has become inactive and needs to be
moved. */
{
@@ -614,11 +613,13 @@ ager_loop (void)
became_inactive ++;
- /* Detach from active list. */
- activity_lru_list_unlink (&desc->activity->active,
- desc);
-
- activity_lru_list_push (&desc->activity->inactive, desc);
+ /* Detach from active list and reattach to
+ inactive list. */
+ int priority = desc->policy.priority;
+ activity_list_unlink
+ (&desc->activity->frames[priority].active, desc);
+ activity_list_push
+ (&desc->activity->frames[priority].inactive, desc);
}
else
ACTIVITY_STATS (desc->activity)->active ++;
@@ -635,16 +636,13 @@ ager_loop (void)
became_active ++;
- if (desc->policy.priority == OBJECT_PRIORITY_LRU)
- {
- /* Detach from inactive list. */
- activity_lru_list_unlink
- (&desc->activity->inactive, desc);
-
- /* Attach to active list. */
- activity_lru_list_push (&desc->activity->active,
- desc);
- }
+ /* Detach from inactive list and reattach to the
+ active list. */
+ int priority = desc->policy.priority;
+ activity_list_unlink
+ (&desc->activity->frames[priority].inactive, desc);
+ activity_list_push
+ (&desc->activity->frames[priority].active, desc);
desc->dirty |= dirty;
}
diff --git a/viengoos/object.c b/viengoos/object.c
index b1433e3..52b2283 100644
--- a/viengoos/object.c
+++ b/viengoos/object.c
@@ -696,46 +696,60 @@ object_desc_claim (struct activity *activity, struct object_desc *desc,
struct object_policy o = desc->policy;
bool ec = desc->eviction_candidate;
+#ifndef NDEBUG
if (desc->activity && update_accounting)
- assertx (desc->activity->priorities_count
- + activity_lru_list_count (&desc->activity->active)
- + activity_lru_list_count (&desc->activity->inactive)
- + eviction_list_count (&desc->activity->eviction_dirty)
- == desc->activity->frames_local,
- "%d+%d+%d+%d = %d != %d! (%p=>%p,%d,%d,%d=>%d,%d=>%d)",
- desc->activity->priorities_count,
- activity_lru_list_count (&desc->activity->active),
- activity_lru_list_count (&desc->activity->inactive),
- eviction_list_count (&desc->activity->eviction_dirty),
- desc->activity->priorities_count
- + activity_lru_list_count (&desc->activity->active)
- + activity_lru_list_count (&desc->activity->inactive)
- + eviction_list_count (&desc->activity->eviction_dirty),
- desc->activity->frames_local,
- desc->activity, activity,
- desc->eviction_candidate, desc->dirty,
- o.discardable, policy.discardable,
- o.priority, policy.priority);
+ {
+ int active = 0;
+ int inactive = 0;
+
+ int i;
+ for (i = OBJECT_PRIORITY_MIN; i <= OBJECT_PRIORITY_MAX; i ++)
+ {
+ active += activity_list_count (&desc->activity->frames[i].active);
+ inactive += activity_list_count (&desc->activity->frames[i].inactive);
+ }
+
+ assertx (active + inactive
+ + eviction_list_count (&desc->activity->eviction_dirty)
+ == desc->activity->frames_local,
+ "%d+%d+%d = %d != %d! (%p=>%p,%d,%d,%d=>%d,%d=>%d)",
+ active, inactive,
+ eviction_list_count (&desc->activity->eviction_dirty),
+ active + inactive
+ + eviction_list_count (&desc->activity->eviction_dirty),
+ desc->activity->frames_local,
+ desc->activity, activity,
+ desc->eviction_candidate, desc->dirty,
+ o.discardable, policy.discardable,
+ o.priority, policy.priority);
+ }
if (activity)
- assertx (activity->priorities_count
- + activity_lru_list_count (&activity->active)
- + activity_lru_list_count (&activity->inactive)
- + eviction_list_count (&activity->eviction_dirty)
- == activity->frames_local,
- "%d+%d+%d+%d = %d != %d! (%p=>%p,%d,%d,%d=>%d,%d=>%d)",
- activity->priorities_count,
- activity_lru_list_count (&activity->active),
- activity_lru_list_count (&activity->inactive),
- eviction_list_count (&activity->eviction_dirty),
- activity->priorities_count
- + activity_lru_list_count (&activity->active)
- + activity_lru_list_count (&activity->inactive)
- + eviction_list_count (&activity->eviction_dirty),
- activity->frames_local,
- desc->activity, activity,
- desc->eviction_candidate, desc->dirty,
- o.discardable, policy.discardable,
- o.priority, policy.priority);
+ {
+ int active = 0;
+ int inactive = 0;
+
+ int i;
+ for (i = OBJECT_PRIORITY_MIN; i <= OBJECT_PRIORITY_MAX; i ++)
+ {
+ active += activity_list_count (&activity->frames[i].active);
+ inactive += activity_list_count (&activity->frames[i].inactive);
+ }
+
+ assertx (active + inactive
+ + eviction_list_count (&activity->eviction_dirty)
+ == activity->frames_local,
+ "%d+%d+%d = %d != %d! (%p=>%p,%d,%d,%d=>%d,%d=>%d)",
+ active, inactive,
+ eviction_list_count (&activity->eviction_dirty),
+ active + inactive
+ + eviction_list_count (&activity->eviction_dirty),
+ activity->frames_local,
+ desc->activity, activity,
+ desc->eviction_candidate, desc->dirty,
+ o.discardable, policy.discardable,
+ o.priority, policy.priority);
+ }
+#endif
if (desc->activity == activity
&& ! desc->eviction_candidate
@@ -796,24 +810,11 @@ object_desc_claim (struct activity *activity, struct object_desc *desc,
}
else
{
- if (desc->policy.priority != OBJECT_PRIORITY_LRU)
- {
- hurd_btree_priorities_detach (&desc->activity->priorities,
- desc);
- desc->activity->priorities_count --;
- }
- else
- {
- struct activity_lru_list *list;
- if (object_active (desc))
- /* DESC is active. */
- list = &desc->activity->active;
- else
- /* DESC is inactive. */
- list = &desc->activity->inactive;
-
- activity_lru_list_unlink (list, desc);
- }
+ activity_list_unlink
+ (object_active (desc)
+ ? &desc->activity->frames[desc->policy.priority].active
+ : &desc->activity->frames[desc->policy.priority].inactive,
+ desc);
if (activity != desc->activity && update_accounting)
activity_charge (desc->activity, -1);
@@ -855,15 +856,7 @@ object_desc_claim (struct activity *activity, struct object_desc *desc,
/* We make the object active. The invariants require that DESC->AGE
be non-zero. */
object_age (desc, true);
- if (desc->policy.priority != OBJECT_PRIORITY_LRU)
- {
- void *ret = hurd_btree_priorities_insert (&activity->priorities,
- desc);
- assert (! ret);
- activity->priorities_count ++;
- }
- else
- activity_lru_list_push (&activity->active, desc);
+ activity_list_push (&activity->frames[desc->policy.priority].active, desc);
if ((activity != desc->activity
|| (desc->eviction_candidate
@@ -912,44 +905,58 @@ object_desc_claim (struct activity *activity, struct object_desc *desc,
desc->policy.discardable ? "discardable" : "precious");
out:
+#ifndef NDEBUG
if (desc->activity && update_accounting)
- assertx (desc->activity->priorities_count
- + activity_lru_list_count (&desc->activity->active)
- + activity_lru_list_count (&desc->activity->inactive)
- + eviction_list_count (&desc->activity->eviction_dirty)
- == desc->activity->frames_local,
- "%d+%d+%d+%d = %d != %d (%p=>%p,%d,%d,%d=>%d,%d=>%d)",
- desc->activity->priorities_count,
- activity_lru_list_count (&desc->activity->active),
- activity_lru_list_count (&desc->activity->inactive),
- eviction_list_count (&desc->activity->eviction_dirty),
- desc->activity->priorities_count
- + activity_lru_list_count (&desc->activity->active)
- + activity_lru_list_count (&desc->activity->inactive)
- + eviction_list_count (&desc->activity->eviction_dirty),
- desc->activity->frames_local,
- desc->activity, activity, ec, desc->dirty,
- o.discardable, policy.discardable,
- o.priority, policy.priority);
+ {
+ int active = 0;
+ int inactive = 0;
+
+ int i;
+ for (i = OBJECT_PRIORITY_MIN; i <= OBJECT_PRIORITY_MAX; i ++)
+ {
+ active += activity_list_count (&desc->activity->frames[i].active);
+ inactive += activity_list_count (&desc->activity->frames[i].inactive);
+ }
+
+ assertx (active + inactive
+ + eviction_list_count (&desc->activity->eviction_dirty)
+ == desc->activity->frames_local,
+ "%d+%d+%d = %d != %d (%p=>%p,%d,%d,%d=>%d,%d=>%d)",
+ active, inactive,
+ eviction_list_count (&desc->activity->eviction_dirty),
+ active + inactive
+ + eviction_list_count (&desc->activity->eviction_dirty),
+ desc->activity->frames_local,
+ desc->activity, activity, ec, desc->dirty,
+ o.discardable, policy.discardable,
+ o.priority, policy.priority);
+ }
if (activity && update_accounting)
- assertx (activity->priorities_count
- + activity_lru_list_count (&activity->active)
- + activity_lru_list_count (&activity->inactive)
- + eviction_list_count (&activity->eviction_dirty)
- == activity->frames_local,
- "%d+%d+%d+%d = %d != %d! (%p=>%p,%d,%d,%d=>%d,%d=>%d)",
- activity->priorities_count,
- activity_lru_list_count (&activity->active),
- activity_lru_list_count (&activity->inactive),
- eviction_list_count (&activity->eviction_dirty),
- activity->priorities_count
- + activity_lru_list_count (&activity->active)
- + activity_lru_list_count (&activity->inactive)
- + eviction_list_count (&activity->eviction_dirty),
- activity->frames_local,
- desc->activity, activity, ec, desc->dirty,
- o.discardable, policy.discardable,
- o.priority, policy.priority);
+ {
+ int active = 0;
+ int inactive = 0;
+
+ int i;
+ for (i = OBJECT_PRIORITY_MIN; i <= OBJECT_PRIORITY_MAX; i ++)
+ {
+ active += activity_list_count (&activity->frames[i].active);
+ inactive += activity_list_count (&activity->frames[i].inactive);
+ }
+
+ assertx (active + inactive
+ + eviction_list_count (&activity->eviction_dirty)
+ == activity->frames_local,
+ "%d+%d+%d = %d != %d! (%p=>%p,%d,%d,%d=>%d,%d=>%d)",
+ active, inactive,
+ eviction_list_count (&activity->eviction_dirty),
+ active + inactive
+ + eviction_list_count (&activity->eviction_dirty),
+ activity->frames_local,
+ desc->activity, activity, ec, desc->dirty,
+ o.discardable, policy.discardable,
+ o.priority, policy.priority);
+ }
+#endif
}
/* Return the first waiter queued on object OBJECT. */
diff --git a/viengoos/object.h b/viengoos/object.h
index 76540c7..0b212ea 100644
--- a/viengoos/object.h
+++ b/viengoos/object.h
@@ -168,13 +168,13 @@ struct object_desc
union
{
/* ACTIVITY is valid, EVICTION_CANDIDATE is false, POLICY.PRIORITY
- != OBJECT_PRIORITY_LRU.
+ != OBJECT_PRIORITY_DEFAULT.
=> attached to ACTIVITY->PRIORITIES. */
hurd_btree_node_t priority_node;
/* ACTIVITY is valid, EVICTION_CANDIDATE is false, POLICY.PRIORITY
- == OBJECT_PRIORITY_LRU,
+ == OBJECT_PRIORITY_DEFAULT,
=> attached to one of ACTIVITY's LRU lists.
@@ -245,7 +245,7 @@ extern struct object_desc *object_descs;
space; \
}), OID_PRINTF (object_to_object_desc ((__onp))->oid) \
-LIST_CLASS(activity_lru, struct object_desc, activity_node, true)
+LIST_CLASS(activity, struct object_desc, activity_node, true)
LIST_CLASS(eviction, struct object_desc, activity_node, true)
LIST_CLASS(available, struct object_desc, available_node, true)
diff --git a/viengoos/pager.c b/viengoos/pager.c
index caede94..295ed4f 100644
--- a/viengoos/pager.c
+++ b/viengoos/pager.c
@@ -73,19 +73,23 @@ reclaim_from (struct activity *victim, int goal)
/* XXX: Implement group dealloc. */
- /* First try objects with a priority lower than LRU. */
+ int i;
+#ifndef NDEBUG
+ int active = 0;
+ int inactive = 0;
- assertx (victim->priorities_count
- + activity_lru_list_count (&victim->active)
- + activity_lru_list_count (&victim->inactive)
- + eviction_list_count (&victim->eviction_dirty)
+ for (i = OBJECT_PRIORITY_MIN; i <= OBJECT_PRIORITY_MAX; i ++)
+ {
+ active += activity_list_count (&victim->frames[i].active);
+ inactive += activity_list_count (&victim->frames[i].inactive);
+ }
+
+ assertx (active + inactive + eviction_list_count (&victim->eviction_dirty)
== victim->frames_local,
- "%d + %d + %d + %d != %d!",
- victim->priorities_count,
- activity_lru_list_count (&victim->active),
- activity_lru_list_count (&victim->inactive),
- eviction_list_count (&victim->eviction_dirty),
+ "%d + %d + %d != %d!",
+ active, inactive, eviction_list_count (&victim->eviction_dirty),
victim->frames_local);
+#endif
debug (5, "Reclaiming %d from " OBJECT_NAME_FMT ", %d frames "
"(global: avail: %d, laundry: %d)",
@@ -93,164 +97,61 @@ reclaim_from (struct activity *victim, int goal)
victim->frames_local,
available_list_count (&available), laundry_list_count (&laundry));
- struct object_desc *desc;
- struct object_desc *next
- = hurd_btree_priorities_first (&victim->priorities);
- while (((desc = next)) && count < goal)
- {
- assert (! desc->eviction_candidate);
-
- assert (desc->policy.priority != OBJECT_PRIORITY_LRU);
- if (desc->policy.priority > OBJECT_PRIORITY_LRU)
- /* DESC's priority is higher than OBJECT_PRIORITY_LRU, prefer
- LRU ordered pages. */
- break;
-
- next = hurd_btree_priorities_next (desc);
-
- object_desc_flush (desc, false);
-
- hurd_btree_priorities_detach (&victim->priorities, desc);
- victim->priorities_count --;
-
- desc->eviction_candidate = true;
-
- if (desc->dirty && ! desc->policy.discardable)
- {
- if (! list_node_attached (&desc->laundry_node))
- laundry_list_queue (&laundry, desc);
-
- eviction_list_queue (&victim->eviction_dirty, desc);
- laundry_count ++;
- }
- else
- {
- assert (! list_node_attached (&desc->available_node));
- is_clean (desc);
-
- available_list_queue (&available, desc);
- eviction_list_queue (&victim->eviction_clean, desc);
-
- if (desc->policy.discardable)
- discarded ++;
- }
-
- count ++;
- }
-
- if (count < goal)
- /* VICTIM still has to yield pages. Start stealing from the
- inactive LRU lists. */
- {
- struct object_desc *inactive;
-
- /* For every clean page we steal, we queue a dirty page for
- writeout. */
-
- inactive = activity_lru_list_head (&victim->inactive);
-
- struct object_desc *next;
-
- while (inactive && count < goal)
- {
- assert (! inactive->eviction_candidate);
- assert (! list_node_attached (&inactive->available_node));
-
- next = activity_lru_list_next (inactive);
-
- activity_lru_list_unlink (&victim->inactive, inactive);
-
- object_desc_flush (inactive, false);
- if (inactive->dirty && ! inactive->policy.discardable)
- {
- eviction_list_push (&victim->eviction_dirty, inactive);
-
- laundry_list_queue (&laundry, inactive);
- laundry_count ++;
- }
- else
- {
- is_clean (inactive);
-
- eviction_list_push (&victim->eviction_clean, inactive);
-
- available_list_queue (&available, inactive);
-
- if (desc->policy.discardable)
- discarded ++;
- }
-
- inactive->eviction_candidate = true;
-
- count ++;
-
- inactive = next;
- }
- }
-
- if (count < goal)
- /* Still hasn't yielded enough. Steal from the active list. */
+ for (i = OBJECT_PRIORITY_MIN; i <= OBJECT_PRIORITY_MAX; i ++)
{
struct object_desc *desc;
- struct object_desc *next = activity_lru_list_head (&victim->active);
-
- while ((desc = next) && count < goal)
+ while (count < goal
+ && (desc = activity_list_head (&victim->frames[i].inactive)))
{
assert (! desc->eviction_candidate);
+ assert (! list_node_attached (&desc->available_node));
+ assertx (i == desc->policy.priority,
+ "%d != %d",
+ i, desc->policy.priority);
- next = activity_lru_list_next (desc);
+ activity_list_unlink (&victim->frames[i].inactive, desc);
object_desc_flush (desc, false);
-
- desc->eviction_candidate = true;
-
- activity_lru_list_unlink (&victim->active, desc);
-
if (desc->dirty && ! desc->policy.discardable)
{
- if (! list_node_attached (&desc->laundry_node))
- laundry_list_queue (&laundry, desc);
+ eviction_list_push (&victim->eviction_dirty, desc);
- eviction_list_queue (&victim->eviction_dirty, desc);
+ laundry_list_queue (&laundry, desc);
laundry_count ++;
}
else
{
- assert (! list_node_attached (&desc->available_node));
is_clean (desc);
+ eviction_list_push (&victim->eviction_clean, desc);
+
available_list_queue (&available, desc);
- eviction_list_queue (&victim->eviction_clean, desc);
if (desc->policy.discardable)
discarded ++;
}
+ desc->eviction_candidate = true;
+
count ++;
}
- }
-
- if (count < goal)
- /* We've cleared the low priority nodes, the inactive LRU lists
- and the active LRU list. Steal from the high priority
- lists. */
- {
- /* NEXT points to the first high priority object descriptor. */
- while (count < goal && (desc = next))
+ /* Currently we evict in LIFO order. We should do a semi-sort and
+ then evict accordingly. */
+ while (count < goal
+ && (desc = activity_list_head (&victim->frames[i].active)))
{
assert (! desc->eviction_candidate);
- assert (desc->policy.priority > OBJECT_PRIORITY_LRU);
-
- next = hurd_btree_priorities_next (desc);
+ assertx (i == desc->policy.priority,
+ "%d != %d",
+ i, desc->policy.priority);
object_desc_flush (desc, false);
- hurd_btree_priorities_detach (&victim->priorities, desc);
- victim->priorities_count --;
-
desc->eviction_candidate = true;
+ activity_list_unlink (&victim->frames[i].active, desc);
+
if (desc->dirty && ! desc->policy.discardable)
{
if (! list_node_attached (&desc->laundry_node))
@@ -295,17 +196,22 @@ reclaim_from (struct activity *victim, int goal)
zalloc_memory, available_list_count (&available),
laundry_list_count (&laundry));
- assertx (victim->priorities_count
- + activity_lru_list_count (&victim->active)
- + activity_lru_list_count (&victim->inactive)
- + eviction_list_count (&victim->eviction_dirty)
+#ifndef NDEBUG
+ active = 0;
+ inactive = 0;
+
+ for (i = OBJECT_PRIORITY_MIN; i <= OBJECT_PRIORITY_MAX; i ++)
+ {
+ active += activity_list_count (&victim->frames[i].active);
+ inactive += activity_list_count (&victim->frames[i].inactive);
+ }
+
+ assertx (active + inactive + eviction_list_count (&victim->eviction_dirty)
== victim->frames_local,
- "%d + %d + %d + %d != %d!",
- victim->priorities_count,
- activity_lru_list_count (&victim->active),
- activity_lru_list_count (&victim->inactive),
- eviction_list_count (&victim->eviction_dirty),
+ "%d + %d + %d != %d!",
+ active, inactive, eviction_list_count (&victim->eviction_dirty),
victim->frames_local);
+#endif
/* We should never have selected a task from which we can free
nothing! */