summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@gnu.org>2009-02-24 03:35:32 +0100
committerNeal H. Walfield <neal@gnu.org>2009-03-01 21:03:10 +0100
commit5b7cdcca8ce9389ccd138c69c72e769a3aea48a8 (patch)
treeb96c00ac3bbb5af7571b1a56052a178ffc1ee515
parentdfe045b9ad900945f15658d052496dbf2741502f (diff)
Improve the boehm gc scheduler.
-rw-r--r--benchmarks/boehm-gc/patches/01-gc-include-private-gcconfig-h.patch7
-rw-r--r--benchmarks/boehm-gc/patches/05-viengoos-scheduler.patch145
2 files changed, 93 insertions, 59 deletions
diff --git a/benchmarks/boehm-gc/patches/01-gc-include-private-gcconfig-h.patch b/benchmarks/boehm-gc/patches/01-gc-include-private-gcconfig-h.patch
index ff3d1fc..f8a0a1e 100644
--- a/benchmarks/boehm-gc/patches/01-gc-include-private-gcconfig-h.patch
+++ b/benchmarks/boehm-gc/patches/01-gc-include-private-gcconfig-h.patch
@@ -4,8 +4,9 @@ exit $?
Tweak the configuration.
---- gc.orig/include/private/gcconfig.h 2007-06-29 02:00:09.000000000 +0200
-+++ gc/include/private/gcconfig.h 2009-02-21 02:28:37.000000000 +0100
+diff -urp -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in gc/include/private/gcconfig.h gc.new/include/private/gcconfig.h
+--- gc/include/private/gcconfig.h 2007-06-29 02:00:09.000000000 +0200
++++ gc.new/include/private/gcconfig.h 2009-02-23 22:59:56.000000000 +0100
@@ -451,7 +451,28 @@
# define HURD
# define I386
@@ -32,7 +33,7 @@ Tweak the configuration.
+# include <viengoos/addr.h>
+extern vg_addr_t gc_activity __attribute__ ((weak));
+# define ACTIVITY (&gc_activity ? gc_activity : VG_ADDR_VOID)
-+extern int GC_available_bytes;
++extern uintptr_t GC_available_bytes;
# endif
# if defined(__TANDEM)
/* Nonstop S-series */
diff --git a/benchmarks/boehm-gc/patches/05-viengoos-scheduler.patch b/benchmarks/boehm-gc/patches/05-viengoos-scheduler.patch
index 2f3a389..a9361d5 100644
--- a/benchmarks/boehm-gc/patches/05-viengoos-scheduler.patch
+++ b/benchmarks/boehm-gc/patches/05-viengoos-scheduler.patch
@@ -6,9 +6,9 @@ Patch to support the Viengoos specific scheduler. To disable it, set
GC_viengoos_scheduler to 0.
-diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -rup gc.orig/allchblk.c gc/allchblk.c
+diff -urp -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in gc.orig/allchblk.c gc/allchblk.c
--- gc.orig/allchblk.c 2007-06-07 02:40:07.000000000 +0200
-+++ gc/allchblk.c 2009-02-21 02:15:48.000000000 +0100
++++ gc/allchblk.c 2009-02-24 03:07:28.000000000 +0100
@@ -117,7 +117,9 @@ void GC_print_hblkfreelist()
while (h != 0) {
hhdr = HDR(h);
@@ -20,7 +20,7 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
total_free += sz;
if (GC_is_black_listed(h, HBLKSIZE) != 0) {
GC_printf("start black listed\n");
-@@ -381,31 +383,135 @@ void GC_add_to_fl(struct hblk *h, hdr *h
+@@ -381,31 +383,142 @@ void GC_add_to_fl(struct hblk *h, hdr *h
#ifdef USE_MUNMAP
@@ -44,6 +44,8 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
-
- for (i = 0; i <= N_HBLK_FLS; ++i) {
+
++ uint64_t mapped_start = GC_get_heap_size() - GC_unmapped_bytes;
++
+ start:
+ if (GC_viengoos_scheduler
+ && (GC_get_heap_size() - GC_unmapped_bytes
@@ -51,12 +53,17 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
+ /* The number of mapped bytes is at most 7/8s the available
+ memory. That's good enough for now. (Recall: the high-water
+ mark is 15/16s the available memory.) */
++ uint64_t mapped_now = GC_get_heap_size() - GC_unmapped_bytes;
++
++ extern char *program_name;
+ if (0)
-+ printf ("%x: After unmapping %d used (%d available)\n",
-+ l4_myself (),
-+ (GC_get_heap_size() - GC_unmapped_bytes) / 4096,
-+ GC_available_bytes / 4096);
-+ return;
++ printf ("%s("VG_THREAD_ID_FMT"): After unmapping %"PRId64" mb, "
++ "%"PRId64"mb used (%"PRId64"mb available)\n",
++ program_name, hurd_myself (),
++ (mapped_start - mapped_now) / 1024 / 1024,
++ mapped_now / 1024 / 1024,
++ (uint64_t) GC_available_bytes / 1024 / 1024);
++ return;
+ }
+
+ /* Start with the large blocks and work our way down. */
@@ -166,7 +173,7 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
}
/* Merge all unmapped blocks that are adjacent to other free */
-@@ -413,6 +519,12 @@ void GC_unmap_old(void)
+@@ -413,6 +526,12 @@ void GC_unmap_old(void)
/* fully mapped or fully unmapped. */
void GC_merge_unmapped(void)
{
@@ -179,7 +186,7 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
struct hblk * h, *next;
hdr * hhdr, *nexthdr;
word size, nextsize;
-@@ -600,12 +712,26 @@ GC_allochblk_nth(size_t sz, int kind, un
+@@ -600,12 +719,26 @@ GC_allochblk_nth(size_t sz, int kind, un
size_needed = HBLKSIZE * OBJ_SZ_TO_BLOCKS(sz);
@@ -206,7 +213,7 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
if (size_avail != size_needed
&& !GC_use_entire_heap
&& !GC_dont_gc
-@@ -642,7 +768,7 @@ GC_allochblk_nth(size_t sz, int kind, un
+@@ -642,7 +775,7 @@ GC_allochblk_nth(size_t sz, int kind, un
next_size = (signed_word)(thishdr -> hb_sz);
if (next_size < size_avail
&& next_size >= size_needed
@@ -215,7 +222,7 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
continue;
}
}
-@@ -748,10 +874,12 @@ GC_allochblk_nth(size_t sz, int kind, un
+@@ -748,10 +881,12 @@ GC_allochblk_nth(size_t sz, int kind, un
/* hbp may be on the wrong freelist; the parameter n */
/* is important. */
hbp = GC_get_first_part(hbp, hhdr, size_needed, n);
@@ -229,9 +236,9 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
if (0 == hbp) return 0;
/* Add it to map of valid blocks */
-diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -rup gc/alloc.c gc.now/alloc.c
---- gc.orig/alloc.c 2007-06-22 04:40:30.000000000 +0200
-+++ gc/alloc.c 2009-02-22 03:15:24.000000000 +0100
+diff -urp -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in gc/alloc.c gc.new/alloc.c
+--- gc/alloc.c 2007-06-22 04:40:30.000000000 +0200
++++ gc.new/alloc.c 2009-02-24 03:07:16.000000000 +0100
@@ -15,6 +15,13 @@
*
*/
@@ -255,15 +262,15 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
/*
* Separate free lists are maintained for different sized objects
* up to MAXOBJBYTES.
-@@ -223,9 +232,134 @@ void GC_clear_a_few_frames()
+@@ -223,9 +232,160 @@ void GC_clear_a_few_frames()
/* limits used by blacklisting. */
static word GC_collect_at_heapsize = (word)(-1);
+int GC_viengoos_scheduler = 1;
-+int GC_available_bytes = (256 + 128) * 1024 * 1024;
++uintptr_t GC_available_bytes = (uintptr_t) ((256 + 128) * 1024 * 1024);
+int GC_could_unmap;
+
-+#define THRESHOLD (15 * (GC_available_bytes / 16))
++#define THRESHOLD ((uintptr_t) (15 * (GC_available_bytes / 16)))
+
+#ifdef __gnu_hurd_viengoos__
+static void *
@@ -281,16 +288,31 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
+ period, &info);
+ assert_perror (err);
+
++ /* What I think I've allocated. This it the amount of mapped
++ heap; it does not include pages tables, etc. */
++ uint64_t my_alloced = GC_get_heap_size () - GC_unmapped_bytes;
++ /* What the kernel thinks I've allocated. It only includes
++ physical memory. */
++ uint64_t real_alloced = (uint64_t) (info.stats.stats[0].dirty
++ + info.stats.stats[0].clean)
++ * PAGESIZE;
++
++ uint64_t old_avail = GC_available_bytes;
++
+ switch (info.event)
+ {
+ case vg_activity_info_stats:
-+ GC_available_bytes = info.stats.stats[0].available_local * PAGESIZE;
++ GC_available_bytes
++ = (uintptr_t) info.stats.stats[0].available_local * PAGESIZE
++ - (real_alloced - my_alloced);
+ period = info.stats.stats[0].period + 1;
+ break;
+
+ case vg_activity_info_pressure:
-+ if (-info.pressure.amount * PAGESIZE < GC_available_bytes)
-+ GC_available_bytes -= -info.pressure.amount * PAGESIZE;
++ /* PRESSURE.AMOUNT is negative. */
++ if (-(uintptr_t) info.pressure.amount * PAGESIZE < my_alloced)
++ GC_available_bytes
++ = my_alloced + (uintptr_t) info.pressure.amount * PAGESIZE;
+ else
+ /* Huh? */
+ GC_available_bytes = 0;
@@ -300,21 +322,29 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
+ panic ("Unknown event and unrequested event: %"PRIdPTR, info.event);
+ }
+
++ extern char *program_name;
+ if (0)
-+ printf (VG_THREAD_ID_FMT": %s: %d alloced: %d, heap: %d, "
-+ "mapped:%d, unmapped: %d, available: %d, "
-+ "low-water: %d\n",
-+ hurd_myself (),
++ printf ("%s("VG_THREAD_ID_FMT"): %s: "
++ "%"PRId64" alloced: %"PRId64"mb, heap: %"PRId64"mb, "
++ "mapped:%"PRId64"mb, unmapped: %"PRId64"mb, "
++ "available: %"PRIdPTR"mb => %"PRIdPTR"mb, "
++ "low-water: %"PRIdPTR"mb\n",
++ program_name, hurd_myself (),
+ info.event == vg_activity_info_stats
+ ? "Period" : DEBUG_BOLD ("PRESSURE"),
-+ (int) (info.event == vg_activity_info_stats
-+ ? period : info.pressure.amount),
-+ (int) GC_adj_bytes_allocd() / PAGESIZE,
-+ (int) GC_get_heap_size () / PAGESIZE,
-+ (int) (GC_get_heap_size () - GC_unmapped_bytes) / PAGESIZE,
-+ (int) GC_unmapped_bytes / PAGESIZE,
-+ (int) GC_available_bytes / PAGESIZE,
-+ (int) THRESHOLD / PAGESIZE);
++ (uint64_t) (info.event == vg_activity_info_stats
++ ? period : info.pressure.amount),
++ (uint64_t) GC_adj_bytes_allocd() / 1024 / 1024,
++ (uint64_t) GC_get_heap_size () / 1024 / 1024,
++ (uint64_t) (GC_get_heap_size () - GC_unmapped_bytes)
++ / 1024 / 1024,
++ (uint64_t) GC_unmapped_bytes / 1024 / 1024,
++ (uint64_t) old_avail / 1024 / 1024,
++ (uint64_t) GC_available_bytes / 1024 / 1024,
++ (uint64_t) THRESHOLD / 1024 / 1024);
++ if (info.event == vg_activity_info_pressure)
++ printf ("pages to free: %d mb\n",
++ info.pressure.amount * (PAGESIZE / 1024) / 1024);
+ }
+}
+#endif
@@ -369,18 +399,21 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
+ a GC. */
+ if (warning != GC_gc_no) {
+ warning = GC_gc_no;
++ extern char *program_name;
+ if (0)
-+ printf ("Scheduling GC: (%u) alloced: %dkb, heap: %dkb, "
-+ "mapped: %dkb, unmapped: %dkb, available: %dkb, "
-+ "low-water: %dkb\n",
-+ (int) GC_gc_no,
-+ (int) alloced / 1024,
-+ (int) GC_get_heap_size () / 1024,
-+ (int) (GC_get_heap_size () - GC_unmapped_bytes)
-+ / 1024,
-+ (int) GC_unmapped_bytes / 1024,
-+ (int) GC_available_bytes / 1024,
-+ (int) THRESHOLD);
++ printf ("%s("VG_THREAD_ID_FMT"): Scheduling GC #%u: "
++ "alloced: %"PRId64"mb, heap: %"PRId64"mb, "
++ "mapped: %"PRId64"mb, unmapped: %"PRId64"mb, "
++ "available: %"PRIdPTR"mb, low-water: %"PRIdPTR"mb\n",
++ program_name, hurd_myself (),
++ (uint64_t) GC_gc_no,
++ (uint64_t) alloced / 1024 / 1024,
++ (uint64_t) GC_get_heap_size () / 1024 / 1024,
++ (uint64_t) (GC_get_heap_size () - GC_unmapped_bytes)
++ / 1024 / 1024,
++ (uint64_t) GC_unmapped_bytes / 1024 / 1024,
++ (uint64_t) GC_available_bytes / 1024 / 1024,
++ (uint64_t) THRESHOLD / 1024 / 1024);
+ }
+ }
+
@@ -390,7 +423,7 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
return(GC_adj_bytes_allocd() >= min_bytes_allocd()
|| GC_heapsize >= GC_collect_at_heapsize);
}
-@@ -256,6 +390,8 @@ void GC_maybe_gc(void)
+@@ -256,6 +416,8 @@ void GC_maybe_gc(void)
n_partial_gcs = 0;
return;
} else {
@@ -399,7 +432,7 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
# ifdef PARALLEL_MARK
GC_wait_for_reclaim();
# endif
-@@ -266,6 +402,7 @@ void GC_maybe_gc(void)
+@@ -266,6 +428,7 @@ void GC_maybe_gc(void)
(unsigned long)GC_gc_no+1,
(long)GC_bytes_allocd);
}
@@ -407,7 +440,7 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
GC_promote_black_lists();
(void)GC_reclaim_all((GC_stop_func)0, TRUE);
GC_clear_marks();
-@@ -275,7 +412,11 @@ void GC_maybe_gc(void)
+@@ -275,7 +438,11 @@ void GC_maybe_gc(void)
} else {
n_partial_gcs++;
}
@@ -419,7 +452,7 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
/* We try to mark with the world stopped. */
/* If we run out of time, this turns into */
/* incremental marking. */
-@@ -294,6 +435,8 @@ void GC_maybe_gc(void)
+@@ -294,6 +461,8 @@ void GC_maybe_gc(void)
GC_n_attempts++;
}
}
@@ -428,7 +461,7 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
}
}
-@@ -325,6 +468,10 @@ GC_bool GC_try_to_collect_inner(GC_stop_
+@@ -325,6 +494,10 @@ GC_bool GC_try_to_collect_inner(GC_stop_
"Initiating full world-stop collection %lu after %ld allocd bytes\n",
(unsigned long)GC_gc_no+1, (long)GC_bytes_allocd);
}
@@ -439,7 +472,7 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
GC_promote_black_lists();
/* Make sure all blocks have been reclaimed, so sweep routines */
/* don't see cleared mark bits. */
-@@ -337,7 +484,8 @@ GC_bool GC_try_to_collect_inner(GC_stop_
+@@ -337,7 +510,8 @@ GC_bool GC_try_to_collect_inner(GC_stop_
if ((GC_find_leak || stop_func != GC_never_stop_func)
&& !GC_reclaim_all(stop_func, FALSE)) {
/* Aborted. So far everything is still consistent. */
@@ -449,7 +482,7 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
}
GC_invalidate_mark_state(); /* Flush mark stack. */
GC_clear_marks();
-@@ -354,7 +502,8 @@ GC_bool GC_try_to_collect_inner(GC_stop_
+@@ -354,7 +528,8 @@ GC_bool GC_try_to_collect_inner(GC_stop_
GC_unpromote_black_lists();
} /* else we claim the world is already still consistent. We'll */
/* finish incrementally. */
@@ -459,7 +492,7 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
}
GC_finish_collection();
if (GC_print_stats) {
-@@ -362,7 +511,10 @@ GC_bool GC_try_to_collect_inner(GC_stop_
+@@ -362,7 +537,10 @@ GC_bool GC_try_to_collect_inner(GC_stop_
GC_log_printf("Complete collection took %lu msecs\n",
MS_TIME_DIFF(current_time,start_time));
}
@@ -471,7 +504,7 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
}
-@@ -390,6 +542,8 @@ void GC_collect_a_little_inner(int n)
+@@ -390,6 +568,8 @@ void GC_collect_a_little_inner(int n)
if (GC_dont_gc) return;
if (GC_incremental && GC_collection_in_progress()) {
@@ -480,7 +513,7 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
for (i = GC_deficit; i < GC_RATE*n; i++) {
if (GC_mark_some((ptr_t)0)) {
/* Need to finish a collection */
-@@ -415,6 +569,8 @@ void GC_collect_a_little_inner(int n)
+@@ -415,6 +595,8 @@ void GC_collect_a_little_inner(int n)
}
if (GC_deficit > 0) GC_deficit -= GC_RATE*n;
if (GC_deficit < 0) GC_deficit = 0;
@@ -489,7 +522,7 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
} else {
GC_maybe_gc();
}
-@@ -904,6 +1060,8 @@ GC_bool GC_expand_hp_inner(word n)
+@@ -904,6 +1086,8 @@ GC_bool GC_expand_hp_inner(word n)
/* Force GC before we are likely to allocate past expansion_slop */
GC_collect_at_heapsize =
GC_heapsize + expansion_slop - 2*MAXHINCR*HBLKSIZE;
@@ -498,7 +531,7 @@ diff -x config.guess -x config.sub -x 'aclocal*' -x configure -x Makefile.in -ru
# if defined(LARGE_CONFIG)
if (GC_collect_at_heapsize < GC_heapsize /* wrapped */)
GC_collect_at_heapsize = (word)(-1);
-@@ -1021,3 +1179,410 @@ ptr_t GC_allocobj(size_t gran, int kind)
+@@ -1021,3 +1205,410 @@ ptr_t GC_allocobj(size_t gran, int kind)
return(*flh);
}