From patchwork Sun Aug 1 10:20:15 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: 60445 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 57A1DB70D4 for ; Sun, 1 Aug 2010 20:20:32 +1000 (EST) Received: (qmail 20281 invoked by alias); 1 Aug 2010 10:20:30 -0000 Received: (qmail 20272 invoked by uid 22791); 1 Aug 2010 10:20:28 -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; Sun, 01 Aug 2010 10:20:22 +0000 Received: from hpaq13.eem.corp.google.com (hpaq13.eem.corp.google.com [172.25.149.13]) by smtp-out.google.com with ESMTP id o71AKKl9003815 for ; Sun, 1 Aug 2010 03:20:20 -0700 Received: from eydd26 (eydd26.prod.google.com [10.208.30.26]) by hpaq13.eem.corp.google.com with ESMTP id o71AKIJu030312 for ; Sun, 1 Aug 2010 03:20:19 -0700 Received: by eydd26 with SMTP id d26so1332931eyd.14 for ; Sun, 01 Aug 2010 03:20:18 -0700 (PDT) Received: by 10.213.40.75 with SMTP id j11mr2381347ebe.28.1280658018706; Sun, 01 Aug 2010 03:20:18 -0700 (PDT) Received: from coign.google.com (dhcp-172-28-249-170.lul.corp.google.com [172.28.249.170]) by mx.google.com with ESMTPS id a48sm6717775eei.18.2010.08.01.03.20.17 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sun, 01 Aug 2010 03:20:17 -0700 (PDT) From: Ian Lance Taylor To: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com Subject: [gccgo] Use __go_thread_ids_lock to lock mcache alloc and free Date: Sun, 01 Aug 2010 03:20:15 -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 There is no lock on the FixAlloc used to allocate and free mcache structures. With this patch, we use __go_thread_ids_lock as a lock for it. This also fixes the problem of accessing the mcache field of an M structure which has been freed by the garbage collector after the thread has been taken off the list of all threads. Committed to gccgo branch. Ian diff -r 18d3fecdcc06 libgo/runtime/go-go.c --- a/libgo/runtime/go-go.c Wed Jul 28 09:07:42 2010 -0700 +++ b/libgo/runtime/go-go.c Sun Aug 01 03:16:41 2010 -0700 @@ -91,9 +91,11 @@ remove_current_thread (void) { struct __go_thread_id *list_entry; + MCache *mcache; int i; list_entry = m->list_entry; + mcache = m->mcache; i = pthread_mutex_lock (&__go_thread_ids_lock); assert (i == 0); @@ -105,16 +107,15 @@ if (list_entry->next != NULL) list_entry->next->prev = list_entry->prev; + /* We use __go_thread_ids_lock as a lock for mheap.cachealloc. */ + MCache_ReleaseAll (mcache); + __builtin_memset (mcache, 0, sizeof (struct MCache)); + FixAlloc_Free (&mheap.cachealloc, mcache); + i = pthread_mutex_unlock (&__go_thread_ids_lock); assert (i == 0); 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. */ @@ -209,7 +210,6 @@ #endif newm = __go_alloc (sizeof (M)); - newm->mcache = allocmcache (); list_entry = malloc (sizeof (struct __go_thread_id)); list_entry->prev = NULL; @@ -226,6 +226,9 @@ i = pthread_mutex_lock (&__go_thread_ids_lock); assert (i == 0); + /* We use __go_thread_ids_lock as a lock for mheap.cachealloc. */ + newm->mcache = allocmcache (); + if (__go_all_thread_ids != NULL) __go_all_thread_ids->prev = list_entry; list_entry->next = __go_all_thread_ids;