Permalink
Browse files

xmalloc: wait for the VMM layer to be initialized before installing x…

…gc().

This is an attempt to tweak the initialization order of the library to see
whether recent problems reported on 64-bit platforms were linked to the early
auto-initialization of the callout queue.

Waiting for the VMM layer to be up before auto-installing the xgc() idle
callback further guarantees that we'll avoid possible sbrk()-based early
allocation.

Besides, there's no real urgency into installing the xgc() callback, so it is
perfectly fine to wait for the VMM layer to be up to do this.
  • Loading branch information...
1 parent 4eadca9 commit 6bbec6fe027e0ba059c83e999a0099af8f28a58e @rmanfredi rmanfredi committed Jun 2, 2012
Showing with 31 additions and 19 deletions.
  1. +31 −19 src/lib/xmalloc.c
View
@@ -516,6 +516,7 @@ static void *lowest_break; /**< Lowest heap address we know */
static void *current_break; /**< Current known heap break */
static size_t xmalloc_pagesize; /**< Cached page size */
static bool xmalloc_freelist_inited;
+static bool xmalloc_xgc_installed;
static spinlock_t xmalloc_sbrk_slk = SPINLOCK_INIT;
@@ -587,6 +588,27 @@ xm_ptr_cmp(const void *a, const void *b)
return xmalloc_grows_up ? ptr_cmp(b, a) : ptr_cmp(a, b);
}
+/**
+ * Called when the main callout queue is idle to attempt background compaction.
+ */
+static bool
+xmalloc_idle_collect(void *unused_data)
+{
+ (void) unused_data;
+
+ xgc();
+ return TRUE; /* Keep calling */
+}
+
+/**
+ * Install periodic idle callback to run the freelist compactor.
+ */
+static G_GNUC_COLD void
+xmalloc_xgc_install(void)
+{
+ cq_idle_add(cq_main(), xmalloc_idle_collect, NULL);
+}
+
/**
* Called when the VMM layer has been initialized.
*/
@@ -608,6 +630,15 @@ xmalloc_vmm_inited(void)
#ifdef XMALLOC_IS_MALLOC
vmm_malloc_inited();
#endif
+
+ /*
+ * We wait for the VMM layer to be up before we install the xgc() idle
+ * thread in an attempt to tweak the self-bootstrapping path of this
+ * library and avoid creating some objects too early: we wish to avoid
+ * sbrk() allocation if possible.
+ */
+
+ once_run(&xmalloc_xgc_installed, xmalloc_xgc_install);
}
/**
@@ -2133,18 +2164,6 @@ xfl_insert(struct xfreelist *fl, void *p, bool burst)
mutex_unlock(&fl->lock); /* Issues final memory barrier */
}
-/**
- * Called when the main callout queue is idle to attempt background compaction.
- */
-static bool
-xmalloc_idle_collect(void *unused_data)
-{
- (void) unused_data;
-
- xgc();
- return TRUE; /* Keep calling */
-}
-
/**
* Initialize freelist buckets once.
*/
@@ -2188,13 +2207,6 @@ xmalloc_freelist_init_once(void)
*/
xmalloc_split_setup();
-
- /*
- * Since this routine is guaranteed to be called only once, use it to
- * install the periodic call to the garbage collector.
- */
-
- cq_idle_add(cq_main(), xmalloc_idle_collect, NULL);
}
/**

0 comments on commit 6bbec6f

Please sign in to comment.