This is the mail archive of the
mailing list for the GCC project.
[gccgo] When a goroutine exits, free its mcache
- From: Ian Lance Taylor <iant at google dot com>
- To: gcc-patches at gcc dot gnu dot org, gofrontend-dev at googlegroups dot com
- Date: Mon, 26 Jul 2010 05:59:55 -0700
- Subject: [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
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 @@
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);
/* 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 @@
c = FixAlloc_Alloc(&mheap.cachealloc);
+ // Clear the free list used by FixAlloc; assume the rest is zeroed.
+ c->list.list = nil;
mstats.mcache_inuse = mheap.cachealloc.inuse;
mstats.mcache_sys = mheap.cachealloc.sys;