summaryrefslogtreecommitdiff
path: root/viengoos/pager.c
diff options
context:
space:
mode:
authorneal <neal>2008-06-27 15:17:27 +0000
committerneal <neal>2008-06-27 15:17:27 +0000
commitc314b447a633a3aa2d1e4a882675038fd381e873 (patch)
treec3d2625fc63af15c7e6200203a5347e68f192713 /viengoos/pager.c
parent8305c7cd3d379fda42cee8c58783bf2ae52f4ff0 (diff)
hurd/
2008-06-27 Neal H. Walfield <neal@gnu.org> * activity.h (RM_activity_stats): Don't define. (RM_activity_info): Replace with this. (struct activity_stats): Add field pressure_local. Make field pressure an 8 bit integer. (struct activity_stats_buffer): Remove structure. (struct activity_info): Replace with this structure. (activity_info_stats): Define. (activity_info_pressure): Likewise. (activity_stats): Remove method. (activity_info): Replace with this. viengoos/ 2008-06-27 Neal H. Walfield <neal@gnu.org> * activity.h (struct activity): Add fields free_bad_karma, free_goal, free_allocations and free_initial_allocation. * rm.h (rm_method_id_string): Replace RM_activity_stats handling with RM_activity_info handling. * thread.h (THREAD_WAIT_STATS): Remove. (THREAD_WAIT_ACTIVITY_INFO): Replace with this. (struct thread): Add field wait_reason_arg2. * ager.c (update_stats): Account for local pressure when calculating availability. Don't use activity_stats to inform threads of new statistics but activity_info. * object.c (object_desc_claim): Adjust the activity's FREE_GOAL, FREE_ALLOCATIONS, and FRAMES_EXCLUDED fields as appropriate. * pager.c (pager_collect): When selecting a victim, don't include an activity's excluded frames in its allocation. Don't even consider activities for which FREE_ALLOCATIONS is non-zero. Having selected a victim, don't increase the pressure do drastically. Update the local pressure. Having selected a victim from which to revoke pages, send any waiting threads a message to free memory. If VICTIM->FREE_BAD_KARMA is 0, assume that the memory will be freed and give the activity 100 claims to do it. If the activity has bad karma, decrease it by one. * server.c (server_loop): Replace activity_stats implementation with implementation appropriate for activity_info. hieronymus/ 2008-06-27 Neal H. Walfield <neal@gnu.org> * hieronymus.c (do_gather_stats): Change to use activity_info instead of activity_stats. (main): Introduce code to delay process creation. ruth/ 2008-06-27 Neal H. Walfield <neal@gnu.org> * ruth.c (main): Update to use activity_info instead of activity_stats. benchmarks/ 2008-06-27 Neal H. Walfield <neal@gnu.org> * shared-memory-distribution.c (main): Update to use activity_info instead of activity_status. * activity-distribution.c (main): Likewise. * GCbench.c: Include <stdint.h> and <stdbool.h>. (now): New function. (struct stats): Add fields time, gcs and iter. (have_a_hog): New variable. (mem_hog) [__gnu_hurd_viengoos__]: Rename from this... (helper) [__gnu_hurd_viengoos__]: ... to this. Use activity_info, not activity_stats. Gather more data. (helper) [! __gnu_hurd_viengoos__]: New function. (tid): Rename from this... (helper_tid): ... to this. (helper_fork) [__gnu_hurd_viengoos__]: Name activities. (main): Improve output. benchmarks/boehm-gc/ 2008-06-27 Neal H. Walfield <neal@gnu.org> * patches/05-viengoos-scheduler.patch: Update to use activity_info in place of activity_stats. Listen for pressure messages and act appropriately. Tighten adaptive code. Improve profiling code.
Diffstat (limited to 'viengoos/pager.c')
-rw-r--r--viengoos/pager.c112
1 files changed, 95 insertions, 17 deletions
diff --git a/viengoos/pager.c b/viengoos/pager.c
index db3f6cf..0dc7ad4 100644
--- a/viengoos/pager.c
+++ b/viengoos/pager.c
@@ -286,13 +286,14 @@ reclaim_from (struct activity *victim, int goal)
ancestor->frames_pending_eviction += laundry_count;
}));
- debug (5, "Reclaimed from " OID_FMT ": goal: %d; %d frames; "
+ debug (5, "Reclaimed from " OBJECT_NAME_FMT ": goal: %d; %d frames; "
DEBUG_BOLD ("%d in laundry, %d made available (%d discarded)") " "
- "(now: avail: %d, laundry: %d)",
- OID_PRINTF (object_oid ((struct object *) victim)), goal,
+ "(now: free: %d, avail: %d, laundry: %d)",
+ OBJECT_NAME_PRINTF ((struct object *) victim), goal,
victim->frames_local,
laundry_count, count - laundry_count, discarded,
- available_list_count (&available), laundry_list_count (&laundry));
+ zalloc_memory, available_list_count (&available),
+ laundry_list_count (&laundry));
assertx (victim->priorities_count
+ activity_lru_list_count (&victim->active)
@@ -324,7 +325,7 @@ pager_collect (int goal)
int available_memory = zalloc_memory + available_list_count (&available);
- debug (5, "Frames: %d, available: %d (%d%%), pending page out: %d, "
+ debug (0, "Frames: %d, available: %d (%d%%), pending page out: %d, "
"low water: %d, goal: %d",
memory_total,
available_memory, (available_memory * 100) / memory_total,
@@ -466,18 +467,34 @@ pager_collect (int goal)
child->policy.sibling_rel.priority))
{
have_self = true;
- int frames = parent->frames_local
- - eviction_list_count (&parent->eviction_dirty)
- - (ACTIVITY_STATS_LAST (parent)->active_local
- >> factor);
- if (frames > 0)
- done = process (parent, parent->policy.child_rel,
- frames);
- if (done)
- break;
+
+ /* If PARENT->FREE_ALLOCATIONS is non-zero, we
+ have already selected this activity for
+ eviction and have sent it a message asking it
+ to free memory. It may make
+ PARENT->FREE_ALLOCATIONS before it is again
+ eligible. */
+ if (! parent->free_allocations)
+ {
+ int frames = parent->frames_local
+ - eviction_list_count (&parent->eviction_dirty)
+ - (ACTIVITY_STATS_LAST (parent)->active_local
+ >> factor);
+ if (frames > 0)
+ done = process (parent, parent->policy.child_rel,
+ frames);
+ if (done)
+ break;
+ }
+ else
+ debug (0, "Excluding " OBJECT_NAME_FMT
+ ": %d free frames, %d excluded",
+ parent->free_allocations,
+ parent->frames_excluded);
}
int frames = child->frames_total
+ - child->frames_excluded
- child->frames_pending_eviction
- (ACTIVITY_STATS_LAST (child)->active >> factor);
if (frames > 0)
@@ -489,6 +506,7 @@ pager_collect (int goal)
if (! done && ! have_self)
{
int frames = parent->frames_local
+ - child->frames_excluded
- eviction_list_count (&parent->eviction_dirty)
- (ACTIVITY_STATS_LAST (parent)->active_local >> factor);
if (frames > 0)
@@ -504,7 +522,7 @@ pager_collect (int goal)
if (! victim)
break;
- ACTIVITY_STATS (victim)->pressure += 4;
+ ACTIVITY_STATS (victim)->pressure ++;
assert (victim);
}
@@ -515,6 +533,8 @@ pager_collect (int goal)
/* We steal from VICTIM. */
+ ACTIVITY_STATS (victim)->pressure_local += 4;
+
/* Calculate VICTIM's share of the frames allocated to all the
activity's at this priority level. */
int share = 0;
@@ -531,8 +551,10 @@ pager_collect (int goal)
assertx (victim_frames >= share,
"%d < %d", victim_frames, share);
- debug (5, DEBUG_BOLD ("Revoking from activity " OBJECT_NAME_FMT ", ")
+ debug (5, "%d of %d pages available; "
+ DEBUG_BOLD ("Revoking from activity " OBJECT_NAME_FMT ", ")
"%d/%d frames (pending eviction: %d/%d), share: %d, goal: %d",
+ zalloc_memory + available_list_count (&available), memory_total,
OBJECT_NAME_PRINTF ((struct object *) victim),
victim->frames_local, victim->frames_total,
eviction_list_count (&victim->eviction_dirty),
@@ -543,7 +565,63 @@ pager_collect (int goal)
if (reclaim > goal)
reclaim = goal;
- total_freed += reclaim_from (victim, reclaim);
+ bool need_reclaim = true;
+
+ struct thread *thread;
+ object_wait_queue_for_each (victim, (struct object *) victim,
+ thread)
+ if (thread->wait_reason == THREAD_WAIT_ACTIVITY_INFO
+ && (thread->wait_reason_arg & activity_info_pressure))
+ break;
+
+ if (thread)
+ {
+ debug (0, DEBUG_BOLD ("Requesting that " OBJECT_NAME_FMT " free "
+ "%d pages.") " Karma: %d",
+ OBJECT_NAME_PRINTF ((struct object *) victim),
+ goal, victim->free_bad_karma);
+
+ if (! victim->free_goal
+ && victim->free_bad_karma == 0)
+ /* If the activity manages half the goal, we'll be
+ happy. */
+ {
+ need_reclaim = false;
+
+ victim->free_goal = goal / 2;
+ victim->free_allocations = 100;
+ victim->free_initial_allocation = victim->frames_local;
+
+ struct activity *ancestor = victim;
+ activity_for_each_ancestor
+ (ancestor,
+ ({
+ ancestor->frames_excluded += victim->frames_local;
+ }));
+
+ total_freed += goal;
+ }
+
+ struct activity_info info;
+ info.event = activity_info_pressure;
+ info.pressure.amount = - goal;
+
+ object_wait_queue_for_each (victim,
+ (struct object *) victim,
+ thread)
+ if (thread->wait_reason == THREAD_WAIT_ACTIVITY_INFO
+ && (thread->wait_reason_arg & activity_info_pressure))
+ {
+ object_wait_queue_dequeue (victim, thread);
+ rm_activity_info_reply (thread->tid, info);
+ }
+ }
+
+ if (victim->free_bad_karma)
+ victim->free_bad_karma --;
+
+ if (need_reclaim)
+ total_freed += reclaim_from (victim, reclaim);
}
if (zalloc_memory + available_list_count (&available)