From patchwork Mon Jul 26 12:59:55 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 59911 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 06A7C1007D2 for ; Mon, 26 Jul 2010 23:00:33 +1000 (EST) Received: (qmail 14318 invoked by alias); 26 Jul 2010 13:00:30 -0000 Received: (qmail 14306 invoked by uid 22791); 26 Jul 2010 13:00:29 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, SPF_HELO_PASS, TW_CC, T_RP_MATCHES_RCVD, T_TVD_MIME_NO_HEADERS X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (74.125.121.35) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 26 Jul 2010 13:00:05 +0000 Received: from kpbe20.cbf.corp.google.com (kpbe20.cbf.corp.google.com [172.25.105.84]) by smtp-out.google.com with ESMTP id o6QD02Gd015399 for ; Mon, 26 Jul 2010 06:00:02 -0700 Received: from eye13 (eye13.prod.google.com [10.208.5.13]) by kpbe20.cbf.corp.google.com with ESMTP id o6QD00XB003404 for ; Mon, 26 Jul 2010 06:00:00 -0700 Received: by eye13 with SMTP id 13so493576eye.23 for ; Mon, 26 Jul 2010 05:59:59 -0700 (PDT) Received: by 10.213.20.4 with SMTP id d4mr3501993ebb.83.1280149199734; Mon, 26 Jul 2010 05:59:59 -0700 (PDT) Received: from coign.google.com (dhcp-172-28-249-136.lul.corp.google.com [172.28.249.136]) by mx.google.com with ESMTPS id v59sm5663335eeh.4.2010.07.26.05.59.57 (version=TLSv1/SSLv3 cipher=RC4-MD5); Mon, 26 Jul 2010 05:59:58 -0700 (PDT) From: Ian Lance Taylor To: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com Subject: [gccgo] When a goroutine exits, free its mcache Date: Mon, 26 Jul 2010 05:59:55 -0700 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 X-System-Of-Record: true X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 cache. 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. Ian 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;