/* For ephemeron layout. */
#include "sdata.h"
+/* For memory advice. */
+#include "ostop.h"
+
static SCHEME_OBJECT ** p_fromspace_start;
static SCHEME_OBJECT ** p_fromspace_end;
static gc_tospace_allocator_t * gc_tospace_allocator;
GUARANTEE_TOSPACE_OPEN ();
CHECK_NEWSPACE_SYNC ();
ok = (proc (tospace_start, tospace_next, ctx));
+ OS_free_pages (tospace_start, tospace_end);
CLOSE_TOSPACE ();
return (ok);
}
{
GUARANTEE_TOSPACE_OPEN ();
CHECK_NEWSPACE_SYNC ();
+ OS_free_pages (tospace_start, tospace_end);
CLOSE_TOSPACE ();
}
void
gc_scan_oldspace (SCHEME_OBJECT * scan, SCHEME_OBJECT * end)
{
+ OS_expect_sequential_access (scan, end);
run_gc_loop (scan, (&end));
+ OS_expect_normal_access (scan, end);
}
void
default: return (syserr_unknown);
}
}
+\f
+void
+OS_expect_sequential_access (void *start, void *end)
+{
+ (void) start; /* ignore */
+ (void) end; /* ignore */
+}
+
+void
+OS_expect_normal_access (void *start, void *end)
+{
+ (void) start; /* ignore */
+ (void) end; /* ignore */
+}
+
+void
+OS_free_pages (void *start, void *end)
+{
+ (void) start; /* ignore */
+ (void) end; /* ignore */
+}
(*length) = ((sizeof (syscall_names_table)) / (sizeof (char *)));
(*names) = syscall_names_table;
}
+\f
+void
+OS_expect_sequential_access (void *start, void *end)
+{
+ (void) start; /* ignore */
+ (void) end; /* ignore */
+}
+
+void
+OS_expect_normal_access (void *start, void *end)
+{
+ (void) start; /* ignore */
+ (void) end; /* ignore */
+}
+
+void
+OS_free_pages (void *start, void *end)
+{
+ (void) start; /* ignore */
+ (void) end; /* ignore */
+}
(*length) = ((sizeof (syserr_names_table)) / (sizeof (char *)));
(*names) = syserr_names_table;
}
+\f
+static unsigned long
+round_up (unsigned long n, unsigned long factor)
+{
+ return (((n + (factor - 1)) / factor) * factor);
+}
+
+static unsigned long
+round_down (unsigned long n, unsigned long factor)
+{
+ return ((n / factor) * factor);
+}
+
+static void
+estimate_pages (void *start, void *end,
+ unsigned long (*round_start) (unsigned long, unsigned long),
+ unsigned long (*round_end) (unsigned long, unsigned long),
+ void **addr, size_t *len)
+{
+ if (end <= start)
+ {
+ (*addr) = start;
+ (*len) = 0;
+ return;
+ }
+
+ {
+ unsigned long page_size = (UX_getpagesize ());
+ char *page_start
+ = ((char *) ((*round_start) (((unsigned long) start), page_size)));
+ char *page_end
+ = ((char *) ((*round_end) (((unsigned long) end), page_size)));
+ (*addr) = ((void *) page_start);
+ (*len) = ((page_start < page_end) ? (page_end - page_start) : 0);
+ }
+}
+
+static void
+underestimate_pages (void *start, void *end, void **addr, size_t *len)
+{
+ estimate_pages (start, end, (&round_up), (&round_down), addr, len);
+}
+
+static void
+overestimate_pages (void *start, void *end, void **addr, size_t *len)
+{
+ estimate_pages (start, end, (&round_down), (&round_up), addr, len);
+}
+\f
+void
+OS_expect_sequential_access (void *start, void *end)
+{
+ void *addr;
+ size_t len;
+ overestimate_pages (start, end, (&addr), (&len));
+#if ((defined (HAVE_POSIX_MADVISE)) && (defined (POSIX_MADV_SEQUENTIAL)))
+ (void) posix_madvise (addr, len, POSIX_MADV_SEQUENTIAL);
+#elif ((defined (HAVE_MADVISE)) && (defined (MADV_SEQUENTIAL)))
+ (void) madvise (addr, len, MADV_SEQUENTIAL);
+#endif
+}
+
+void
+OS_expect_normal_access (void *start, void *end)
+{
+ void *addr;
+ size_t len;
+ overestimate_pages (start, end, (&addr), (&len));
+#if ((defined (HAVE_POSIX_MADVISE)) && (defined (POSIX_MADV_NORMAL)))
+ (void) posix_madvise (addr, len, POSIX_MADV_NORMAL);
+#elif ((defined (HAVE_MADVISE)) && (defined (MADV_NORMAL)))
+ (void) madvise (addr, len, MADV_NORMAL);
+#endif
+}
+
+void
+OS_free_pages (void *start, void *end)
+{
+ void *addr;
+ size_t len;
+ underestimate_pages (start, end, (&addr), (&len));
+#if ((defined (HAVE_MADVISE)) && (defined (MADV_FREE)))
+ (void) madvise (addr, len, MADV_FREE);
+#endif
+}