diff options
author | neal <neal> | 2008-02-18 10:42:15 +0000 |
---|---|---|
committer | neal <neal> | 2008-02-18 10:42:15 +0000 |
commit | ee31ed0a6c91293314f4d1759f0a1cd549b14bc3 (patch) | |
tree | 0bc9652ae6d979e8fe2e9f0dd1775f42dae55075 /viengoos/pager.c | |
parent | 9bbc315a45e45332a681946d0f02aecf8576e645 (diff) |
2008-02-18 Neal H. Walfield <neal@gnu.org>
* pager.c (pager_collect): When looking for a victim activity, if
none are found, repeat the process giving the number of active
pages less weight. Fix asserts.
Diffstat (limited to 'viengoos/pager.c')
-rw-r--r-- | viengoos/pager.c | 72 |
1 files changed, 42 insertions, 30 deletions
diff --git a/viengoos/pager.c b/viengoos/pager.c index 087f8bc..d1f3c91 100644 --- a/viengoos/pager.c +++ b/viengoos/pager.c @@ -287,7 +287,7 @@ pager_collect (int goal) PAGER_LOW_WATER_MARK, goal); /* Find a victim. */ - struct activity *victim = root_activity; + struct activity *victim; struct activity *parent; struct activity_memory_policy victim_policy; @@ -388,39 +388,50 @@ pager_collect (int goal) return false; } - parent = victim; - victim = NULL; - bool have_self = false; - - struct activity *child; - bool done = false; - for (child = activity_children_list_tail (&parent->children); - child; - child = activity_children_list_prev (child)) + /* Each time through, we let the number of active frames play a + less significant role. */ + int factor; + for (factor = 1; factor <= 16; factor <<= 1) { - if (! have_self && (parent->policy.child_rel.priority <= - child->policy.sibling_rel.priority)) + parent = root_activity; + victim = NULL; + bool have_self = false; + + struct activity *child; + bool done = false; + for (child = activity_children_list_tail (&parent->children); + child; + child = activity_children_list_prev (child)) { - have_self = true; - done = process (parent, parent->policy.child_rel, - parent->frames_local - - ACTIVITY_STATS_LAST (parent)->active_local); + if (! have_self && (parent->policy.child_rel.priority <= + child->policy.sibling_rel.priority)) + { + have_self = true; + int frames = parent->frames_local + - ACTIVITY_STATS_LAST (parent)->active_local / factor; + done = process (parent, parent->policy.child_rel, frames); + if (done) + break; + } + + int frames = child->frames_total + - ACTIVITY_STATS_LAST (child)->active / factor; + done = process (child, child->policy.sibling_rel, frames); if (done) break; } - done = process (child, child->policy.sibling_rel, - child->frames_total - - ACTIVITY_STATS_LAST (child)->active); - if (done) + if (! done && ! have_self) + { + int frames = parent->frames_local + - ACTIVITY_STATS_LAST (parent)->active_local / factor; + process (parent, parent->policy.child_rel, frames); + } + + if (victim) break; } - if (! done && ! have_self) - process (parent, parent->policy.child_rel, - parent->frames_local - - ACTIVITY_STATS_LAST (parent)->active_local); - assert (victim); /* We steal from VICTIM. */ @@ -428,17 +439,18 @@ pager_collect (int goal) /* Calculate VICTIM's share of the frames allocated to all the activity's at this priority level. */ int share = 0; - if (weight > 0 && frames < goal) - share = ((frames - goal) * victim_policy.weight) / weight; + if (weight > 0 && frames > goal) + share = ((uint64_t) (frames - goal) * victim_policy.weight) / weight; + assert (share >= 0); /* VICTIM's share must be less than or equal to the frames allocated to this priority as we know that this activity has an excess and VICTIM is the most excessive. */ - assertx (share < victim->frames_total, - "%d <= %d", share, victim->frames_total); + assertx (share <= victim->frames_total, + "%d > %d", share, victim->frames_total); assertx (victim_frames >= share, - "%d > %d", victim_frames, share); + "%d < %d", victim_frames, share); debug (0, "Choosing activity " OID_FMT "%s, %d/%d frames, " "share: %d, goal: %d", |