This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gccgo] When a goroutine exits, free its mcache

In the gc compiler runtime, goroutines exit but OS threads never do.
This means that there is never a need to free the thread-specific memory

In gccgo, OS threads do exit.  And that means that we do need to free
the thread-specific cache when they exit.  That is what this patch does.

Interestingly, the garbage collector is fully able to free up all the
memory used by the cache.  However, it is not able to free the cache
itself.  This means that caches slowly accumulate over time as a new one
is allocated for each new goroutine.  A more important effect is that
each cache holds references to spans.  Not freeing the caches means that
the spans are never freed.  And that means that the spans are during
each garbage collection sweep, even though they no longer contain any
allocated memory.

Fixing this problem speeds up gccgo's garbage collection to take an
acceptable amount of time.

Committed to gccgo branch.


diff -r 4ccd6253e3e9 libgo/runtime/go-go.c
--- a/libgo/runtime/go-go.c	Mon Jul 26 04:21:01 2010 -0700
+++ b/libgo/runtime/go-go.c	Mon Jul 26 05:47:38 2010 -0700
@@ -114,6 +114,11 @@
   free (list_entry);
   m->list_entry = NULL;
+  MCache_ReleaseAll (m->mcache);
+  __builtin_memset (m->mcache, 0, sizeof (struct MCache));
+  FixAlloc_Free (&mheap.cachealloc, m->mcache);
+  m->mcache = NULL;
 /* Start the thread.  */
@@ -511,7 +516,7 @@
   struct __go_thread_id *p;
   for (p = __go_all_thread_ids; p != NULL; p = p->next)
-    MCache_ReleaseAll(p->m->mcache);
+    MCache_ReleaseAll (p->m->mcache);
 /* Start the other threads after garbage collection.  */
diff -r 4ccd6253e3e9 libgo/runtime/malloc.goc
--- a/libgo/runtime/malloc.goc	Mon Jul 26 04:21:01 2010 -0700
+++ b/libgo/runtime/malloc.goc	Mon Jul 26 05:47:38 2010 -0700
@@ -248,6 +248,10 @@
 	MCache *c;
 	c = FixAlloc_Alloc(&mheap.cachealloc);
+	// Clear the free list used by FixAlloc; assume the rest is zeroed.
+	c->list[0].list = nil;
 	mstats.mcache_inuse = mheap.cachealloc.inuse;
 	mstats.mcache_sys = mheap.cachealloc.sys;
 	return c;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]